条件和需求
- 测试环境:centos7系统的阿里云服务器一台
- flask编写的一个api接口项目,可以对外进行api接口访问
- vue编写的一个静态网站,需要内部访问flask的api接口
- emqx搭建的mqtt服务器,客户端需要对外访问websocket链接
docker 安装过程
项目目录结构
- 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 , 将下面三个容器连接在一起运行
- nginx-uwsgi-flask容器
- mysql容器
- 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;