使用docker部署django技术栈项目的方法步骤

随着Docker的普及成熟,已经逐渐成为部署项目的首选,今天来和大家分享下如何使用docker部署django技术栈项目。

我们这里说的Django技术栈为:python3.6、Django2.2、redis、mysql、celery、gunicorn和nginx。在实际的生产项目中,这些组件分布在集群的不同机器,如Nginx、redis和Mysql可能会有单独的团队或部门负责。涉及的部署架构和容器的编排会更为复杂,本文暂不去深究。本文主要介绍,如何使用 docker-compose 来编排这些组件,这种方式适用于测试环境的部署或者你的个人 sideproject 的部署。

本文默认你已经了解 docker 和 docker-compose 的一些基本知识,若你不了解,可阅读下面这些资料:

下面我们来说下如何部署。

项目组织结构

首先,看下我们的项目组织结构,结构如下:

├── LICENSE
├── README.md
├── compose
│  ├── celery
│  │  ├── Dockerfile
│  │  ├── celery-beat.sh
│  │  └── celery.sh
│  ├── mysql
│  │  └── my.cnf
│  ├── nginx
│  │  └── nginx.conf
│  └── web
│    ├── Dockerfile
│    ├── entrypoint.sh
│    ├── gunicorn.conf
│    └── gunicorn.sh
├── docker-compose.yml
├── docker_django_demo
│  ├── __init__.py
│  ├── celery.py
│  ├── settings.py
│  ├── urls.py
│  └── wsgi.py
├── env.tpl
├── manage.py
├── requirements.txt

除了Django的项目文件外,主要增加了 compose 配置文件目录和 docker-compose.yml 配置文件。

  • compose目录主要存放各组件的dockerfile文件和启动脚本。
  • docker-compose.yml 是docker-compose的编排配置文件。

编写Dockerfile 及启动初始化脚本

在docker-compose中,容器的启动有两种方法,一种是直接使用公共的镜像来启动容器,另一种是通过我们自己编写的Dockerfile。因为我们要安装额外的工具包和初始化相关配置,web和celery组件我们使用自定义的Dockerfile方式。

web容器的 compose/web/Dockerfile :

FROM python:3.6
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

COPY ./requirements.txt /code/
RUN pip install --no-cache-dir -r requirements.txt \
  && rm -rf requirements.txt

COPY . /code/
COPY ./compose/web/*.sh /code/
RUN sed -i 's/\r//' gunicorn.sh \
  && chmod +x gunicorn.sh \
  && sed -i 's/\r//' entrypoint.sh \
  && chmod +x entrypoint.sh

ENTRYPOINT ["/bin/bash", "entrypoint.sh"]

web容器的其他文件:

  • compose/web/entrypoint.sh web容器的启动脚本,执行一些初始化或检测逻辑。
  • compose/web/gunicorn.conf gunicorn配置文件。
  • compose/web/gunicorn.sh gunicorn的启动脚本。

celery的Dockerfile:

FROM python:3.6
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

COPY ./requirements.txt /code/
COPY ./compose/celery/*.sh /code/
RUN pip install --no-cache-dir -r requirements.txt \
  && rm -rf requirements.txt && sh init_env.sh

COPY . /code/
COPY ./compose/celery/*.sh /code/
RUN sed -i 's/\r//' celery.sh \
  && chmod +x celery.sh \
  && sed -i 's/\r//' celery-beat.sh \
  && chmod +x celery-beat.sh

celery的其他文件:

  • compose/celery/celery.sh celery的启动脚本。
  • compose/celery/celery-beat.sh celery-beat的启动脚本。

编写Compose启动配置文件

docker-compose 配置如下:

version: '2'

services:
 redis:
  image: redis
  ports:
   - "6379:6379"

 db:
  restart: always
  image: mysql:5.7.19
  # command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  volumes:
   - ./compose/mysql/:/etc/mysql/conf.d
   - ./db:/var/lib/mysql
  # for test
  ports:
   - "127.0.0.1:3307:3306"
   # (HOST:CONTAINER)
  env_file:
   - .env

 web:
  # restart: always
  build:
   context: .
   dockerfile: ./compose/web/Dockerfile
  command: sh gunicorn.sh # ["/bin/bash", "gunicorn.sh"]
  ports:
   - "8080:8002"
   # (HOST:CONTAINER)
  volumes:
   - ./logs:/var/logs/
   - ./collect_static:/code/collect_static
   - ./static:/code/static
   - ./templates:/code/templates
   - ./uploads:/code/uploads
  env_file: .env
  depends_on:
   - redis
   - db

 nginx:
  restart: always
  image: nginx:1.13.0
  volumes:
   - ./compose/nginx:/etc/nginx/conf.d/
   - ./staticfiles:/code/staticfiles
   - ./logs:/var/log/nginx
  ports:
   - "80:80"
   # (HOST:CONTAINER)
  depends_on:
   - web

 celery:
  build:
   context: .
   dockerfile: ./compose/celery/Dockerfile
  command: sh celery.sh
  volumes:
   - ./logs:/var/logs/
   - ./uploads:/code/uploads
  depends_on:
   - redis
   - db
  env_file: .env

 celery-beat:
  build:
   context: .
   dockerfile: ./compose/celery/Dockerfile
  command: sh celery-beat.sh
  volumes:
   - ./logs:/var/logs/
  depends_on:
   - redis
   - db
  env_file: .env

celery 的worker 和beat这里我们使用同一个镜像Dockerfile, 按照一个镜像一个进程的原则,启动两个容器来分别跑worker和beat进程。

编译测试

编写好配置文件之后,编译镜像测试运行:

docker-compose build
docker-compose up # 前台运行
docker-compose up -d # 无误后可后台运行

docker-compose ps 可以看到启动好的容器:

$ docker-compose ps
       Name              Command        State      Ports
--------------------------------------------------------------------------------------------------
dockerdjangodemo_celery-beat_1  sh celery-beat.sh        Up
dockerdjangodemo_celery_1    sh celery.sh           Up
dockerdjangodemo_db_1      docker-entrypoint.sh mysqld   Up   127.0.0.1:3307->3306/tcp
dockerdjangodemo_nginx_1     nginx -g daemon off;       Up   0.0.0.0:80->80/tcp
dockerdjangodemo_redis_1     docker-entrypoint.sh redis ...  Up   0.0.0.0:6379->6379/tcp
dockerdjangodemo_web_1      /bin/bash entrypoint.sh sh ...  Up   0.0.0.0:8080->8002/tcp

映射端口可根据自己的实际情况调整。

问题

下面说下在构建过程中的几个需要注意的问题。

mysql 编码问题

docker 提供的mysql镜像,默认编码为 latin1 , 在保存中文时会显示乱码。官方提供了一种修改编码方式的方法,在启动脚本后指定编码格式,文档可见这里。mysql容器5.7.19版本可直接在docker-compose.yml 中的command后跟上参数 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci 。这种方式,只是修改server端的编码。可直接使用配置文件覆盖的方式,指定所有的编码格式。

配置如下:

[mysqld]
default-storage-engine=INNODB
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'
init_connect='SET collation_connection = utf8mb4_general_ci'
skip-character-set-client-handshake # 跳过客户端的编码配置,客户端直接使用服务端的编码配置
bind-address = 0.0.0.0

注:mysql 5.7.19 配置文件方式成功,5.7.4、5.7.17 均失败,可做参考。

web等mysql启动完成后再继续

mysql 容器在启动起来之前是无法接受数据库链接的,在web启动初始化时,若数据库还没有启动好会导致web容器启动失败直接退出。我们可以增加在web容器启动时增加检测脚本,数据库连通之后,再继续。

脚本如下:

#!/usr/bin/env bash
set -o errexit
set -o pipefail

echo $MYSQL_PASSWORD
echo $MYSQL_DATABASE
echo $MYSQL_HOST
echo $MYSQL_USER
echo $MYSQL_PORT

function mysql_ready(){
python << END
import sys
import pymysql
try:
  conn = pymysql.connect(host="db", port=3306, user="root", passwd="$MYSQL_ROOT_PASSWORD", db='$MYSQL_DATABASE', charset='utf8')
except pymysql.err.OperationalError:
  sys.exit(-1)
sys.exit(0)
END
}

until mysql_ready; do
 >&2 echo "MySQL is unavailable - sleeping"
 sleep 1
done

>&2 echo "MySQL is up - continuing..."

总结

到此,使用docker来部署django技术栈服务就完成了,完整的项目代码,大家可参阅 docker-django-demo

文章开始说了,该部署方式不适合大型网站的线上生产服务,耦合度太高,不好维护等存在着许多问题。但是,部署自己的sideproject或者测试环境,在硬件资源有限的情况的下还是非常不错的。除了减少环境部署搭建的麻烦外,迁移起来也是很方便的。

demo项目中也有些开发环境下如何使用docker的案例,但是个人一直认为docker更适合部署,在开发环境方便不如直接搭建来的灵活方便。欢迎大家留言,共同讨论docker在开发和部署上的使用心得。

参考

cookiecutter-django

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Docker 部署Django项目的方法示例

    使用docker部署django项目也很简单,挺不错,分享下 环境 默认你已安装好docker环境 django项目大概结构 (p3s) [root@opsweb]# tree opsweb opsweb ├── apps ├── logs ├── manage.py ├── media ├── opsweb ├── README.md ├── requirements.txt └── static 编写Dockerfile 这里指定 Python 版本为docker官方提供的 "0.0.0.0

  • 详解Docker+Jenkins+Gitlab+Django应用部署实践

    一.背景介绍 在互联网应用快速更新迭代的大背景下,传统的人工手动或简单脚本已经不能适应此变化,此时Devops为我们提供了良好的解决方案,应用好CI/CD可以大大的方便我们的日常工作,自动化快速的持续集成/持续交付为我们带来了应用开放的更快速度.更好的稳定性和更强的可靠性. 二.拓扑环境 2.1 架构拓扑 如上图实例,简单花了下流程拓扑: 当研发push本地代码到gitlab-server后,webhook自动触发jenkins构建应用 在docker host上部署应用git clone来自g

  • 使用Docker搭建Django,Nginx,R,Python部署环境的方法

    本文介绍了使用Docker搭建Django,Nginx,R,Python部署环境的方法,分享给大家,具体如下: 基本环境: Ubuntu 16.10 docker 17.06.0-ce 压缩自己的项目文件 1.这里需要注意的是,在压缩的时候,也需要把自己的需要的Python包写在requirement.txt,这样搭建环境的时候才会知道你需要什么包,才能一起安装,我的项目的requirement.txt 内容如下. Django==1.10.5 rpy2==2.8.5 PyMySQL==0.7.

  • 使用Docker-compose离线部署Django应用的方法

    我们所在的内网环境需要部署一个类似CMS的应用,就是一些表格的CRUD,数据导出,人员权限管理等功能.想到Django做这方面的工作挺擅长的,而且开发量不大,于是选择Django作为开发基础.开发功能比较简单,差不多就是使用xadmin等插件实现以上功能.但有一个问题我们是不好绕过去的,那就是部署到一个内网环境,在内网pip等工具是不能使用的,但好在内网有一个yum服务器可以使用,所以我们决定在内网服务器上安装Docker,然后把开发环境的容器复制到生产环境实现部署.以下是主要的步骤: 安装开发

  • Docker部署Django应用的示例

    之前部署Web应用,没用docker,直接在服务器上部署,使用了fabric+nginx+supervisor+gunicorn部署,可查看我写过的一片博客:部署Web应用.但后来了解了docker,为其"Build,Ship and Run Any App,Anywhere"的思想所折服,觉得这个太牛逼了,所以我也尝试一下自己用docker部署Web应用.本篇文章为了记录我用docker部署web应用的过程和心得. 一.网络架构 我用Visio大概画了一下我的网络架构图: 我构建的容

  • 使用docker部署django技术栈项目的方法步骤

    随着Docker的普及成熟,已经逐渐成为部署项目的首选,今天来和大家分享下如何使用docker部署django技术栈项目. 我们这里说的Django技术栈为:python3.6.Django2.2.redis.mysql.celery.gunicorn和nginx.在实际的生产项目中,这些组件分布在集群的不同机器,如Nginx.redis和Mysql可能会有单独的团队或部门负责.涉及的部署架构和容器的编排会更为复杂,本文暂不去深究.本文主要介绍,如何使用 docker-compose 来编排这些

  • docker部署springboot和vue项目的实现步骤

    A. docker 部署 springboot项目 一.springboot项目编译打包 二.在项目根目录创建Dockerfile文件 FROM openjdk:8-jdk-alpine VOLUME /tmp ADD ./target/demo-0.0.1-SNAPSHOT.jar demo.jar RUN sh -c 'touch /demo.jar' ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.se

  • Django+Xadmin构建项目的方法步骤

    Django部分 创建项目 django-admin startproject mysite #创建一个mysite项目 运行简易服务器 python manage.py runserver #欢迎页面http://127.0.0.1:8000 设置系统语言和时间 //文件名:settings.py ********************* LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' 设置MySQL数据库 更改设置文件之前需先创建

  • centos8使用Docker部署Django项目的详细教程

    引言 在本文中将介绍在Docker中通过django + uwsgi + nginx部署方式部署Django项目, 由于记录的是学习过程,使用的都是目前较高的版本. python  版本为3.8.3 django  版本为3.0.6 nginx   版本为1.17.10 好了简单的介绍之后,就进入正题了. 创建一个工作目录 创建一个工作目录用来存放项目,和Dockerfile等文件. mkdir uwsgidocker 简单说明一下各个文件 docker-compose.yml: Docker

  • Docker部署Django+Mysql+Redis+Gunicorn+Nginx的实现

    一. 前言 docker技术现在非常火热,通过容器构建项目环境,运行效率和部署效率都很不错.所以最近抽空看了一些教程,然后将博客部署方式改为了docker,感觉网上没有特别好的关于 docker 部署 django 项目的教程,特意写了这篇文章,算是记录自己的心得. 本次教程的测试环境为 Deepin ,主要侧重于 容器的编排 和 Django 相关部署知识,一些细节方面,例如环境依赖安装,不会讲得特别详细.由于是在本地测试,所以在配置 nginx 相关信息时,将配置 http 代理而非 htt

  • Docker搭建部署Node项目的方法步骤

    目录 什么是Docker 客户端Docker Docker基本操作 镜像名称 拉取镜像 其他操作 Dockerfile Docker-compose 构建nginx-node-postgres项目 前段时间做了个node全栈项目,服务端技术栈是 nginx + koa + postgresql.其中在centos上搭建环境和部署都挺费周折,部署测试服务器,接着上线的时候又部署生产环境服务器.这中间就有很多既无聊又费精力,吃力不讨好的"体力活".所以就开始思考怎么自动化这部分搭建部署的工

  • 基于Docker镜像部署go项目的方法步骤

    依赖知识 Go交叉编译基础 Docker基础 Dockerfile自定义镜像基础 docker-compose编排文件编写基础 当然,一点也不会也可以按照这个步骤部署完成,不过可能中间如果出点小问题,会不知道怎么解决,当然你也可以留言. 我是在mac环境上开发测试的,如果你是在windows上可能有一点出入,但应该不会有啥大问题. 一.依赖环境 Docker 二.编写一个GoLang web程序 我这里就写一个最简单的hello world程序吧,监听端口是80端口. 新建一个main.go文件

  • 详解如何使用Docker部署Django+MySQL8开发环境

    前一段时间重装了系统,然后我还没有备份,导致电脑里的开发环境全都没有了. 一想到又要装 Python 环境,还要装数据库,然后安装过程中还可能报一堆错就头疼. 最近正在学习 Docker,这不正好解决了我当前的痛点了吗?而且,不止这次重装系统,以后再重装都不怕了,只要拿着 Dockerfile 和 docker-compose 文件,不管到什么环境,一条命令轻松跑起来. 之前部署 Python 开发环境,都是用的 virtualenv,或者是 Pipenv.这次使用 Docker 之后,对比下来

  • 使用docker部署dubbo项目的方法步骤

    1.首先用springboot构建一个简单的dubbo测试程序,并引入相关依赖 编写公共接口api 编写provider实现UserSvice的方法,并暴露服务 编写provider的配置文件 编写Consumer 通过调用provider的服务获取user信息并返回 consumer的配置文件 测试程序已完成 在本地启动,看看程序是否能正常调用服务 启动zookeeper 先启动provider端再启动consumer端 通过dubbo的控制台看到我们的服务已经注册成功 通过访问本地,看到我们

随机推荐