云锁docker部署注意点

注意事项目

一、将阿里云服务器80、8088、9000、3306四个端口打开;
二、部署顺序:mysql》》》nginx》》》redis》》》django》》》fastapi
三、mysql
1、修改远程访问密码,跟django和fastapi中设置文件(settings.py和config.py)的密码一致;
2、字符集修改为utf-8;
四、nginx
1、nginx原有的设置文件nginx.conf不做任何改动;
2、添加自有配置文件 xiaoyan到目录conf.d;
3、启动容器后,进入容器bash界面,使用命令(nginx -c /etc/nginx/conf.d/xiaoyan)装入自有配置。
五、django
1、修改代码设置文件(/yunshuo/django/code/xiaoyanwebsite/XiaoyanWebsite/settings.py)中的mysql的host地址和访问密码;
2、django容器启动后,到code目录中运行命令(uwsgi --ini uwsgi.ini),以启动uwsgi服务。
六、fastapi
1、修改代码设置文件(/yunshuo/fastapi/code/DataManager/MySQLManager.py)中的mysql的host地址和访问密码;
2、fastapi容器启动后,到code目录中运行命令(gunicorn -c config.py main:app),以启动gunicorn服务。

 

nginx部署(原nginx.conf不动,自有配置内容在/yunshuo/nginx/conf.d/xiaoyan文件中)

一、dockerfile

FROM nginx:1.14

COPY nginx/conf.d /etc/nginx/conf.d

WORKDIR /etc/nginx
RUN mkdir html log

二、build docker

docker build -f nginx_dockerfile -t xiaoyan-nginx:1.0 .

三、运行docker

docker run -d --restart=always -p 9000:9000 -p 80:80 -p 8088:8088 -v /yunshuo/nginx/conf.d:/etc/nginx/conf.d -v /yunshuo/nginx/log:/etc/nginx/log -v /yunshuo/nginx/html:/etc/nginx/html --name my-nginx xiaoyan-nginx:1.0

四、进入容器bash中装载自有配置文件

[root@sam4core yunshuo]# docker exec -it b9d60c1e68f2 /bin/bash

root@b9d60c1e68f2:/etc/nginx/conf.d# nginx -c /etc/nginx/conf.d/xiaoyan
2022/05/26 06:34:28 [emerg] 14#14: open() "/etc/nginx/log/frontend/nginx_access.log" failed (2: No such file or directory)
nginx: [emerg] open() "/etc/nginx/log/frontend/nginx_access.log" failed (2: No such file or directory)

root@b9d60c1e68f2:/etc/nginx/log# mkdir fastapi
root@b9d60c1e68f2:/etc/nginx/log# mkdir frontend
root@b9d60c1e68f2:/etc/nginx/log# mkdir django

root@b9d60c1e68f2:/etc/nginx/conf.d# nginx -c /etc/nginx/conf.d/xiaoyan

五、解决nginx中访问后端的跨域问题

      1、后端访问有2种方式

    跨域       https://www.xiaoyan.link:9000/            跨域        http://www.xiaoyan.link:8088/api/test/ 
          非跨域    https://www.xiaoyan.link/fastapi          非跨域     https://www.xiaoyan.link/django/api/test/

      2、非跨域访问方式,跟前端用同样的端口号(80或443),增加标志性的后缀,转发前删除后缀,如下列例子中的 django 和 fastapi     

        #后端django API地址暴露为:http://www.xiaoyan.link/django
        #http://www.xiaoyan.link/django/api/test/
        location /django {
            proxy_pass http://127.0.0.1:8080/;
            proxy_pass_request_headers on;
            # 重写URL,去掉django
            rewrite "^/django/(.*)$" /$1 break;
        }    
        #后端fastapi API地址暴露为:http://www.xiaoyan.link/fastapi
        #http://www.xiaoyan.link/fastapi
        location /fastapi {
            proxy_pass http://127.0.0.1:9001/;
            proxy_pass_request_headers on;
            # 重写URL,去掉fastapi
            rewrite "^/fastapi/(.*)$" /$1 break;
        }        

       3、跨域方式,使用单独的端口号

    server {
        listen 8088;
        server_name 121.43.147.156 xiaoyan.link;

        index index.html;
        location / {
            proxy_pass http://django/; # 将指定的ip或者域名的http请求转发到upstream池中
            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;
        }
        access_log      /etc/nginx/log/django/nginx_access.log;
        error_log       /etc/nginx/log/django/nginx_error.log;
    }


    server {
        listen 9000;
        ssl    on;
        server_name 121.43.147.156 xiaoyan.link;

        #ssl configuration
        ssl_certificate    /etc/nginx/conf.d/7852698_www.xiaoyan.link.pem; #open here
        ssl_certificate_key     /etc/nginx/conf.d/7852698_www.xiaoyan.link.key; #open here
        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_pass http://fastapi/; # 将指定的ip或者域名的http请求转发到upstream池中
            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;
        }
        access_log      /etc/nginx/log/fastapi/nginx_access.log;
        error_log       /etc/nginx/log/fastapi/nginx_error.log;
    }

六、前端echo浏览器的文件类型必须正确,有专门的类型配置语句

http {
    include    /etc/nginx/mime.types;
    default_type  application/octet-stream;

    upstream django {
        server 127.0.0.1:8080; # django.gunicorn(0.0.0.0:8080)
    }
    upstream fastapi {
        server 127.0.0.1:9001; # fastapi.gunicorn(0.0.0.0:9001)
    }

七、配置ssl文件,要将ssl pem和key文件拷贝到相应位置

    server {
        listen 80;
        listen 443 ssl; #open here
        server_name 121.43.147.156 xiaoyan.link;

        #ssl configuration
        ssl_certificate    /etc/nginx/conf.d/7852698_www.xiaoyan.link.pem; #open here
        ssl_certificate_key     /etc/nginx/conf.d/7852698_www.xiaoyan.link.key; #open here
        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;

 

redis部署 (可用配置文件:/yunshuo/redis/redis.conf)

最佳参考 https://blog.csdn.net/wangyue23com/article/details/110194399

一、配置文件关键点

      修改redis.conf配置:

      1.dir 配置,改为如下 /data 工作目录

        # Note that you must specify a directory here, not a file name.
        dir /data
      2.logfile配置,修改log路径 为/data目录下

        # output for logging but daemonize, logs will be sent to /dev/null
        logfile /data/redis.log

      3、在共用nginx网络模式下无法确认redis已经正常工作,可以设置loglevel=debug,这样每次写入数据和连接redis都可以在log上实时看到

# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel debug

# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile /data/redis.log

二、redis docker有2个主要工作目录

      1、/etc目录下放置 redis.conf文件

      2、/data目录下放置 db文件和log文件

三、运行部署容器命令

云锁部署方式,与nginx网络联结
docker run -d --restart=always --name my-redis --network container:my-nginx --privileged=true -v /yunshuo/redis/redis.conf:/etc/redis.conf -v /yunshuo/redis/data:/data redis:6.0 redis-server /etc/redis.conf
网上例子
docker run -itd  --name  redis --privileged=true -v /etc/redis.conf:/etc/redis.conf -v /usr/local/redis/data:/data  -p 6379:6379  redis redis-server /etc/redis.conf

四、进入容器确认安装好

进入容器命令
[root@sam4core yunshuo]# docker exec -it cd4c8ce8dabc bash

查看/etc/redis.conf和/data目录内容
root@b9d60c1e68f2:/# ls /etc/redis.conf
/etc/redis.conf
root@b9d60c1e68f2:/# cd /data        
root@b9d60c1e68f2:/data# ls
dump.rdb  redis-server.log  redis.log
root@b9d60c1e68f2:/data# cat redis.log
1:C 26 May 2022 08:37:43.708 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 26 May 2022 08:37:43.708 # Redis version=6.0.16, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 26 May 2022 08:37:43.708 # Configuration loaded

查看log内容
root@a0436e256c18:/data# cat redis.log

 

mysql部署 (mysql只认3306端口外面用3308还是3307,都要映射到docker内3306,密码见笔记和连接软件)

一、拷贝配置文件

      /docker/mysql001/config   >>>>>>   /yunshuo/mysql/conf.d

二、运行run命令生成容器     

1、run生成容器
[root@sam4core yunshuo]# docker run -d -p 3308:3306 --privileged=true -v /yunshuo/mysql/log:/var/log/mysql -v /yunshuo/mysql/data:/var/lib/mysql -v /yunshuo/mysql/my.conf:/etc/mysql/my.conf -e MYSQL_ROOT_PASSWORD=emi,.123456 --name my-mysql mysql:5.7
c114cf48cdb7e7620d627d39867f15af38161c0db3b5c9274f5ed9a2f1673de8
2、进入容器
[root@sam4core yunshuo]# docker exec -it c114cf48cdb7 bash
3、进入数据库管理设置
root@c114cf48cdb7:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)
4、设置远程登陆密码
mysql> grant all privileges on *.* to root@'%' identified by 'emi.123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
5、设置本地登陆密码
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('emi.123456'); 
Query OK, 0 rows affected, 1 warning (0.00 sec)

 

django部署

最佳参考:https://www.jianshu.com/p/12fd6fb59d4d

一、build命令

[root@sam4core yunshuo]# docker build -f django_dockerfile -t xiaoyan-django:1.0 .

二、run命令生成容器

[root@sam4core yunshuo]# docker run -it  --restart=always --name my-django -v /yunshuo/django/code/xiaoyanwebsite:/code/xiaoyanwebsite -v /yunshuo/django/log:/code/log --network container:my-nginx xiaoyan-django:1.0

三、启动uwsgi服务

# uwsgi --ini uwsgi.ini
[uWSGI] getting INI configuration from uwsgi.ini

 

四、gunicorn部署django

docker run命令
docker run -it  --restart=always --name my-django -v /yunshuo/django/code:/code --network container:my-nginx xiaoyan-django:1.0
容器内启动gunicorn
gunicorn xiaoyan.wsgi:application -c gunicorn.conf.py
build命令
docker build -f gunicorn_dockerfile -t xiaoyan-django:1.0 .
容器启动命令(宿主机端口映射方式)
docker run -d  --restart=always --name my-django -v /yunshuo/django/code:/code  -p 3000:8080 xiaoyan-django:1.0 /bin/bash -c "gunicorn XiaoyanWebsite.wsgi:application -c gunicorn.conf.py"
容器启动命令(nginx网络联结方式)
docker run -d  --restart=always --name my-django -v /yunshuo/django/code:/code  --network container:my-nginx xiaoyan-django:1.0 /bin/bash -c "gunicorn XiaoyanWebsite.wsgi:application -c gunicorn.conf.py"
gunicorn.conf.py配置文件

# -*- coding: utf-8 -*-
#import multiprocessing
#from pathlib import Path

#BASE_DIR = Path(__file__).resolve(strict=True).parent.parent.parent.parent

debug = True

# ============================================================
# gunicorn要切换到的目的工作目录
# ============================================================

#chdir = str(BASE_DIR)
#chdir = '/code/xiaoyanwebsite'

# ============================================================
# server socket相关
# ============================================================

# 指定绑定的ip和端口   注:docker映射端口时默认IP使用0.0.0.0,而不是django平时测试使用的127.0.0.1,
用gunicorn部署主机IP必须设置为0.0.0.0,更奇怪的是nginx送过来的IP必须是127.0.0.1,gunicorn才接受。
bind = "0.0.0.0:8080"
# 服务器中排队等待的最大连接数,建议值64-2048,超过2048时client连接会得到一个error backlog = 2048 # ============================================================ # 调试相关 # ============================================================ # 当代码有修改时,自动重启workers,适用于开发环境 reload = False # 以守护进程形式来运行Gunicorn进程,其实就是将这个服务放到后台去运行 daemon = False # ============================================================ # worker进程相关 # ============================================================ # 用于处理工作的进程数 workers = 1 # worker进程的工作方式,有sync、eventlet、gevent、tornado、gthread, 默认是sync, # django使用gevent容易造成阻塞, 使用gthread的方式好一些 worker_class = 'sync' # 指定每个工作进程开启的线程数 threads = 3 # 访问超时时间 timeout = 30 # 接收到restart信号后,worker可以在graceful_timeout时间内,继续处理完当前requests graceful_timeout = 60 # server端保持连接时间 keepalive = 30 # ============================================================ # 日志相关 # ============================================================ """日志文件格式,其每个选项的含义如下: h remote address l '-' u currently '-', may be user name in future releases t date of the request r status line (e.g. ``GET / HTTP/1.1``) s status b response length or '-' f referer a user agent T request time in seconds D request time in microseconds L request time in decimal seconds p process ID """ access_log_format = '%(t)s %(h)s "%(r)s" %(s)s %(b)s "%(f)s" "%(L)s"' LOG_DIR = '/code' #LOG_DIR = Path(BASE_DIR, 'log') #if not LOG_DIR.exists(): # LOG_DIR.mkdir(parents=True) # 错误日志输出等级,访问日志的输出等级无法设置 loglevel = "debug" # 正常的日志文件路径,'-'表示输出到终端 accesslog = '/code/xiaoyanwebsite/gunicorn_accesslog.log' # 错误日志文件路径,'-'表示输出到终端 errorlog = '/code/xiaoyanwebsite/gunicorn_error.log' # ============================================================ # 进程名相关 # ============================================================ # 设置进程名称,默认是gunicorn proc_name = 'gunicorn_yunsuo'

 

 

gunicorn_dockerfile

# 从仓库拉取带有python3.8的Linux环境
FROM python:3.8.6

# 镜像维护者的姓名和邮箱地址
MAINTAINER chenxiaojie  <390976522@qq.com>

# 因为墙的关系,有时安装库可能会很慢或者失败,所以推荐使用国内镜像源
# 此处是创建一个指向阿里云镜像源的参数,以便后面引用
#ARG pip_url=http://mirrors.aliyun.com/pypi/simple/
#ARG pip_host=mirrors.aliyun.com

# 设置python环境变量
ENV PYTHONUNBUFFERED 1

# 容器默认的时间是UTC时间,此处设置为上海时间
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 定义一个变量,其值为项目在docker容器中的工作目录
ARG work_home=/code

# 在容器中创建code文件夹
RUN mkdir ${work_home}

# 将容器中的room文件夹设置为工作目录,拷贝代码到工作目录
WORKDIR /code/xiaoyanwebsite

# 拷贝代码到容器的code目录,因为build中指定的context环境目录为project这一层,所以当前目录即项目目录
COPY django/code ${work_home}

# 将django/code下的startapp.sh 文件拷贝到容器的根目录下
COPY django/code/gunicorn_start.sh /gunicorn_start.sh
# 将django/code下的wait-for-it.sh文件拷贝到容器的根目录下
COPY django/code/wait-for-it.sh /wait-for-it.sh

# 修改文件权限 ,为sh文件增加可执行
RUN chmod +x /gunicorn_start.sh
RUN chmod +x /wait-for-it.sh
RUN chmod +x /code/gunicorn_start.sh
RUN chmod +x /code/wait-for-it.sh

# 更新pip
#RUN pip install pip -U
RUN python -m pip install --upgrade pip -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com/simple/

# 安装所有依赖库
#RUN pip install -r ./xiaoyanwebsite/requirements.txt -i ${pip_url} --trusted-host ${pip_host}
RUN pip install -r ./xiaoyanwebsite/requirements.txt -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com/simple/


CMD ["sh"]

 

fastapi部署思路

fastapi部署总体思路:uvicorn运行代码,gunicorn当服务器

if __name__ == '__main__':
    uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)

# 启动命令
gunicorn main:app -b 0.0.0.0:8001 -w 4 -k uvicorn.workers.UvicornWorker  # -D 守护启动 -c 配置文件

 

dockerfile

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
#FROM python:3.8.6-slim

COPY fastapi/code /code

WORKDIR /code

RUN python -m pip install --upgrade pip -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com/simple/
RUN pip install -r requirements.txt -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com/simple/

CMD ["sh"]

 

build命令

docker build -f fastapi_dockerfile -t xiaoyan-fastapi:1.1 .

容器run运行命令

docker run -itd --name my-fastapi -v /yunshuo/fastapi/code:/code  -p 3000:9001  xiaoyan-fastapi:1.1 /bin/bash -c "gunicorn main:app -k uvicorn.workers.UvicornWorker -c gunicorn.conf.py"
项目名:main:app  (main.py启动代码中有)
类别:-k uvicorn.workers.UvicornWorker 
设置文件:-c gunicorn.conf.py

设置文件(gunicorn.conf.py)

# -*- coding: utf-8 -*-
#import multiprocessing
#from pathlib import Path

#BASE_DIR = Path(__file__).resolve(strict=True).parent.parent.parent.parent

debug = True

# ============================================================
# gunicorn要切换到的目的工作目录
# ============================================================

#chdir = str(BASE_DIR)
#chdir = '/code/xiaoyanwebsite'

# ============================================================
# server socket相关
# ============================================================

# 指定绑定的ip和端口, 注:docker默认映射主机是0.0.0.0,而不是django项目通常的127.0.0.1
bind = "0.0.0.0:9001"

# 服务器中排队等待的最大连接数,建议值64-2048,超过2048时client连接会得到一个error
backlog = 2048

# ============================================================
# 调试相关
# ============================================================

# 当代码有修改时,自动重启workers,适用于开发环境
reload = False

# 以守护进程形式来运行Gunicorn进程,其实就是将这个服务放到后台去运行
daemon = False

# ============================================================
# worker进程相关
# ============================================================

# 用于处理工作的进程数
workers = 1

# worker进程的工作方式,有sync、eventlet、gevent、tornado、gthread, 默认是sync,
# django使用gevent容易造成阻塞, 使用gthread的方式好一些
worker_class = 'sync'

# 指定每个工作进程开启的线程数
threads = 3

# 访问超时时间
timeout = 30

# 接收到restart信号后,worker可以在graceful_timeout时间内,继续处理完当前requests
graceful_timeout = 60

# server端保持连接时间
keepalive = 30

# ============================================================
# 日志相关
# ============================================================

"""日志文件格式,其每个选项的含义如下:
h          remote address
l          '-'
u          currently '-', may be user name in future releases
t          date of the request
r          status line (e.g. ``GET / HTTP/1.1``)
s          status
b          response length or '-'
f          referer
a          user agent
T          request time in seconds
D          request time in microseconds
L          request time in decimal seconds
p          process ID
"""
access_log_format = '%(t)s %(h)s "%(r)s" %(s)s %(b)s "%(f)s" "%(L)s"'

LOG_DIR = '/code'
#LOG_DIR = Path(BASE_DIR, 'log')
#if not LOG_DIR.exists():
#    LOG_DIR.mkdir(parents=True)

# 错误日志输出等级,访问日志的输出等级无法设置
loglevel = "debug"

# 正常的日志文件路径,'-'表示输出到终端
accesslog = '/code/logs/gunicorn_accesslog.log'

# 错误日志文件路径,'-'表示输出到终端
errorlog =  '/code/logs/gunicorn_error.log'

# ============================================================
# 进程名相关
# ============================================================

# 设置进程名称,默认是gunicorn
proc_name = 'fastapi_yunsuo'

 

posted @ 2022-05-26 13:59  pearlcity  阅读(148)  评论(0编辑  收藏  举报