1. 采用的服务结构


1.1 traefic

镜像:traefik
功能:协管80和443端口,当项目的docker-compose.yml执行时,会自动添加SSL证书,并到期自动续签。
目录结构:

缺点:其实traefik有更人性化的可视化服务,但是我们没有发挥到极致,相关学习视频和博客都比较少,而且基本都是关于可视化的traefik讲解,控制台操作内容比较少,学习成本高,花了我两天时间搞定。
想要学习traefik的同学请看:Docker container management with Traefik v2 and Portainer

1.2 nginx

镜像:nginx:1.16-alpine
功能:编写niginx.conf,开通http服务,正向代理和反向代理。
注意事项:我们的服务器采用的是Docker容器管理方式,哪怕是一个反向代理都需要单独开启一个nginx容器来管理服务,还有就是在容器里面的127.0.0.1只是容器的IP,反向代理需要用到服务器的私网IP——192.168.0.26
目录结构:src里面放项目,如果只用作反向代理,空着就行了。

缺点:浪费资源。

2. 正向代理


2.1 应用场景

H5页面和PHP页面都可以用Nginx正向代理,这其实就是一个文件目录的映射,实现页面渲染。

2.2 代码及详解

docker-compose.yml方式快速部署nginx项目。

version: '3'
services:
# 服务名字
  checkit:
    # 镜像版本
    image: nginx:1.16-alpine
    # 路径映射
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./src:/var/www
   
    networks:
      http-group:
    deploy:
     # labels下面是通过traefik设置这个服务的域名并获取SSL证书
      labels:
        traefik.enable: "true"
        traefik.http.services.lianliankanqian.loadbalancer.server.port: 80
        traefik.http.routers.lianliankanqian-unsecure.rule: Host(`standby3.bitworkshop.cn`) 
        traefik.http.routers.lianliankanqian-unsecure.entrypoints: web
        traefik.http.routers.lianliankanqian.rule: Host(`standby3.bitworkshop.cn`) 
        traefik.http.routers.lianliankanqian.entrypoints: websecure
        traefik.http.routers.lianliankanqian.tls.certresolver: letsencrypt
    command: [nginx, '-g', 'daemon off;']
networks:
    http-group:
      external:
        name: traefik

编写代理配置文件nginx.conf

user root;
worker_processes 1;
pid /run/nginx.pid;

events {
    worker_connections 127;
}

http {
    include /etc/nginx/mime.types;
	default_type application/octet-stream;
    access_log /dev/stdout;
    error_log /dev/stderr;

    gzip on;
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_http_version 1.1;

    server {
        listen 80;
        server_name _;
        root /var/www;
        index index.html;
  # 设置首页入口
    }
}

3. 反向代理


3.1 应用场景

后端程序运行在非80端口,需要Nginx反向代理至80端口访问。

3.2 代码及详解

docker-compose.yml,本项目是比特工程绩点查询,其程序本体运行在大活104电脑上,通过比特阿里云服务器内网穿透,这里穿透到5444端口,可以理解现在这个程序在服务器的5444端口运行,现在需求是将其代理至80端口,添加域名,并添加SSL证书安全访问。

version: '3'
services:
  checkit:
    image: nginx:1.16-alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./src:/var/www
   
    networks:
      http-group:
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.services.checkit.loadbalancer.server.port: 80
        traefik.http.routers.checkit-unsecure.rule: Host(`checkit.bitworkshop.cn`) 
        traefik.http.routers.checkit-unsecure.entrypoints: web
        traefik.http.routers.checkit.rule: Host(`checkit.bitworkshop.cn`) 
        traefik.http.routers.checkit.entrypoints: websecure
        traefik.http.routers.checkit.tls.certresolver: letsencrypt
    command: [nginx, '-g', 'daemon off;']
networks:
    http-group:
      external:
        name: traefik

编写nginx.conf,这里其他格式都差不多,唯一不一样的地方就是多了Location ^~ /{},而正在起到反向代理的代码是proxy_pass http://192.168.0.26:5444;
我理解是Nginx在监听80端口的时候,一旦监听到有人访问域名,就转发至http://192.168.0.26:5444的程序。
由于这里部署方式是Docker容器,所以http://127.0.0.1:5444是不行的。

user root;
worker_processes 1;
pid /run/nginx.pid;

events {
    worker_connections 127;
}

http {
    include /etc/nginx/mime.types;
	default_type application/octet-stream;
    access_log /dev/stdout;
    error_log /dev/stderr;

    gzip on;
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_http_version 1.1;                                                                                                                                                              

    server {
        listen 80;
        server_name checkit;
        root /var/www;
        location ^~ /
        {
            proxy_pass http://192.168.0.26:5444;

            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 REMOTE-HOST $remote_addr;
            
            add_header X-Cache $upstream_cache_status;
            
            #Set Nginx Cache
            
            set $static_fileEZHQIxW9 0;
            if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
            {
                set $static_fileEZHQIxW9 1;
                expires 12h;
                }
            if ( $static_fileEZHQIxW9 = 0 )
            {
            add_header Cache-Control no-cache;
            }
        }
    }
}

个人感觉比较浪费资源,我只是添加个反向代理都得开个单独的Nginx容器。

3. Docker部署命令

执行docker-compose.yml,生成docker service(保证容器不被关闭,容器一旦关闭会服务会重新启动)。

docker stack deploy -c docker-compose.yml 服务的名称 --with-registry-auth

执行后traefik就会去申请SSL证书,一般十分钟内会自动添加,所以https会一时没反应,不是错了,是证书还没到。
注意:这里添加证书之后,需要重启一下traefik服务才会生效。

这里我们用的是Nginx官方镜像,不需要制作镜像,这个过程用的最多就三条命令,多敲几次就熟练了。

# 查看docker服务
docker service ls
# 去除某个服务
docker service rm 服务ID
# 生成服务
docker stack deploy -c docker-compose.yml 服务的名称 --with-registry-auth