• 后端开发之光!Django应用的容器化部署实践~


    在此之前,我一直用uwsgi+virtualenv+nginx方式进行应用部署,操作起来比较麻烦,而且依赖于服务器上的Python版本,服务的管理方面单纯uwsgi + pid算不上特别麻烦但总没有docker compose方便,无奈原本的服务器是32位系统的用不上docker,现在又增加了一个新服务器,所以赶紧把docker安排上~ 不得不说真的太简单太方便了,全程傻瓜式操作,也基本没像之前uwsgi部署那样遇到一些坑,真棒!

    安装

    最好是在开发机装上docker和compose,方便本机测试,安装方法直接参考官网,本文不再赘述。

    参考:https://docs.docker.com/

    编写Dockerfile

    首先是要给Django应用写一个Dockerfile来构建服务镜像。

    我的Dockerfile内容如下,每一行都有注释,供各位参考:

    FROM python:3.7
    
    # 设置 python 环境变量
    ENV PYTHONUNBUFFERED 1
    
    # 创建 code 文件夹并将其设置为工作目录
    RUN mkdir /code
    WORKDIR /code
    
    # 更新 pip
    RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U
    # 设置清华源
    RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
    
    # 将 requirements.txt 复制到容器的 code 目录
    ADD requirements.txt /code/
    
    # 安装库
    RUN pip install -r requirements.txt
    
    # 将当前目录复制到容器的 code 目录
    ADD . /code/
    

    写完之后可以直接运行docker run构建镜像,之后进入container的命令行执行python manage.py runserver 0.0.0.0 8000测试能否正常启动服务器(当然没有暴露端口前是没办法访问到的)

    使用compose编排服务

    Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。 
    Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。

    官方文档:https://docs.docker.com/compose/overview/

    注意compose版本需要和docker版本正确对应才能正常运行,docker更新很快,安装最好从官网最新版本进行~

    下面附上我的docker-compose.yml文件,后面会对配置项目进行介绍

    version: "3"
    services:
    
      mongo:
        image: mongo
        expose:
          - 27017
        restart: on-failure # 退出代码指示出现故障错误时重启
    
      postgres:
        image: postgres
        expose:
          - 5432
        restart: on-failure
        environment:
          - POSTGRES_PASSWORD=password
    
      web:
        restart: always # 除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。
        build: .
        environment:
          - ENVIRONMENT=docker
        command: python3 manage.py runserver 0.0.0.0:8000
        volumes:
          - .:/code
        ports:
          - "9000:8000"
        depends_on:
          - postgres
          - mongo
    

    可以看到我这个项目里面使用到了PostgreSQL和MongoDB,使用compose把他们整合在一起,并且暴露端口给web(也就是Django应用)使用。

    编写完docker-compose.yml文件之后,执行docker-compose up就可以自动构建各个镜像并且运行服务了,非常方便。

    如果需要后台运行则使用:docker-compose up -d

    重新构建镜像使用:docker-compose up --build

    删除使用:docker-compose down

    启动和停止:docker-compose startdocker-compose stop

    compose配置

    官网上有非常详细的配置文档,本文中我只介绍几个我常用的配置项。

    build

    build 可以指定包含构建上下文的路径,比如前面docker-compose.yml里的:

    web:
      build: .
    

    volumes配置

    注意web节点下有个volumes配置。

    从前面Dockerfile可以看到,Django应用的代码是在构建时静态复制到容器中的,即通过Dockerfile文件中的ADD . /code/命令实现物理主机中的源码复制到容器中,这样在后续物理主机src目录中代码的更改不会反应到容器中。 
    可以通过volumes 关键字实现物理主机目录挂载到容器中的功能(这时可以删除Dockerfile中的ADD . /code/命令了,不需要创建镜像时将代码打包进镜像,而是通过volums动态挂载,容器和物理host共享数据卷,这样还是实现程序的热更新)

    这两个差不多其实,不过前者官网文档说已经不建议使用了,所以用depends_on吧,作用就是把多个服务中的容器链接起来,比如本文例子中,我的Django应用需要用到postgresql数据库和MongoDB,所以我把他们链接起来,并且暴露端口(但要注意的是,在docker中,每一个镜像都是单独的一个主机,所以这三个服务相当于是三个不同的虚拟机,不能通过 localhost:port 访问),这样在Django服务里需要使用 postgres:5432 这样的形式使用。

    其中postgres是我们写在depends_on里面的服务名称,当然可以设置别名,比如 postgres:db,那么就是通过 db:5432去访问了~

    通过这个名称去访问服务器的原理相当于本地DNS吧,或者说是host文件~

    数据库迁移

    当Django应用在服务器上部署之后,还面临一个数据库迁移的问题,其实很好解决,要不就直接进docker环境执行命令,或者使用docker-compose run来执行,如下:

    docker-compose run web python3 manage.py makemigrations
    docker-compose run web python3 manage.py migrate
    

    其他需要执行的命令同理~

    command

    这个command是要在一个服务里面的镜像构建完启动之后执行的命令,一般来说只能执行一条,不过也能执行多条(不推荐)

    看了一眼Stack Overflow,大体两种方法:

    第一种:

    web:
      command: python a.py && python b.py
    

    第二种,利用管道:

    web:
      command:
        - /bin/sh
        - -c
        - |
          python a.py
          python b.py
    

    大概就说这么多啦,因为其实真的太简单了,更多操作参考官网文档吧~

    参考资料

  • 相关阅读:
    Cocos2dx-lua开发之c++绑定到lua
    SCOPE_IDENTITY和@@IDENTITY[转]
    c#List结合IEqualityComparer求交集
    K:java中正则表达式的使用说明及其举例
    K:常见的正则表达式
    K:正则表达式之基础简介
    Q:javax.comm 2.0 windows下Eclipse的配置
    Q:同时安装了python2和python3的电脑下pip的使用
    K:java 断言 assert 初步使用:断言开启、断言使用
    请描述一下 cookies,sessionStorage 和 localStorage 的区别
  • 原文地址:https://www.cnblogs.com/deali/p/13285829.html
Copyright © 2020-2023  润新知