docker nginx 代理多个网站和应用

条件和需求

  • 测试环境:centos7系统的阿里云服务器一台
  • flask编写的一个api接口项目,可以对外进行api接口访问
  • vue编写的一个静态网站,需要内部访问flask的api接口
  • emqx搭建的mqtt服务器,客户端需要对外访问websocket链接

docker 安装过程

docker安装教程-centos

项目目录结构

- flask  	// flask项目
	- Dockerfile // flask容器对应的Dockerfile
	- app   
		- app	
		- dist    // vue静态网站存放位置
		- manager.py
		- uwsgi.ini  // uwsgi配置文件
		- requirement.txt  // flask项目所需包
- mysql
	- data    // mysql数据库保存数据文件夹
	- conf	 // mysql配置文件存放位置
	- init 	 // mysql初始化执行的sql存放位置,此文件只在第一次创建容器时会执行
- nginx
	- conf.d
		- nginx.conf      // flask网站的80端口内部代理api接口,用于vue内部api进行访问
		- flask.conf		//  域名访问的api接口,用于外部访问
		- vue.conf		// vue静态网站配置,域名访问
		- emqx.conf     // emqx配置,websocket代理访问
	- certs // nginx域名相关证书文件存放位置
- docker-compose.yml

关键文件说明:

根目录docker-compose.yml 文件

version: '3'
services:
  nginx-uwsgi-flask:
    build: ./
    links:
      - mysql
      - emqx
    volumes:
      - ./app:/app
      - ./nginx/conf.d:/etc/nginx/conf.d  // nginx配置文件存放位置
      - ./nginx/certs:/etc/nginx/certs     // 证书存放位置
    ports:
      - "80:80"
      - "443:443"
    environment:
      - FLASK_APP=app/manager.py
      - FLASK_DEBUG=1
      - 'RUN=flask run --host=0.0.0.0 --port=80'
    restart: always
  mysql:
    build: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: p@ssw0rd123
    ports:
      - "3305:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d/
      # - ./mysql/conf/my.cnf:/etc/my.cnf
    restart: always
  emqx:
    image: emqx/emqx:latest
    environment:
      EMQX_LISTENER__TCP__EXTERNAL: 1883
      EMQX_LISTENER__WS__EXTERNAL: 8083
    ports:
      - "1883:1883"
      - "8083:8083"
      - "18083:18083"
    restart: always

说明:这里使用docker-compose , 将下面三个容器连接在一起运行

  1. nginx-uwsgi-flask容器
  2. mysql容器
  3. emqx容器

其中nginx-uwsgi-flask容器link了mysql和emqx容器,mysql容器用于nginx-uwsgi-flask中数据库的访问和连接操作,emqx的websocket端口nginx代理在nginx-uwsgi-flask容器中

flask目录下相关文件

  • Dockerfile文件
FROM tiangolo/uwsgi-nginx-flask:python3.5
COPY ./app /app
RUN pip3 install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com -r /app/requirements.txt

这里采用docker镜像tiangolo/uwsgi-nginx-flask:python3.5
uwsgi-nginx-flask镜像使用方法连接

  • uwsgi.ini 文件
[uwsgi]
chdir=/app
module=manager
callable=app
master=true
socket=/tmp/uwsgi.sock
pidfile=/tmp/uwsgi.pid
daemonize=/tmp/uwsgi.log

nginx目录下cont.d文件夹相关配置文件

  • nginx.conf :监听80端口,代理uwsgi运行的flask容器对应的uwsgi.sock
server {
    listen 80;
    location / {
        try_files $uri @app;
    }
    location @app {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
    location /static {
        alias /app/static;
    }
}
  • flask.conf : 域名访问,反向代理本地80端口,即nginx.conf代理的uwsgi的80端口,实现域名访问api接口,,外部通过https://yourdomain.cn/api访问你api接口
server {
    server_name yourdomain.cn;
    listen 443 ssl;
    ssl_certificate /etc/nginx/certs/2361849_yourdomain.cn.pem;
    ssl_certificate_key /etc/nginx/certs/2361849_yourdomain.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_session_cache shared:SSL:50m;
    location / {
        try_files $uri @app;
    }
    location @app {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
    location /static {
        alias /app/static;
    }
}
  • vue.conf : 域名访问, 代理vue生成的静态网页 app/dist文件夹,并反向代理vue项目中的/prod-api接口到本地的80端口,外部通过https://www.yourdomain.cn访问你的vue网站
upstream webapi {
  server localhost:80 weight=1;
}
server {
    server_name www.yourdomain.cn;
    listen 443 ssl;
    ssl_certificate /etc/nginx/certs/2361849_www.yourdomain.cn.pem;
    ssl_certificate_key /etc/nginx/certs/2361849_www.yourdomain.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_session_cache shared:SSL:50m;
    error_log  /tmp/vue_nginx.log warn;
    location / {
        try_files $uri $uri/ /index.html last;
        root   /app/dist;
        index  index.html;
    }
    location ^~ /prod-api {
        proxy_pass http://webapi/api;
    }
}
  • emqx.conf : websocket代理emqx的8083端口,外部通过wss://mqtt.yourdomain.cn/mqtt连接emqx
server {
    server_name mqtt.yourdomain.cn; #填写绑定证书的域名

    listen 443 ssl;

    ssl_certificate /etc/nginx/certs/2387577_mqtt.yourdomain.cn.pem;
    ssl_certificate_key /etc/nginx/certs/2387577_mqtt.yourdomain.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
    ssl_prefer_server_ciphers on;

    location /mqtt {
        proxy_pass http://emqx:8083;
        proxy_redirect off;
        proxy_set_header Host $host;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        }
}

这里面需要注意的是这两行,这里表示代理的是emqx容器的8083端口,header使用的是$host变量 :

		proxy_pass http://emqx:8083;
        proxy_set_header Host $host;

你可能感兴趣的:(docker)