欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用docker-compose部署Django前后端分离项目

程序员文章站 2022-06-13 16:34:14
...

1. 打包开发环境中的后端项目镜像

后端Django的Dockefile:

FROM python:3.7

RUN apt-get update \
    && apt-get upgrade -y \
    && apt-get -y install vim \
    && mkdir -p /home/backend \
    && cd /home/backend \
    && mkdir static \
    && mkdir media \
    && mkdir logs \
    && rm -r /var/lib/apt/lists/*

ENV PYTHONUNBUFFERED 1

ENV ConfigPath "production"

WORKDIR /home/backend

COPY ./requirements.txt /home/backend

RUN pip install -r /home/backend/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple \
    && rm -rf ~/.cache/pip \
    && rm -rf /tmp

COPY ./ /home/backend

CMD ["/usr/local/bin/daphne", "-b", "0.0.0.0", "-p", "8000", "--proxy-headers", "config.asgi:application"]

用python:3.7这种指定版本的镜像作为基础镜像,使用ubuntu系统,优点是环境全面、相对保险。但缺点是最终镜像的体积较大,后期可以改进为alpine版本;
更新镜像内的软件,新建backend目录用于存放django项目代码,并新建static、media、logs路径用于存放服务运行中产生的相应文件;
设置两个环境变量,一个用于python的缓存,一个用于指示当前运行环境;
将Dockerfile中之后的命令执行目录改为新建的项目目录;
先将项目依赖环境复制到项目目录中;
安装项目依赖环境,这一步占市较久,所以在复制项目代码前单独执行;
复制项目代码到镜像中;
使用daphne作为服务器启动服务。
构建镜像:

docker build -t backend:p0.0.1 .

2. 打包开发环境中的前端项目镜像

前端主要是静态文件和脚本,镜像相对简单。
在制作镜像前,需要向配置生产环境中的nginx,主要是docker-compose服务间的通信:
nginx.conf:

upstream apollo_spa {
        server project_django_web_1:8000;
}
server {
        listen 80;
        server_name _;
        client_max_body_size 1000m;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        charset utf-8;

        location /themis-server/{
                proxy_pass  http://apollo_spa/themis-server/;
                proxy_redirect     off;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
        location /fomssapi/{
                proxy_pass  http://apollo_spa/fomssapi/;
                proxy_redirect     off;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
        location /admin/{
                proxy_pass  http://apollo_spa/admin/;
                proxy_redirect     off;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

        location /ws/ {
            proxy_pass http://apollo_spa/ws/;
            proxy_redirect off;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
        }


        location /static/ {
            proxy_pass  http://apollo_spa/static/;
            proxy_redirect     off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

        location /media/ {
            proxy_pass  http://apollo_spa/media/;
            proxy_redirect     off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

    location / {
        root /usr/share/nginx/html;
        autoindex on;
    }
}

这里需要注意upstream中的server参数,它负责将请求转发给后端服务,这里后端在docker-compose中的名称是django_web,docker-compose.yml的上层路径是project/,所以要配成project_django_web_1,之后naginx会将受到请求中的’apollo_spa’替换为’project_django_web_1’。
附上官方解释:

For example, suppose your app is in a directory called myapp, and your docker-compose.yml looks like this:

version: "3"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

When you run docker-compose up, the following happens:

A network called myapp_default is created.
A container is created using web’s configuration. It joins the network myapp_default under the name web.
A container is created using db’s configuration. It joins the network myapp_default under the name db.

Dockerfile:

FROM nginx
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY dist/Root /usr/share/nginx/html

使用nginx作为基础镜像;
使用本地的nginx配置代替镜像中的默认配置;
将本地的代码复制到镜像中。
构建镜像:

docker build -t nginxfont:p0.0.1 .

3. 构建docker-compose项目

docker-compose.yml:

version: "3"

services:
    # MySQL
    db:
        image: mysql:5.7
        command: [
            '--default-authentication-plugin=mysql_native_password',
            '--character-set-server=utf8',
            '--collation-server=utf8_general_ci',
        ]
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: password
            MYSQL_DATABASE: fomss
        volumes:
            - "/home/project/mysql_data:/var/lib/mysql"

    redis_ser:
        image: redis:2.8
        command: redis-server --requirepass root
        restart: always

    django_web:
        image: backend:prod0.0.1
        restart: always
        links:
            - db
        depends_on:
            - db
            - redis_ser
        volumes:
            - "/home/project/media:/home/backend/media/"
            - "/home/project/logs:/home/backend/logs/"
            - "/home/project/static:/home/backend/static/"
        ports:
            - "30007:8000"

    nginx_server:
        image: nginxfont:prod0.0.1
        restart: always
        ports:
            - "8090:80"
        depends_on:
          - django_web

这里一共用了四组服务,并都设定了容器自动重启。
mysql,设置了字符集,密码和数据库,并将数据挂载在主机的/home/project/mysql_data路径下;
redis,使用命令行设置了密码;
后端服务,在docker-compose中命名为django_web可用于服务间通信,挂载了三个路径用于存放容器内产生的数据;
前段以及nginx代理:向外暴露8090端口,提供服务。

4. 镜像导出

本地镜像打包后,可以使用docker save命令将镜像导出:

docker save -o ~/Desktop/backend.tar backend:prod0.0.1
docker save -o ~/Desktop/nginxfont.tar nginxfont:prod0.0.1
docker save -o ~/Desktop/mysql.tar mysql:5.7
docker save -o ~/Desktop/redis.tar redis:2.8

这样就把整个项目需要的镜像全部导出到桌面了。

5. 生产环境部署

将上一步导出的景象以及docker-compose.yml复制到生产环境中

5.1. 导入镜像

使用docker load倒入镜像

docker load --input backend:prod0.0.1

其他镜像依次导入

5.2. 启动docker-compose

将docker-compose.yml复制到/home/project路径下,这里docker-compose.yml的上层路径,及project/必须和neginx中配置的一致。
启动服务:

docker-compose up

6. docker-compose自启

验证服务启动,没有问题后。设置docker-compose 开机自启:
首先使用systemd管理docker自启,这一步很关键,否则容器不能启动

systemctl enable docker

设置docker-compose自启:

6.1. 建立软连接

cd /usr/local/bin && ln -s /usr/bin/docker-compose docker-compose

6.2. 编辑自启脚本

cd /etc/init.d/ && vim start-docker-compose.sh

start-docker-compose.sh:

#!/bin/bash
# chkconfig: 2345 85 15
# description: docker-compose init start

/usr/local/bin/docker-compose -f /home/project/docker-compose.yml up -d

重启验证服务已经可用。deploy_nginx/