Docker安装Nginx

Arthit 于 2024-03-22 发布

创建挂载文件目录

mkdir nginx
cd nginx
mkdir conf && mkdir log && mkdir html

启动临时 nginx 容器,复制配置文件

启动临时 nginx 容器

docker run -d --name nginx -p 9080:80 nginx

拷贝 nginx 容器里面的文件到宿主机

docker cp nginx:/etc/nginx/nginx.conf conf/nginx.conf
docker cp nginx:/etc/nginx/conf.d conf/conf.d
docker cp nginx:/usr/share/nginx/html ./

删除临时容器

docker stop nginx
docker rm nginx

修改配置文件

我自己搭建了好多网站,我想一个网站一个配置文件,不想把所有的网站都放到nginx.conf配置文件里面,于是我的配置文件目录长这样

nginx.conf 文件内容

user  root;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  2048;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    # 这句话至关重要,匹配conf.d文件下的所有以.conf结尾的文件,作为nginx的配置文件
    include /etc/nginx/conf.d/*.conf;
}

iarthit.conf 文件内容

server {
    listen 80;
    server_name www.iarthit.com iarthit.com;
    return 301 https://$server_name$request_uri;
}
server {
     listen 443 ssl;

     #填写证书绑定的域名
     server_name www.iarthit.com iarthit.com;

     #填写证书文件绝对路径
     ssl_certificate /etc/nginx/cert/cert-j76op8xez670x42z/fullchain.cer;
     #填写证书私钥文件绝对路径
     ssl_certificate_key /etc/nginx/cert/cert-j76op8xez670x42z/cert.key;

     ssl_session_cache shared:SSL:1m;
     ssl_session_timeout 5m;

     #自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
     #TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差。
     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
     ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

     #表示优先使用服务端加密套件。默认开启
     ssl_prefer_server_ciphers on;

     location / {
          root   /usr/share/nginx/html/blog;
          index  index.html;
    }


    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

blog-comment.conf 文件内容

server {
    listen 80;
    server_name blog-comment.iarthit.com;
    return 301 https://$server_name$request_uri;
}
server {
     listen 443 ssl;

     #填写证书绑定的域名
     server_name blog-comment.iarthit.com;

     #填写证书文件绝对路径
     ssl_certificate /etc/nginx/cert/cert-j76op8xez670x42z/fullchain.cer;
     #填写证书私钥文件绝对路径
     ssl_certificate_key /etc/nginx/cert/cert-j76op8xez670x42z/cert.key;

     ssl_session_cache shared:SSL:1m;
     ssl_session_timeout 5m;

     #自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
     #TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差。
     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
     ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

     #表示优先使用服务端加密套件。默认开启
     ssl_prefer_server_ciphers on;

     location / {
	      proxy_pass http://172.19.0.3:8360;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    }
}

创建 docker-compose 文件

touch docker-compose.yml

使用 vi 命令把以下内容复制到 docker-compose 文件

version: '3.3'
services:
    nginx:
        container_name: nginx
        ports:
            - '80:80'
            - '443:443'
        restart: unless-stopped
        volumes:
            - './conf/nginx.conf:/etc/nginx/nginx.conf' # 挂载配置文件
            - './conf/conf.d:/etc/nginx/conf.d' # 挂载配置文件目录
            - './logs:/var/log/nginx' # 挂载日志文件夹
            - './html:/usr/share/nginx/html' # 挂载页面内容
            - './cert:/etc/nginx/cert' # 挂载SSL证书文件夹位置
        image: nginx

启动容器

docker-compose up -d

使用 Certbot 申请证书(2024-04-08 补充)

运行以下 docker 命令申请证书

docker run -it --rm --name certbot \
-v "/root/nginx/cert:/etc/letsencrypt" \
-v "/root/nginx/html/blog:/var/lib/letsencrypt" \
certbot/certbot certonly --manual --preferred-challenges dns -d iarthit.com -d *.iarthit.com

DNS 方式验证需要添加一条解析记录,类似这样的 截图

最后我们把 nginx 的 docker-compose.yml 文件修改一下,用 certbot 自动续期证书。

version: '3.3'
services:
  nginx:
    container_name: nginx_self
    ports:
      - '80:80'
      - '443:443'
    restart: unless-stopped
    volumes:
      - '/root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf'
      - '/root/nginx/conf/conf.d:/etc/nginx/conf.d'
      - '/root/nginx/logs:/var/log/nginx'
      - '/root/nginx/html:/usr/share/nginx/html'
      - '/root/nginx/cert:/etc/nginx/cert'
    image: nginx
    command: /bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'

  certbot:
    image: certbot/certbot
    container_name: certbot
    restart: unless-stopped
    volumes:
      - '/root/nginx/cert:/etc/letsencrypt'
      - '/root/nginx/html/blog:/var/www/certbot'
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

修改 nginx 的 SSL 配置

ssl_certificate /etc/nginx/cert/live/iarthit.com/fullchain.pem;
ssl_certificate_key /etc/nginx/cert/live/iarthit.com/privkey.pem;

参考

certbot 有好多内容,可以看看文档。我目前用 docker 安装的 certbot,也可以直接在宿主机安装 certbot,并且可以使用 nginx 插件(certbot --nginx)能自动修改 nginx 配置文件。

# 续期测试
certbot renew --dry-run
# 宿主机使用certbot续期SSL证书
15 2 * */2 * certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"