├── ssl └── PLACE_HOLDER ├── www └── log │ └── PLACE_HOLDER ├── start.sh ├── reload-nginx.sh ├── .gitignore ├── renew-ssl.sh ├── README_cn.md ├── vhost.sh ├── nginx ├── conf.d │ └── conf.demo └── nginx.conf ├── compose.yaml └── README.md /ssl/PLACE_HOLDER: -------------------------------------------------------------------------------- 1 | . -------------------------------------------------------------------------------- /www/log/PLACE_HOLDER: -------------------------------------------------------------------------------- 1 | . -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo docker compose up -d 4 | -------------------------------------------------------------------------------- /reload-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo docker exec nginx nginx -s reload 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | www/*/* 2 | !www/log/PLACE_HOLDER 3 | 4 | ssl/* 5 | !ssl/PLACE_HOLDER 6 | 7 | nginx/conf.d/* 8 | !nginx/conf.d/conf.demo 9 | 10 | *.swp 11 | *.swo 12 | -------------------------------------------------------------------------------- /renew-ssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # NOTE run certbot/Let's Encrypt for the first time. 4 | # sudo docker compose run --rm certbot certonly --email demo@gmail.com --agree-tos --no-eff-email --webroot --webroot-path /home/www/demo.com -d demo.com 5 | 6 | sudo docker compose run --rm certbot renew 7 | 8 | # run this script via crontab 9 | #sudo crontab -e 10 | #0 3 * * 1 cd /path/to/your/site; bash -x reload-nginx.sh 11 | -------------------------------------------------------------------------------- /README_cn.md: -------------------------------------------------------------------------------- 1 | 通过 `docker` 运行 `nginx`,使用 `Let's Encrypt` 更新 `https/ssl`。 2 | 3 | # 如何使用 4 | 5 | - 克隆本项目。 6 | - 使用 `./vhost.sh add your_domain.com` 添加站点。 7 | - 提前设置好域名的 DNS,指定当前服务器 IP 8 | - 将站点文件添加至:`./www/your_domain.com/public` 9 | - 更新站点配置文件:`./nginx/conf.d/your_domain.com.conf` 10 | - 启动 docker:`./start.sh` 11 | - 修改站点配置文件后,重载 nginx:`./reload-nginx.sh` 12 | - 使用 `crontab` 定期更新 ssl:`./renew-ssl.sh` 13 | 14 | # 介绍本项目 15 | 16 | 各文件夹及文件: 17 | 18 | - `nginx`: nginx 配置文件 19 | - `www`: 站点数据文件,每个域名一个子文件夹,日志位于 `www/log` 20 | - `ssl`: ssl 配置文件,使用 Let's Encrypt 生成及更新 21 | - `vhost.sh`: 添加、删除站点 22 | - `compose.yaml`: docker compose 配置文件 23 | - `start.sh`: 使用 `docker compose up` 启动 24 | - `reload-nginx.sh`: 修改站点配置文件后,重载 nginx 25 | - `renew-ssl.sh`: 使用 Let's Encrypt 更新 ssl 26 | -------------------------------------------------------------------------------- /vhost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dir=$(pwd) 4 | operate=$1 5 | domain=$2 6 | 7 | if [ -z "$operate" ] || [ -z "$domain" ]; then 8 | echo "Usage:" 9 | echo " ./vhost.sh add domain.com" 10 | echo " ./vhost.sh del domain.com" 11 | exit 1 12 | fi 13 | 14 | echo "$operate $domain" 15 | 16 | if [ "$operate" = "add" ]; then 17 | mkdir -p ./www/$domain/.well-known 18 | mkdir -p ./www/$domain/public 19 | 20 | cd ./nginx/conf.d/ 21 | cp conf.demo $domain.conf 22 | sed -i "s/demo.com/$domain/g" $domain.conf 23 | 24 | echo "Done" 25 | 26 | elif [ "$operate" = "del" ]; then 27 | rm -rf ./www/$domain/.well-known 28 | rm -rf ./www/$domain/public 29 | 30 | rm ./nginx/conf.d/$domain.conf 31 | 32 | echo "Done" 33 | fi 34 | 35 | cd $dir 36 | ./reload-nginx.sh 37 | -------------------------------------------------------------------------------- /nginx/conf.d/conf.demo: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name demo.com; 4 | 5 | location ~ /.well-known/acme-challenge { 6 | root /home/www/demo.com; 7 | } 8 | 9 | location / { 10 | return 301 https://$host$request_uri; 11 | } 12 | 13 | #access_log off; 14 | } 15 | 16 | server { 17 | listen 443 ssl; 18 | server_name demo.com; 19 | http2 on; 20 | 21 | ssl_certificate /etc/letsencrypt/live/demo.com/fullchain.pem; 22 | ssl_certificate_key /etc/letsencrypt/live/demo.com/privkey.pem; 23 | 24 | location / { 25 | root /home/www/demo.com/public; 26 | index index.html index.htm; 27 | } 28 | 29 | location ~ /\. { 30 | deny all; 31 | } 32 | 33 | #access_log off; 34 | access_log /home/www/log/demo.com.log; 35 | error_log /home/www/log/demo.com.log; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | nginx: 5 | image: nginx:alpine 6 | container_name: nginx 7 | ports: 8 | - 80:80 9 | - 443:443 10 | restart: always 11 | volumes: 12 | - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro 13 | - ./nginx/conf.d/:/etc/nginx/conf.d/:ro 14 | - ./ssl/:/etc/letsencrypt/:ro 15 | - ./www/:/home/www/:ro 16 | - ./www/log/:/home/www/log/:rw 17 | # NOTE In fact only the following two folders used. 18 | # Add whole folder of `./www` is for convenience when adding a new site. 19 | #- ./www/demo.com/public:/home/www/demo.com/public:ro 20 | #- ./www/demo.com/.well-known:/home/www/demo.com/.well-known:ro 21 | 22 | certbot: 23 | image: certbot/certbot:latest 24 | volumes: 25 | - ./ssl/:/etc/letsencrypt/:rw 26 | - ./www/:/home/www/:rw 27 | # NOTE Similar with `volumes` in `nginx`. 28 | #- ./www/demo.com/.well-known:/home/www/demo.com/.well-known:rw 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project is to run nginx via Docker, support https/ssl via Let's Encrypt. 2 | 3 | [中文文档](./README_cn.md) 4 | 5 | # How to Use 6 | 7 | - Clone this project. 8 | - Use `./vhost.sh add your_domain.com` to add your site. 9 | - Don't forget to configure the DNS, i.e.g, map your domain to ip of your server. 10 | - Add site source to `./www/your_domain.com/public`. 11 | - Update site config file if necessary: `./nginx/conf.d/your_domain.com.conf`. 12 | - Start docker: `./start.sh` 13 | - Reload nginx after modify site config file: `./reload-nginx.sh`. 14 | - Update ssl every week: `./renew-ssl.sh` via `crontab`. 15 | 16 | # Introduce this Project 17 | 18 | The folders and files: 19 | 20 | - `nginx`: nginx config file for your site. 21 | - `www`: site source files for your side. Each domain has its sub folder. Logs in `www/log`. 22 | - `ssl`: ssl config file, updated by Let's Encrypt. 23 | - `vhost.sh`: used to add or delete site. 24 | - `compose.yaml`: docker compose config file. 25 | - `start.sh`: run `docker compose up` to start project. 26 | - `reload-nginx.sh`: reload nginx after update site config file. 27 | - `renew-ssl.sh`: renew ssl file using Let's Encrypt. 28 | -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes auto; 4 | 5 | error_log /var/log/nginx/error.log notice; 6 | pid /var/run/nginx.pid; 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | http { 13 | include /etc/nginx/mime.types; 14 | default_type application/octet-stream; 15 | 16 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 17 | '$status $body_bytes_sent "$http_referer" ' 18 | '"$http_user_agent" "$http_x_forwarded_for"'; 19 | 20 | access_log /var/log/nginx/access.log main; 21 | 22 | sendfile on; 23 | #tcp_nopush on; 24 | 25 | keepalive_timeout 65; 26 | 27 | gzip on; 28 | gzip_comp_level 5; 29 | gzip_min_length 256; 30 | gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; 31 | 32 | location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { 33 | expires 7d; 34 | } 35 | 36 | location ~ .*\.(js|css)?$ { 37 | expires 12h; 38 | } 39 | 40 | limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s; 41 | limit_conn_zone $binary_remote_addr zone=addr:10m; 42 | 43 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 44 | '$status $body_bytes_sent "$http_referer" ' 45 | '"$http_user_agent" "$http_x_forwarded_for"'; 46 | 47 | include /etc/nginx/conf.d/*.conf; 48 | } 49 | --------------------------------------------------------------------------------