Skip to content

Nginx 安装之 Docker 和 Compose

docker hub: https://hub.docker.com/_/nginx

准备

创建挂载目录

shell
# 配置文件目录
mkdir -p /opt/nginx/conf.d
# 日志文件目录 
mkdir -p /opt/nginx/logs
#项目文件目录(这里可以存放web文件)
mkdir -p /opt/nginx/html
# 证书
mkdir -p /opt/nginx/ssl

# 可以直接一条命令创建多个文件夹
mkdir -p /opt/nginx/conf.d /opt/nginx/logs /opt/nginx/html /opt/nginx/ssl

# 最推荐的方式
mkdir -p /opt/nginx/{conf.d,logs,html,ssl}

从临时容器中复制配置文件模板

挂载操作会直接将两个文件夹内容同步,若是直接用宿主机的空文件夹直接挂载到容器内部的配置文件目录上,会造成 nginx 容器配置文件目录被同步为空文件夹,进而导致容器启动失败。故我们需要先启动一遍容器,将初始配置拷贝出来。

shell
# 创建容器
docker run -d --name nginx nginx:1.31.1

# 复制容器配置文件到宿主机
docker cp nginx:/etc/nginx/conf.d /opt/nginx/
docker cp nginx:/usr/share/nginx/html /opt/nginx/

# 授权文件夹,防止 nginx 操作文件夹权限不足
chmod -R a+rwx /opt/nginx

# 删除容器
docker rm -f nginx

然后把 nginx 配置文件,html 静态资源,ssl 证书文件放到对应的位置。

Docker 安装

shell
docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
--restart=unless-stopped \
--network host \
-v /opt/nginx/conf.d:/etc/nginx/conf.d \
-v /opt/nginx/logs:/var/log/nginx \
-v /opt/nginx/html:/usr/share/nginx/html \
-v /opt/nginx/ssl:/etc/nginx/ssl \
nginx:1.31.1

Docker Compose 安装

yaml
services:
  nginx:
    image: nginx:1.31.1
    container_name: nginx
    restart: unless-stopped
    # host 模式直接使用主机网络。无需映射端口。
    network_mode: host
    # 注意:host模式下,ports 部分必须移除或注释掉。这样配置后,Nginx 会直接监听宿主机的 80 和 443 等端口
    #ports:
      #- "80:80"
      #- "443:443"
    volumes:
      - /opt/nginx/conf.d:/etc/nginx/conf.d:ro
      - /opt/nginx/html:/usr/share/nginx/html:ro
      - /opt/nginx/logs:/var/log/nginx
      - /opt/nginx/ssl:/etc/nginx/ssl
      - /etc/localtime:/etc/localtime:ro
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

容器网络:

建议 nginx 容器网络使用 --network host 模式,这样配置文件中可以直接使用 localhost

挂载卷常用选项:

:ro: 表示只读(read-only)挂载,容器内无法修改该卷的内容。 :rw: 默认挂载方式,可读写。 /etc/localtime:/etc/localtime:ro:保持容器和宿主机的时间同步。

healthcheck 选项:

test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]:检查容器是否正常启动,通过访问容器的根路径(/)并检查返回的状态码是否为200。 interval: 30s:检查间隔为30秒。 timeout: 10s:超时时间为10秒。 retries: 3:检查失败重试3次。 start_period: 5s:容器启动后等待5秒再开始检查。

修改配置

进入挂载的配置文件夹 /opt/nginx/conf.d/ 下。

修改 default.conf, 或者新建 conf 文件。

在这个目录下,.conf 后缀的文件都会被读取为配置文件(因为 /opt/nginx/nginx.conf 中配置了 include /etc/nginx/conf.d/*.conf)

这里以修改 default.conf 文件为例:

注意:server_name 默认为 localhost,一般情况下,使用 localhost 是可以的。但是这里用域名的目的是为例隐藏不同服务访问的端口号,统一从 80/443 端口访问不同服务,所以才需要用不同的域名来区分。

shell
server {
    listen 80;
    listen  [::]:80;
    server_name aday.fun;
    rewrite ^(.*)$ https://$host$1 permanent;
}

server {
    listen      443 ssl;
    listen [::]:443 ssl;
    server_name  aday.fun;
    
    # 修改大一点,默认 1M 不够用
    client_max_body_size 1024m;
    ssl_certificate /etc/nginx/ssl/aday.fun.cer;
    ssl_certificate_key /etc/nginx/ssl/aday.fun.key;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;

        error_page 404 /404.html;
        error_page 403 /404.html;
    }
}

server {
    listen      443 ssl;
    listen [::]:443 ssl;
    server_name vita.aday.fun;

    client_max_body_size 1024m;
    ssl_certificate /etc/nginx/ssl/aday.fun.cer;
    ssl_certificate_key /etc/nginx/ssl/aday.fun.key;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 容器内转发后台接口,一般通过 --network 创建网络后,把 localhost 改成容器名才能访问的到。
        # 后台接口容器的端口可以不用去映射端口,这里通过自定义网络可以直接访问内部端口。
        # 比如原本是:-p 8081:8080,现在不需要了,直接转发到内部 8080 端口即可。 
        # 若 nginx 容器网络使用 --network host 模式,可以直接使用 `localhost + 其它容器映射后的端口`。
        proxy_pass http://<容器>:8080/;
    }
}

以上配置,配置了同一个应用所需要的 3 个 server。生产环境下,可以每一个 应用单独一个 .conf 文件,以便更清晰的管理配置。

比如 home.conf、vita.conf、jenkins.conf 文件,全部放在 /opt/nginx/conf/conf.d/ 文件夹下即可。

上传 web 文件到挂载目录中

比如:将你的前端 npm run build 打包后生成的部署文件夹 dist/ 目录里面的所有文件上传到 /opt/nginx/html/ 这个目录中。

shell
# 加入 dist.zip 在 /opt/nginx 目录下
# 解压到指定目录
unzip dist.zip -d /opt/nginx

# 移动 /opt/nginx/dist 目录到 /opt/nginx/html 目录
mv dist html

重启 nginx 容器,使配置生效

shell
docker restart nginx

# docker compose 重启 nginx 容器
docker compose restart nginx

访问网页测试

浏览器访问 http://localhost:80

若报错或者启动失败,可查看日志排除错误