Docker安装Nginx


由于实在看不下去以前到处扔垃圾一样装的杂七杂八环境,前两天心血来潮还原了下服务器,改用 docker 安装一些必备的应用,虽然也踩了不少坑,但不得不说,docker 是真的香。

获取配置文件

先在想要安装 nginx 的目录下创建几个文件,用来存放配置文件、静态页面、日志、证书等文件

1
2
# 这里我选择安装在 /usr/local/nginx 目录下
mkdir -p /usr/local/nginx/{conf,html,logs,ssl}

拉取并运行一个 nginx 镜像,从里面拷贝出需要的配置文件,拿完文件删掉容器即可~~始乱终弃

这里用的是 1.21.6 版本,直接用最新版也 ok

1
2
3
4
5
6
7
# 拉取并启动 nginx 容器
docker run -d --name nginx nginx:1.21.6
# 从容器内拷贝需要的文件,nginx.conf:基本配置文件,conf.d:配置文件目录
docker cp nginx:/etc/nginx/nginx.conf /usr/local/nginx/
docker cp nginx:/etc/nginx/conf.d /usr/local/nginx/
# 删掉这个容器
docker rm -f nginx

放置自己的文件

接下来把相关的文件都丢进各个目录即可

如证书丢进 ssl 目录,静态页面丢进 html,站点配置文件放在 conf.d

为什么是 conf.d

在 nginx 基本配置文件中有这样一行:

1
include /etc/nginx/conf.d/*.conf;

即代表着只要是 conf.d 目录下的 .conf 文件都会被加载进来

站点配置文件模板

静态文件模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
server {
listen 80;
listen [::]:80;
server_name marrydream.top;

rewrite ^(.*) https://$server_name$1 permanent; # http 请求重定向至 https
}

server {
listen 443 ssl;
server_name marrydream.top;

gzip on; # 开启gzip压缩

# 不压缩临界值,大于1K的才压缩
gzip_min_length 1k;
# buffer,就是,嗯,算了不解释了
gzip_buffers 4 16k;
# 用了反向代理的话,末端通信是HTTP/1.0,默认是HTTP/1.1
#gzip_http_version 1.0;
# 压缩级别,1-10,数字越大压缩的越好,时间也越长
gzip_comp_level 9;
# 进行压缩的文件类型
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 跟Squid等缓存服务有关,on的话会在Header里增加"Vary: Accept-Encoding"
gzip_vary off;
# IE6对Gzip不怎么友好,不给它压缩了
gzip_disable "MSIE [1-6]\.";

ssl_certificate /etc/nginx/ssl/7423661_marrydream.top.pem; # 证书位置
ssl_certificate_key /etc/nginx/ssl/7423661_marrydream.top.key; # 私钥位置

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

ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
root /usr/share/nginx/html/xxxx; # 静态网页文件所在的完整路径
index index.html index.htm;
try_files $uri $uri/ /index.html; # 防止 spa 项目出现莫名其妙的 404
}
}

反向代理模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server {
listen 80;
listen [::]:80;
server_name api.test.com;

rewrite ^(.*) https://$server_name$1 permanent;
}

server {
listen 443;
server_name api.test.com;

ssl_certificate /etc/nginx/ssl/xxx.pem;
ssl_certificate_key /etc/nginx/ssl/xxx.key;

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

ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location /blog {
proxy_pass http://172.xx.0.1:xxxx; # 地址为此 docker 网络地址,下面讲解
proxy_buffering off;
client_max_body_size 5M;
}
}

由于 docker 使用网络桥接方式与容器联通,因此容器内部若需要连接运行在物理机上的应用时,应使用** docker 网络物理机**的 ip 地址

而默认情况下使用的 docker0 地址,若使用自定义网络或 docker-compose 启动时则使用 docker 分配的自定义网络的地址

获取 docker 网络网段 ip 的方法如下

1
2
3
4
5
6
7
8
# 查看 nginx 容器元数据
docker inspect nginx

# 获得如下数据
"Networks": {
"Gateway": "172.31.0.1", # 网段 ip
"IPAddress": "172.31.0.2" # 容器在网段中被分配的 ip
}

获取物理机网段 ip 方法如下

1
2
# 查看物理机 ip 数据
ifconfig

获得如下数据

1
2
3
4
5
6
7
8
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
inet 12.0.6.10 netmask 255.255.252.0 broadcast 10.0.11.255
inet6 fe80::5054:ff:fe3e:1125 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:3e:11:25 txqueuelen 1000 (Ethernet)
RX packets 190960405 bytes 77991137222 (72.6 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 233028288 bytes 40267341304 (37.5 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

可以得到 docker 网络网段 ip 为 172.31.0.1,物理机 ip 为 12.0.6.10,两者取其一填入配置文件中的 proxy_pass 即可。

由于每次创建容器时 docker 网络 ip 均会被重置,因此建议使用 物理机 ip。

编写 docker-compose.yml

使用 docker-compose 来方便的直接启动 nginx 容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
version: "3.7"
services:
web:
image: nginx:1.21.6
ports:
- 80:80
- 443:443
container_name: nginx
restart: always
privileged: true
volumes:
- ./logs:/var/log/nginx
- ./html:/usr/share/nginx/html
- ./conf.d:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
- ./nginx.conf:/etc/nginx/nginx.conf

启动容器

docker-compose.yml 所在目录下执行,无报错即成功

1
docker-compose up -d