django系列13 - 部署代码到linux上

Posted 阿_焦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django系列13 - 部署代码到linux上相关的知识,希望对你有一定的参考价值。

腾讯云部署接口自动化平台

第一步、部署 portainer

  1. 云服务器中执行:yum update

  2. 安装并验证 docker、docker-compose,参考:docker学习总结2 - docker\\docker-compose安装配置

  3. 根目录下依次执行:
    mkdir /opt/vhosts/portainer
    cd /opt/vhosts/portainer
    touch docker-compose.yml

  4. 复制内容到 docker-compose.yml 中:

version: '3'

services:
  portainer:
    image: portainer/portainer-ce
    container_name: portainer
    restart: always
    ports:
      - 9001:9000
    command: -H unix:///var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

踩坑:
(1)第一次排查过程:
portainer官网:https://docs.portainer.io/v/ce-2.11/start/install/server/docker/linux
docker官网:https://hub.docker.com/r/portainer/portainer
访问portainer官网后,查看如何在linux部署后把commond那行去掉了,问题解决
(2) 第二次发现没有识别到我在服务器部署的容器,继续排查:
发现我把 docker-compose.yml 配错了,在- /var/run/docker.sock:/var/run/docker.sock最后少了个k,问题排查了2小时

  1. 登录 portainer:http://162.14.119.65:9001 后,创建管理员账号:admin / admin@123456

第二步、编写 Dockerfile 制作项目镜像

FROM python:3.8-buster
ENV PYTHONUNBUFFERED=1
ADD ./requirements.txt /app/requirements.txt

RUN sh -c "echo 'Asia/Shanghai' > /etc/timezone" \\
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \\
    && pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple \\ 
    && cd /app \\
    && mkdir static \\
    && pip install -r ./requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

#是否将源代码打包到镜像内?取决于什么因素?频繁的发版本就不要放里面了,只需要改下代码提价后,git自动拉取就好了
# ADD . /app

EXPOSE 8000
ENTRYPOINT cd /app; python manage.py collectstatic -c --no-input; gunicorn -b 0.0.0.0:8000 auto_test_platform.wsgi;

# 不管加不加 migrate ,需要注意到对后续流程的影响
# python manage.py migrate
  1. 关掉 add . /app ,没有将代码打包进镜像,意味着:我们开发了新功能,只需要 git pull 一下代码,重启下容器,就可以在linux中部署开发的功能了。
  2. 如果打开 add . /app,我们就将当前版本的代码放入镜像中,别人拉取代码镜像+其他部署需要的镜像部署容器后,进入镜像配置下 .env文件,启动容器就可以使用这个版本的功能了。

第三步、创建目录并拉取代码

  1. mkdir /opt/vhosts/auto-test-plt-project
  2. cd /opt/vhosts/auto-test-plt-project
  3. 拉取仓库代码:git clone https://gitee.com/jiao-tengfei/auto_test_platform.git
  4. 更新最新的仓库代码:git pull origin master

注意:
我这块拉取了100多M的代码,因为开发过程中我上传过其他资料文档,所以比较大。
注意你的代码仓库名必须是:auto_test_plt

第四步、编辑 .env 文件,设置生产环境变量

DEBUG=False
DATABASE_URL=mysql://auto_test_plt:atp2021$Atstudy@mysql-8:3306/auto_test_plt

TEST_PLT_API_TIMEOUT_CONNECT=3.1
TEST_PLT_API_TIMEOUT_RESP=30

LIST_PER_PAGE=10

LOG_DIR=/var/log/django
ERROR_LOG_FILE=error.log
INFO_LOG_FILE=info.log

LOG_TEST_PLT_LEVEL=WARNING

CELERY_BROKER_URL=amqp://rabbit:atstudy@162.14.119.65:5672/test_plt
CELERY_RESULT_EXPIRES=259200
CELERY_TASK_TIME_LIMIT=600

DINGTALK_WEB_HOOK_TOKEN=a97afd37850226e4f52bcf03f38ddaaeb5bdd6be626515e623e5005adb26c8a6
DINGTALK_WEB_HOOK_SIGN=SEC4b24231218a79134c9ee9602d54ccaadb8f7d3b41e698d217d5df2fced9ee972

注意:
(1)将 CELERY_BROKER_URL 的 ip 值修改为你的云服务器 ip**,这个用于连接 rabbitmq 的虚拟机test_plt,如果配置错误,会导致异步任务执行失败,界面报错 500,这个坑太深,我踩了4个小时。
(2)配置你自己的 DINGTALK_WEB_HOOK_TOKENDINGTALK_WEB_HOOK_SIGN

第五步、创建docker镜像、数据卷

构建自动化测试平台 docker 镜像,从前面可以看出这个镜像是用来运行我们开发的代码,并创建部署所需的 docker volume 数据卷,创建数据卷的意义在于我们删除了容器,不至于将我们写的N多条测试用例都给删除了,容器的数据卷会将数据都映射到容器外面。

# 构建镜像
cd /opt/vhosts/auto-test-plt-project/auto_test_platform
docker build -t auto_test_platform:v1.0.0 .

# 创建数据卷
cd /opt/vhosts/auto-test-plt-project
mkdir -p ./mysql-data 
mkdir -p ./rabbitmq-data 
mkdir -p ./logs/rabbitmq 
mkdir -p ./logs/django 
mkdir -p ./logs/worker 
mkdir -p ./logs/beat 
mkdir -p ./logs/flower 
mkdir -p ./logs/nginx 
mkdir -p ./nginx/

第六步、编写 nginx 、docker-compose 配置文件

  1. 创建nginx配置文件
    cd /opt/vhosts/auto-test-plt-project
    touch nginx/nginx.conf
  2. 复制以下内容到 nginx.conf
#user nobody;
worker_processes 1;
error_log /var/log/nginx/error.log;

events 
  worker_connections 1024; 


http 
  include mime.types;
  default_type application/octet-stream;
  access_log /var/log/nginx/access.log;
  sendfile on;
  keepalive_timeout 65;
  
  server 
    listen 80;
    server_name auto_test_platform;
		
    location /static/ 
      expires 30d;
      autoindex on;
      add_header Cache-Control private;
      alias /static/;
    
			
    location / 
      proxy_pass http://auto_test_platform-web:8000;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;
      proxy_redirect off;
    
  

  1. 创建 docker-compose.yml 文件
    cd /opt/vhosts/auto-test-plt-project
    touch docker-compose.yml
  2. 复制以下内容到 docker-compose.yml 中,并执行:docker-compose up -d
version: '3'

services:
  db:
    # ★注意:该镜像默认已经包含CONVERT_TZ所需的时区数据,不需要再从官网下载导入
    image: mysql
    container_name: mysql-8
    command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb_buffer_pool_size=512M
    restart: always
    ports:
      - 3306:3306
    volumes:
      - ./mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: Woaizhongguo@21cen
      MYSQL_DATABASE: auto_test_plt
      MYSQL_USER: auto_test_plt
      MYSQL_PASSWORD: atp2021$$Atstudy
      # ★注意:小心在docker-compose yml中$字面量必须用$$代替,尽量避免在密码中使用$。
    networks:
      - default

  phpmyadmin:
    image: phpmyadmin
    container_name: phpmyadmin
    depends_on:
      - db
    restart: always
    ports:
      - 8080:80
    environment:
      - PMA_HOST=mysql-8
      - PMA_PORT=3306
      - UPLOAD_LIMIT=20M
    networks:
      - default

  rabbitmq:
    image: rabbitmq:management
    container_name: rabbitmq-common
    # ★注意:先建立目录
    volumes:
      - ./rabbitmq-data/:/var/lib/rabbitmq/
    restart: always
    ports:
      - 5672:5672
      - 15672:15672
    environment:
      - RABBITMQ_DEFAULT_USER=rabbit
      - RABBITMQ_DEFAULT_PASS=atstudy
    networks:
      - default

  auto_test_plt:
    # ★注意:先git clone源码然后构建镜像 docker build -t auto_test_platform:v1.0.0 .
    image: auto_test_platform:v1.0.0
    container_name: auto_test_platform-web
    depends_on:
      - db
    working_dir: /app
    # ★注意:先建立目录
    volumes:
      - ./auto_test_platform:/app
      - ./logs/django:/var/log/django
    expose:
      - 8000
    networks:
      - default

  # 注意worker和beat的日志级别,稳定投产之后就不要用info了
  celery_worker:
    image: auto_test_platform:v1.0.0
    container_name: auto_test_platform-celery_worker
    depends_on:
      - auto_test_plt
      - rabbitmq
    working_dir: /app
    # ★注意:先建立目录volumes
    volumes:
      - ./auto_test_platform:/app
      - ./logs/worker:/var/log/worker
    entrypoint: celery -A auto_test_platform worker -l info -f /var/log/worker/celery-worker.log
    networks:
      - default

  celery_beat:
    image: auto_test_platform:v1.0.0
    container_name: auto_test_platform-celery_beat
    depends_on:
      - auto_test_plt
      - rabbitmq
    working_dir: /app
    # ★注意:先建立目录
    volumes:
      - ./auto_test_platform:/app
      - ./logs/beat:/var/log/beat
    entrypoint: celery -A auto_test_platform beat -l info -f /var/log/beat/celery-beat.log
    networks:
      - default

  celery_flower:
    image: auto_test_platform:v1.0.0
    container_name: auto_test_platform-celery_flower
    depends_on:
      - auto_test_plt
      - rabbitmq
    working_dir: /app
    ports:
      - 5555:5555
    volumes:
      - ./auto_test_platform:/app
      - ./logs/flower:/var/log/flower
    entrypoint: celery -A auto_test_platform flower --port=5555 --broker_api=http://rabbit:51testing@rabbitmq-common:15672/api/
    networks:
      - default

  nginx:
    image: nginx:latest
    container_name: auto_test_platform-nginx
    depends_on:
      - auto_test_plt
    # ★注意:先建立目录,复制nginx.conf
    volumes:
      - ./auto_test_platform/static:/static
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./logs/nginx:/var/log/nginx
    ports:
      - 80:80
    networks:
      - default

networks:
  default:
    driver: bridge

第七步、验证各个服务是否正常

  1. 打开腾讯云的相关端口:

5555(auto_test_platform-celery_flower)
80(auto_test_platform-nginx)
8080(phpmyadmin)
5672、15672(rabbitmq-common)
3306(mysql-8)
9001( portainer)

  1. 保存以下网站:

自动化测试平台:http://162.14.119.65/admin 【root / test@123】
portainer:http://162.14.119.65:9001【admin / admin@123456】
phpmyadmin:http://162.14.119.65:8080/【auto_test_plt / atp2021$Atstudy】
rabbitmq:http://162.14.119.65:15672/【rabbit / atstudy】
flower:http://162.14.119.65:5555/

  1. rabbitmq 中创建 host
  2. 数据库迁移


  3. 登录phpmyadmin,查看数据表的生成
  4. 登录portainer,重启相关报错容器后,全绿,进入各个容器查看日志是否报错

注意:
(1)启动报错:发现我少写了 ngix 的yml,补充后,继续查看容器日志是否有报错的
(2)启动报错:2022-07-27 13:23:34.405268+00:00 [noti] <0.44.0> Application rabbit exited with reason: >>cannot_log_to_file,"/var/log/rabbitmq/rabbit@

解决思路:
groupadd rabbitmq
useradd -m -g rabbitmq rabbitmq
chown -R rabbitmq:rabbitmq /var/log/rabbitmq/
还是没解决,最后,我直接把yml里面的日志数据卷给删掉了,好气啊

(3)beat报错:因为我们没有在rabbitmq中创建test_plt,所以 beat连接不上自动就会报错

第八步、给环境导入本地调测的数据

(1)打开 mysql workbench,菜单 server 》 data export ,去勾选5张表,因为之前migrate的数据库已经有数据了,会产生冲突,导出数据后并压缩成 zip 文件


(2)将zip文件导入 phpmyadmin 中

部署过程相关报错

  1. kombu.exceptions.OperationalError: [Errno 111] Connection refused
    解决办法:代码没有连接到 rabbit,部署 rabbit 的账号密码跟连接 rabbitmq 的密码不一致,另外,在云服务器中,连接 rabbitmq 不能用 locahost,应该使用服务器ip
  2. failed to open log file at ‘/var/log/rabbitmq/rabbit@1a98467c8a3a_upgrade.log’, reason: permission denied
    解决办法:去掉数据卷log,避免报错,后续再看

以上是关于django系列13 - 部署代码到linux上的主要内容,如果未能解决你的问题,请参考以下文章

python之Django部署

在Play with Kubernetes平台上以测试驱动的方式部署Istio

Linux如何去部署Django (Nginx + uwsgi + Python3 + Django)

Linux学习8-CentOS部署自己本地的django项目

Django部署在linux下,如何调试?

Linux(CentOS7)系统中部署Django web框架