Skip to content

Docker 安装 Nginx

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 --restart=unless-stopped -p 80:80 -p 443:443 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

# 启动容器并挂载目录
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

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

进入挂载的配置文件夹 /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,实际生产换下,可以每一个 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

访问网页测试

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

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

shell
docker logs nginx