docker_nginx反向代理多个容器实例

docker_nginx反向代理多个容器实例, 这里使用的是 qnap 中的 Container Station 跑的docker.
目的: 在使用同一个外网端口(443)的情况下, 通过反向代理 二级域名 到 多个容器的不同端口上. 同时使用 https 加持
例如: a.xx.com -> 实例a:3000, b.xx.com -> 实例a:4000


前置物料

  1. 阿里云注册的域名, 及其免费证书.
  2. 公网ip
  3. docker 实例 , 这里是 gogs, 容器 web 端口是 3000

!!! 不要使用的端口 !!!

家用 nas 的 443, 80 这两个端口都不要用, 已经被运营商封了, 所以做端口映射时, 将外网端口 32443 映射到 实例端口 443 上, 那么 Nginx 配置文件还是配 443 端口, 如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server
{
listen 443 ssl;
server_name aaa.bbb.cn;
ssl_certificate /certs/cert_gitea/3361546_aaa.bbb.cn.pem;
ssl_certificate_key /certs/cert_gitea/3361546_aaa.bbb.cn.key;
ssl_session_timeout 5m;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_redirect off;
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_pass http://10.0.3.4:3000;
}
client_max_body_size 512M;
access_log /var/log/nginx/aaa.bbb.cn.log;
}

url 访问时访问的是 32443, 如: https://aaa.bbb.cn:32443/


docker nginx 启动

  1. 拉个官网镜像. docker pull nginx

  2. https 正式丢到 DockerData/nginx/certs 下.

  3. 跑起来, 这里用的是 qnap

    1. 链接了两个 docker 实例

      :gogs:3000
      :hexo:4000

    2. 端口映射, 主要是 443 https端口

      443:443
      32770:80

    3. 挂载文件

      DockerData/nginx/certs:/certs # 挂载 阿里云 下载的 nginx证书
      DockerData/nginx/conf:/etc/nginx/conf.d # 配置文件. 详细配置看这里 反向代理配置

      添加配置文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      server
      {
      listen 443 ssl;
      server_name gogs.wilker.cn; # 阿里云域名
      ssl_certificate /certs/cert_gogs/214816825520979.pem; # 两个证书路径
      ssl_certificate_key /certs/cert_gogs/214816825520979.key;
      ssl_session_timeout 5m;
      ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_prefer_server_ciphers on;
      location / {
      proxy_redirect off;
      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_pass http://gogs:3000; # 代理链接的gogs web端口
      }
      client_max_body_size 512M;
      access_log /var/log/nginx/gogs.wilker.cn.log;
      }

  4. run 起来后访问


多域名绑定同一个ip

同一台机子绑定了多个二级域名, 将二级域名的记录值CNAME到主域名即可
参考: https://github.com/chenhw2/aliyun-ddns-cli/issues/10


hexo docker: https://hub.docker.com/r/ipple1986/hexo/


gogos 使用 https 及 二级域名 加持

需要修改gogs中修改两个参数, 才能https中显示正确, 并 clone

1
2
3
[server]
DOMAIN = gogs.wilker.cn
ROOT_URL = https://gogs.wilker.cn/

https://gogs.wilker.cn/yangxuan/ArtRes_ItsCharOld.git

(ssh暂时没研究)


开启 gzip

  1. nginx代理所有都开启gzip, 修改配置文件 /etc/nginx/nginx.conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # vi /etc/nginx/nginx.conf # 加入以下配置
    ...
    #gzip on;
    #启用gzip
    gzip on;
    #需要压缩文件的最小尺寸,单位是B
    gzip_min_length 1000;
    #gzip文件缓存大小
    gzip_buffers 4 8k; # 4和8之间有个空格的啊
    #gzip压缩文件格式,以下涵盖了一般所需的类型
    gzip_types text/plain application/x-javascript text/css application/xml application/javascript application/json;
    #gzip压缩等级,数值越高压缩得越狠,也越占资源
    gzip_comp_level 3;
    ...
  2. 重启nginx

  3. 打开Chrome查看是否开启成功


相关详细配置

反向代理配置

自定义文件 /etc/nginx/conf.d/my_nginx.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# http conf
# server {
# listen 80;
# server_name gogs.wilker.cn;
# access_log /var/log/nginx/www.wilker.access.log main;
# error_log /var/log/nginx/www.wilker.error.log error;
# location / {
# proxy_set_header Host $http_host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_pass http://gogs:3000;
# }
# }

# web 服务
server {
listen 32081;
server_name gitea.wilker.cn;
root /mypublic;
index index222.html
access_log /var/log/gitea.com.log;
}

# 文件服务
server {
listen 32080;
server_name *.wilker.cn; # 自己PC的ip或者服务器的域名 charset utf-8; # 避免中文乱码
root /mypublic; # 存放文件的目录
location / {
autoindex on; # 索引
autoindex_exact_size on; # 显示文件大小
autoindex_localtime on; # 显示文件时间
}
}

# https conf
# server
# {
# listen 32443 ssl;
# server_name www.wilker.cn;
# ssl_certificate /certs/cert_www/214597807690979.pem;
# ssl_certificate_key /certs/cert_www/214597807690979.key;
# ssl_session_timeout 5m;
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_prefer_server_ciphers on;
# location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
# }
# # location / {
# # proxy_redirect off;
# # 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_pass http://127.0.0.1;
# # }
# client_max_body_size 512M;
# access_log /var/log/nginx/www.wilker.cn.log;
# }

server
{
listen 32443 ssl;
server_name dl.wilker.cn;
ssl_certificate /certs/dl.wilker.cn/dl.wilker.cn.crt;
ssl_certificate_key /certs/dl.wilker.cn/dl.wilker.cn.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_redirect off;
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_pass http://10.0.3.4:8080;
}
client_max_body_size 512M;
access_log /var/log/nginx/dl.wilker.cn.log;
}

server
{
listen 32443 ssl;
server_name family.wilker.cn;
ssl_certificate /certs/family.wilker.cn/family.wilker.cn.crt;
ssl_certificate_key /certs/family.wilker.cn/family.wilker.cn.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_redirect off;
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_pass http://10.0.3.1:59305;
}
client_max_body_size 512M;
access_log /var/log/nginx/family.wilker.cn.log;
}

证书下载

证书相关文件 214816925260979.pem 和 214816925260979.key 直接从阿里云上下载, 下载的类型为 其他


获取其他容器的ip地址

如果没有通过 别名连接, 也可以通过ip连接, 首先得获取其他容器的ip地址, 进入其他容器的输入指令 # cat /etc/hosts

1
2
3
root@5c871bc66627:/usr/local/tomcat# cat /etc/hosts                                               
...
10.0.3.9 5c871bc66627
  • 可以获取到该容器的 docker ip 地址 及 实例id
  • 该ip地址会随容器的 stop start 而改变, 所以需要经常修改.

然后在 Nginx 中通过ip连接

1
2
3
...
proxy_pass http://10.0.3.9:8080;
...

参考链接


web 服务 配置

  1. xxx.conf 中加入配置

    1
    2
    3
    4
    5
    6
    7
    # web 服务
    server {
    listen 32081;
    server_name gitea.wilker.cn;
    root /mypublic;
    index index222.html
    }
  2. 访问: http://nas.wilker.cn:32081/


文件服务 配置

  1. xxx.conf 中加入配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server {
    listen 32080;
    server_name *.wilker.cn; # 自己PC的ip或者服务器的域名 charset utf-8; # 避免中文乱码
    root /mypublic; # 存放文件的目录
    location / {
    autoindex on; # 索引, off 则禁止列举文件
    autoindex_exact_size on; # 显示文件大小
    autoindex_localtime on; # 显示文件时间
    limit_rate 0; # 不限制速度
    }
    }
  2. 访问: http://nas.wilker.cn:32080/


Windows 版本

使用

  1. 解压, cd 到根目录, cmd 启动

    1
    $ start nginx
  2. 访问: http://localhost


踩坑

启动失败报错默认端口 80 被占用

错误: bind() to 0.0.0.0:80 failed

修改默认端口, 添加一个环境变量 NGINX_PORT

1
2
environment:
- NGINX_PORT=80

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