docker+nginx反向代理做统一出入口

使用nginx反向代理docker容器的服务,从而避免暴露过多的端口

nginx的安装见 之前的博客 docker搭建nginx

预期效果:
只有nginx和主机进行了端口映射,其他容器都没有映射。全部都由nginx去转发到对应的应用上去。

1
2
3
4
5
6
7
8
9
10

[root@zmr-service ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bc7425371cb lizheming/waline:1.30.4 "docker-entrypoint.s…" 22 hours ago Up 22 hours 8360/tcp waline
af3b2f1b7892 nginx:1.24.0 "/docker-entrypoint.…" 39 hours ago Up 24 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx
60ba55559d39 snowdreamtech/frpc:0.48.0 "/bin/sh -c '/usr/bi…" 13 days ago Up 24 hours frpc
61e4f29b5ebc gitea/gitea:1.19.0 "/usr/bin/entrypoint…" 2 weeks ago Up 38 hours 22/tcp, 3000/tcp gitea
413621548b9a mysql/mysql-server:8.0.32 "/entrypoint.sh --de…" 2 weeks ago Up 38 hours (healthy) 3306/tcp, 33060-33061/tcp mysql8
[root@zmr-service ~]#

  1. 核心就是所有的docker容器都使用相同的网络。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 创建网卡
    docker network create -d bridge app_net

    [root@zmr-service ~]# docker network ls
    NETWORK ID NAME DRIVER SCOPE
    391b4ed84d89 app_net bridge local
    fab5d9edb87f bridge bridge local
    e976eb0945b9 host host local
    fa4d4514eb40 none null local
  2. 然后所有的docker-compose.yml中都指定使用这个网卡:

    nginx的docker-compose.yml为例,其它容器也都使用相同的网络配置:

    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
    [root@zmr-service nginx]# cat docker-compose.yml
    version: "3"

    services:
    nginx:
    container_name: nginx
    image: nginx:1.24.0
    restart: always
    ports: # 其他容器将ports全部都注释掉,表示不映射端口
    - 80:80
    - 443:443
    volumes:
    - /opt/docker-data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
    - /opt/docker-data/nginx/www:/home/www
    - /opt/docker-data/nginx/logs:/var/log/nginx
    - /opt/docker-data/nginx/conf/conf.d:/etc/nginx/conf.d
    - /opt/docker-data/nginx/html:/usr/share/nginx/html
    # 这里指定使用的网络
    networks:
    - app_net

    # 这里指定使用的网络
    networks:
    app_net:
    external: true
  3. nginx做反向代理的配置

先确认能nginx容器和其他容器都是通的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@zmr-service conf.d]# docker exec -it nginx ping gitea
PING gitea (172.25.0.4): 56 data bytes
64 bytes from 172.25.0.4: icmp_seq=0 ttl=64 time=0.190 ms
64 bytes from 172.25.0.4: icmp_seq=1 ttl=64 time=0.134 ms
64 bytes from 172.25.0.4: icmp_seq=2 ttl=64 time=0.148 ms
64 bytes from 172.25.0.4: icmp_seq=3 ttl=64 time=0.133 ms
64 bytes from 172.25.0.4: icmp_seq=4 ttl=64 time=0.128 ms
64 bytes from 172.25.0.4: icmp_seq=5 ttl=64 time=0.130 ms
64 bytes from 172.25.0.4: icmp_seq=6 ttl=64 time=0.131 ms
64 bytes from 172.25.0.4: icmp_seq=7 ttl=64 time=0.130 ms

[root@zmr-service conf.d]# docker exec -it nginx ping waline
PING waline (172.25.0.5): 56 data bytes
64 bytes from 172.25.0.5: icmp_seq=0 ttl=64 time=0.261 ms
64 bytes from 172.25.0.5: icmp_seq=1 ttl=64 time=0.136 ms
64 bytes from 172.25.0.5: icmp_seq=2 ttl=64 time=0.139 ms

配置nginx反向代理

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
[root@zmr-service conf.d]# cat app.conf

upstream gitea {
server gitea:3000;
}

upstream waline {
server waline:8360;
}



server {
listen 443 ssl;
server_name waline.test.com; #当访问https://waline.test.com ,会将其转发到 waline:8360

ssl_certificate /etc/nginx/conf.d/ssl/fullchain1.pem;
ssl_certificate_key /etc/nginx/conf.d/ssl/privkey1.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";

set_real_ip_from waline.test.com;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

location /{
proxy_pass http://waline; #转发的地址
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;
proxy_set_header REMOTE-HOST $remote_addr;
add_header X-Cache $upstream_cache_status;
# cache
add_header Cache-Control no-cache;
expires 12h;
}
}


server {
listen 443 ssl;
server_name gitea.test.com; #当访问https://gitea.test.com ,会将其转发到 gitea:3000

ssl_certificate /etc/nginx/conf.d/ssl/fullchain1.pem;
ssl_certificate_key /etc/nginx/conf.d/ssl/privkey1.pem;

location /{
client_max_body_size 128m;
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://gitea; #转发的地址
}
}