使用dockerfile 搭建django系统(nginx+redis+mongodb+celery)
背景
有需求需要对django系统进行docker化,以达到灵活部署和容灾。该系统基于django 2.2版本开发,数据库采用mongodb,服务器使用nginx,因系统有部分异步任务,异步任务则采用clelery+redis实现。
基于该需求,所采用的思路是:“基于ubuntu16.04”源镜像,根据dockerfile制作各个运行环境的镜像。因docker提倡单应用单镜像,故这里将django源代码程序作为一个镜像、mongodb作为一个镜像、nginx作为一个镜像、redis作为一个镜像。并最终使用docker-compose对这些镜像做编排。(假设当前已了解docker与docker-compose知识)
实现
下面就是一步步制作docker镜像了。关于各个镜像的Dockerfile模板,这里有一个非常好用的网站,可在网站中搜索自己感兴趣的项目,得到其Dockerfile。假设ubuntu16.04的源镜像及版本名为:ubuntu:16.04。
首先我们在宿主机(宿主机为ubuntu16.04系统,用户为user)中建立一个父文件夹例如名为vs,其中的目录如下:
mongodb_vs: 存放mongod的数据、配置文件与dockerfile文件;
vsapp: 存放django系统的源代码、相关配置文件与dockerfile文件;
redis_vs: 存放redis的配置文件与dockerfile文件;
nginx_vs: 存放nginx的配置文件与dockerfile文件。
1. mongodb镜像
首先是mongodb镜像的Dockerfile,内容如下:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install gcc -y
RUN apt-get install g++ -y
RUN apt-get install make -y
RUN apt-get install wget -y
# Install MongoDB.
RUN \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 && \
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' > /etc/apt/sources.list.d/mongodb.list && \
apt-get update && \
apt-get install -y mongodb-org && \
rm -rf /var/lib/apt/lists/*
# Define mountable directories.
VOLUME ["/data/db"]
# Define working directory.
WORKDIR /data
RUN mkdir bin && mkdir log
COPY mongodb.conf ./bin/
# Expose ports.
# - 27017: process
# - 28017: http
EXPOSE 27017
EXPOSE 28017
# Define default command.
# CMD ["mongod", "-f", "./bin/mongodb.conf"]
Dockerfile解释:首先更新ubuntu的源,然后下载mongodb的安装包并安装;在镜像中定义了“/data/db”的数据卷路径,并在/data/路径下创建了bin文件夹与log文件夹(db文件夹与log文件夹分别用来存储mongodb的数据库和mongodb运行的log。bin文件夹用来存放mongodb的配置文件);将宿主机下的mongodb配置文件“mongodb.conf”文件拷贝到镜像中的bin文件夹下;暴露mongodb运行的相应端口。
Dockerfile运行条件:要想运行该Dockerfile,需要有配置文件mongodb.conf的支持。在mongodb_vs文件夹下放入Dockerfile并创建一个文件mongodb.conf和一个data文件夹,data文件夹中有db和log两个空文件夹(db和log用来存储mongodb运行中的数据库和log)。整体目录如下:
--mongodb_vs
--Dockerfile
--mongodb.conf
--data
--db
--log
mongodb.conf内容如下:
# db path
dbpath = /data/db/
# log path
logpath = /data/log/logs.log
port = 27017
# fork = true
# auth = true
以上内容中,fork表示是否在后台运行mongodb,auth表示mongodb是否要进行认证,目前我们先将这两个禁用掉。
编译镜像:在mongodb_vs文件夹下运行如下命令:
docker build -t mongodb:v1.0 .
命令运行后若是没有报错,则会编译出一个名为:mongodb:v1.0的镜像。
运行容器:在mongodb文件夹下运行如下命令:
docker run -it --name mongodb_test -p 27017:27017 -p 27018:27018 -v /home/user/vs/mongodb_vs/data/db:/data/db -v /home/user/vs/mongodb_vs/data/log:/data/log mongodb:v1.0
我们基于mongodb_vs镜像在前台运行了一个名为mongodb_test的容器,并将其端口与宿主机端口绑定,将mongodb产生的数据、log与宿主机进行映射。
若无报错,则会进入到该容器中,在容器中运行命令:mongod -f ./bin/mongodb.conf --fork则会在后台启动开mongodb服务。我们可以在该容器中再输入mongo命令,若能正常进入到mongodb的shell中,则说明mongodb启动成功(也可用工具检验是否能连接到该mongodb实例)。
2. 源程序镜像
因该系统采用python的django框架完成。故需要系统有python环境。我们可以先基于ubuntu源镜像制作一个python3的镜像,再基于python3的镜像制作源程序镜像。
制作python3的镜像方法有很多,这里列出一种供参考:
python3.6.3的Dockerfile
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get -y install gcc make zlib1g zlib1g-dev openssl libpcre3 libpcre3-dev
RUN apt-get -y install libbz2-dev libsqlite3-dev libxml2-dev libffi-dev libssl-dev libxslt1-dev
RUN apt-get -y install wget
RUN apt-get -y upgrade
RUN apt-get -y dist-upgrade
RUN apt-get -y install bzip2
RUN apt-get -y install python3-pip python3-dev
RUN wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tar.xz
RUN tar -xvf Python-3.6.3.tar.xz
RUN cd Python-3.6.3 && ./configure && make -j 8 && make install
运行构建命令:docker build -t python:v3.6.3 .即可制作出python3.6.3的镜像。
下面就是制作源程序的镜像,制作之前还需要一些准备工作:
a.
将源程序代码放入到vsapp文件夹下,例如源代码项目名为:vscode(vscode子一级目录下有manage.py文件);为了使项目支持nginx,在vscode子一级目录下放入名为uwsgi_params文件,文件内容为:
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
b.
利用命令“pip freeze > requirements.txt”将源程序所需要的python依赖包都导出到requirements.txt文件中。并将该文件放入到vsapp文件夹下。我这里的requirements.txt内容如下,供参考:
beautifulsoup4==4.6.0
redis==2.10.6
celery==3.1.26.post2
celery-with-redis==3.0
Django==2.2.2
django-rest-framework-mongoengine==3.3.1
jira==2.0.0
ldap3==2.6
mongoengine==0.17.0
multi-key-dict==2.0.3
mysqlclient==1.3.13
pymongo==3.8.0
python-jenkins==1.4.0
requests==2.22.0
requests-oauthlib==1.2.0
requests-toolbelt==0.9.1
sqlparse==0.3.0
urllib3==1.25.3
xlrd==1.2.0
xlwt==1.3.0
generic==0.3.1
uWSGI==2.0.17.1
djangorestframework==3.9.4
c.
因项目中使用了celery,故还要将celery的配置文件放入到vsapp中。在vsapp中建立名为celeryconf的文件夹,下载官方的两个脚本并放入到celeryconf中;在vsapp中建立名为celeryd的文件,并将以下内容存储到该文件中:
# Names of nodes to start
# most will only start one node:
CELERYD_NODES="worker1"
# but you can also start multiple and configure settings
# for each in CELERYD_OPTS (see `celery multi --help` for examples).
#CELERYD_NODES="worker1 worker2 worker3"
# Absolute or relative path to the 'celery' command:
CELERY_BIN="/usr/local/bin/celery"
#CELERY_BIN="/virtualenvs/def/bin/celery"
# App instance to use
# comment out this line if you don't use an app
# 这里填写实际的项目中项目名
CELERY_APP="vscode"
# or fully qualified:
#CELERY_APP="proj.tasks:app"
# Where to chdir at start.
# 这里填写项目中应用名在容器中对应的绝对路径,因编译镜像时我这里命名为/web/vscode/
CELERYD_CHDIR="/web/vscode/"
# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=8"
# %N will be replaced with the first part of the nodename.
CELERYD_LOG_FILE="/var/log/celery/worker1.log"
CELERYD_PID_FILE="/var/run/celery/%N.pid"
# Workers should run as an unprivileged user.
# You need to create this user manually (or you can choose
# a user/group combination that already exists, e.g. nobody).
CELERYD_USER="root"
CELERYD_GROUP="root"
# If enabled pid and log directories will be created if missing,
# and owned by the userid/group configured.
CELERY_CREATE_DIRS=1
若是想查看celery运行的log,可以在vsapp下建立一个名为celerywork.log的文件。
关于celery的配置详情,可参考这篇博客
d.
因源程序中采用的是“nginx + uwsgi”搭建服务器端,故这里需要对uwsgi进行配置。在vsapp下建立名为vsapp_uwsgi.ini的文件。并在其中保存以下内容:
# mysite_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /web/vscode
# Django's wsgi file
module = vscode.wsgi
# the virtualenv (full path)
# home = /var/local/bin/python3
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
chmod-socket = 666
# 这里指定了与nginx对接的端口为8000
socket = :8000
# clear environment on exit
vacuum = true
uid = www-data
gid = www-data
pidfile = /web/webapp_uwsgi.pid
# daemonize = /web/uwsgi_log.log
e.
下面就是配置源程序运行的启动命令。因源程序运行既需要启动uwsgi还需要启动celery的异步任务与定时任务。故我们在vsapp下建立名为run_web.sh的文件,并放入如下内容:
#!/bin/bash
# 启动celery的异步任务与定时任务
/etc/init.d/celeryd start
/etc/init.d/celerybeat start
# 启动uwsgi
uwsgi --ini vsapp_uwsgi.ini
f.
准备工作做完后,就是编写源程序的Dockerfile了。在vsapp下建立名为Dockerfile的文件,其中内容如下:
FROM python:v3.6.3
RUN apt-get update \
&& apt-get install -y libmysqlclient-dev \
&& apt-get install -y --no-install-recommends \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
VOLUME ["/web/vscode"]
WORKDIR /web
COPY requirements.txt ./
RUN pip3 install -r requirements.txt
COPY vsapp_uwsgi.ini ./
COPY celeryconf/celeryd /etc/init.d/
COPY celeryconf/celerybeat /etc/init.d/
COPY celeryd /etc/default/
COPY run_web.sh ./
RUN chmod 777 run_web.sh \
&& chmod 777 /etc/init.d/celeryd \
&& chmod 777 /etc/init.d/celerybeat \
&& chmod 640 /etc/default/celeryd
EXPOSE 8000
# CMD ["./run_web.sh"]
最后,整个vsapp下的目录如下:
编译镜像:在vsapp文件夹下运行如下命令:
docker build -t vsapp:v1.0 .
运行容器:镜像编译成功后,运行如下命令:
docker run -it --name vsapp_test -p 8000:8000 -v /home/user/vs/vsapp/vscode/:/web/vscode/ -p /home/user/vs/vsapp/celerywork.log:/var/log/celery/worker1.log
若容器运行成功,在该容器中运行shell脚本命令“./run_web.sh”,即可启动源程序的服务,若期间没有报错,则源程序镜像制作成功。
3. nginx镜像
nginx镜像的制作只需要重新配置一下nginx的配置文件nginx.conf,以使其能够与源程序对接并加载源程序中的静态资源文件。
在nginx_vs文件夹下创建名为nginx.conf的文件,该文件内容如下:
#user www-data;
worker_processes 1;
#pid /run/nginx.pid;
events {
worker_connections 1024; ## Default: 1024
}
http {
# Definethe MIME types for files.
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream django {
# server unix:///usr/share/nginx/html/webapp.sock;
# 这里的端口要写成8000,因为在源程序镜像中的vsapp_uwsgi.ini中配置的是8000
server 127.0.0.1:8000; # for a web port socket (we'll use this first)
}
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 256k;
fastcgi_buffers 16 256k;
fastcgi_busy_buffers_size 512k;
fastcgi_temp_file_write_size 512k;
# configuration of the server
server {
# the port your site will be served on
listen 8090;
# the domain name it will serve for
server_name 127.0.0.1; # substitute your machine's IP address or FQDN
charset UTF-8;
access_log logs/myweb_access.log;
error_log logs/myweb_error.log;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /static/ {
expires 30d;
autoindex on;
add_header Cache-Control private;
alias /usr/share/nginx/html/webapp/static/; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_read_timeout 500;
uwsgi_pass django;
include /usr/share/nginx/html/webapp/uwsgi_params; # the uwsgi_params file you installed
}
}
}
daemon off;
该配置文件其实是对原nginx中的配置文件进行了更改。主要是声明了内部nginx与uwsgi通讯的端口,以及外部正常访问服务器的端口;源程序的静态资源文件夹路径;源程序的的uwsgi_params文件路径。
在nginx_vs文件夹下建立Dockerfile文件,内容如下:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install gcc -y
RUN apt-get install g++ -y
RUN apt-get install make -y
RUN apt-get install wget -y
RUN wget http://nginx.org/download/nginx-1.14.0.tar.gz && wget https://ftp.pcre.org/pub/pcre/pcre-8.37.tar.gz
#RUN cd /usr/local && mkdir src
RUN tar -xvf nginx-1.14.0.tar.gz -C /usr/local/src && tar -xvf pcre-8.37.tar.gz -C /usr/local/src
WORKDIR /usr/local/src/nginx-1.14.0/
RUN ./configure --prefix=/usr/local/nginx --without-http_gzip_module --with-pcre=/usr/local/src/pcre-8.37 && make && make install
ADD nginx.conf /usr/local/nginx/conf/
VOLUME ["/usr/share/nginx/html/webapp/"]
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80 8090 8000
ENTRYPOINT ["nginx"]
编译镜像:在nginx_vs文件夹下运行命令
docker build -t nginx:v1.0 .
运行容器: 运行命令:
docker run -it --name nginx_test -p 8090:8090 -v /home/user/vs/vsapp/vscode/:/usr/share/nginx/html/webapp nginx:v1.0
4. redis镜像
redis在该vscode系统中充当的角色是任务队列,故直接制作原始的redis镜像即可。不过为了使我们能在宿主机上查看redis镜像运行容器时产生的数据库数据与log,我们有必要重新配置redis配置文件redis.conf。
拿到原始的redis.conf修改以下几处:
# 指定log存放路径
logfile /data/logs/redis.log
# 指定数据库存放路径
dir /data/redisData/
# 若连接redis需要密码,则配置以下项
requirepass 1234*
在redis_vs下建立文件夹data,并将修改后的redis.conf放到data中,再在data目录中建立logs、redisData文件夹,logs文件夹中建立名为redis.log的文件。整个redis_vs的目录结构如下:
-- redis_vs
-- data
-- redisData
-- logs
-- redis.log
-- redis.conf
-- Dockerfile
redis的Dockerfile文件内容如下(我这里安装的redis版本为3.0.6):
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install gcc -y
RUN apt-get install g++ -y
RUN apt-get install make -y
RUN apt-get install wget -y
RUN \
cd /tmp && \
wget http://download.redis.io/releases/redis-3.0.6.tar.gz && \
tar xvzf redis-3.0.6.tar.gz && \
cd redis-3.0.6 && \
make && \
make install && \
cp -f src/redis-sentinel /usr/local/bin && \
mkdir -p /etc/redis && \
cp -f *.conf /etc/redis && \
rm -rf /tmp/redis-3.0.6* && \
sed -i 's/^\(bind .*\)$/# \1/' /etc/redis/redis.conf && \
sed -i 's/^\(daemonize .*\)$/# \1/' /etc/redis/redis.conf && \
sed -i 's/^\(dir .*\)$/# \1\ndir \/data/' /etc/redis/redis.conf && \
sed -i 's/^\(logfile .*\)$/# \1/' /etc/redis/redis.conf
# Define mountable directories.
VOLUME ["/data"]
COPY data/redis.conf .
# Define working directory.
WORKDIR /data
# Define default command.
# CMD ["redis-server", "redis.conf"]
# Expose ports.
EXPOSE 6379
编译镜像: 在redis_vs目录下运行命令:
docker build -t redis:v1.0 .
运行容器: 运行如下命令:
docker run -it --name redis_test -p 6379:6379 -v /home/user/vs/redis_vs/data/:/data/ redis:v1.0
当进入到容器中,在容器中运行命令“redis-server redis.conf”即可启动redis服务。
5. 编写docker-compose.yml
现在所有的镜像都已编译成功,下面就是将这些镜像所运行的容器联合起来以搭建成系统。这里我们采用docker-compose对这些镜像进行编排。
在vsapp下建立名为docker-compose.yml的文件,其内容如下:
version: '3'
services:
mongodb:
image: mongodb:v1.0
ports:
- "27017:27017"
- "27018:27018"
volumes:
- "$PWD/mongodb_vs/data/db/:/data/db"
- "$PWD/mongodb_vs/data/log/:/data/log/"
command: ["./start_mongo.sh"]
webapp:
image: vsapp:v1.0
network_mode: "host"
ports:
- "8000:8000"
volumes:
- "$PWD/vsapp/vscode/:/web/vscode/"
- "$PWD/vsapp/celerywork.log:/var/log/celery/worker1.log"
depends_on:
- mongodb
- nginx
- redis
command: ["./run_web.sh"]
nginx:
image: nginx:v1.0
network_mode: "host"
ports:
- "8090:8090"
volumes:
- "$PWD/vsapp/vscode/:/usr/share/nginx/html/webapp"
redis:
image: redis:v1.0
network_mode: "host"
ports:
- "6379:6379"
volumes:
- "$PWD/redis_vs/data/:/data/"
command: ["redis-server","redis.conf"]
此时,docker-compose已经编写完成,下面就是利用docker-compose运行这些容器了
运行命令:
docker-compose up
若运行后没有报错,说明整个系统已经搭建并启动成功。可以对该系统进行访问尝试。
总结
将系统进行docker化其实就是重新对原来的系统进行了一个在新机器上的配置,只不过配置的可以分应用一个个配置了。
使用dockerfile 搭建django系统(nginx+redis+mongodb+celery)的更多相关文章
- 使用Docker搭建Django,Nginx,R,Python部署环境
转载自https://blog.csdn.net/The_One_is_all/article/details/76063968 基本环境: Ubuntu 16.10 docker 17.06.0-c ...
- ubuntu系统nginx+Redis+PHP
一.安装ngnix apt-get update sudo apt-get install nginx /etc/init.d/nginx start 二.安装php sudo apt-get ins ...
- Docker部署Django项目+Nginx+Fluend日志收集 和redis、memcached、RabbitMQ、Celery
前言 一.docker 1.docker是什么? Docker的英文本意是“搬运工”,Docker搬运的是集装箱(Container)可以成为容器,我可以把写的Django的WEB应用以及Python ...
- CentOS 环境下基于 Nginx uwsgi 搭建 Django 站点
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,CentOS 环境下基于 Nginx uwsgi 搭建 Django 站点 以下 ...
- 在win7系统上搭建django+oracle 11g时,注意事项
在win7系统上搭建django+oracle 11g时,注意事项[示例用的是python 2.7]: 重要:python.oracle.oracle client这三个的OS bit 一定一定要相同 ...
- Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx)
Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx) 一丶集群和Nginx反向代理 ...
- django+uWSGI+nginx的工作原理流程与部署过程
django+uWSGI+nginx的工作原理流程与部署过程 一.前言 知识的分享,不应该只是展示出来,还应该解释这样做是为什么... 献给和我一样懵懂中不断汲取知识,进步的人们. 授人与鱼,不如授人 ...
- Nginx+Redis+Ehcache大型高并发高可用三层架构总结
在生产环境中,对于高并发架构,我们知道缓存 是最重要的环节,对于大量的高并发.可以采用三层缓存架构来实现,也就是Nginx+Redis+Ehcache 对于中间件Nginx常来做流量分发,同事ngin ...
- 接入层高性能缓存技术nginx+redis利器OpenResty
一. OpenRestyOpenResty是一个基于 Nginx与 Lua的高性能 Web平台,其内部集成了大量精良的 Lua库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极 ...
随机推荐
- DOS窗口启动tomact,运用startup.bat/shutdown.bat命令启动/关闭tomcat
设置CATALINA_HOME环境变量1.CATALINA_HOME是TOMCAT安装路径的别名,目的是为了方便使用TOMCAT2.计算机>属性>环境变量, 新建环境变量.变量名为CATA ...
- .pid文件
pid文件为进程文件,默认的在每个/var/run/目录下生成,当使用systemctl进行进程启动的时候,在这个目录下就会生成相应的pid文件,今天在进行poc测试的时候,对进程执行了enable操 ...
- 51nod 1060
反素数定义:对于任意正整数 $n$, 其约数个数记为 $f(n)$, 如果某个正整数 $n$ 满足 对于任意正整数 $i, (0 < i < n)$, 都有 $f(i) < f(n) ...
- [Luogu] 遥远的国度
https://www.luogu.org/problemnew/show/P3979 3种情况 x=root,很显然此时应当查询整棵树 lca(root,x)!=x ,此时直接查询x的子树即可,与换 ...
- 测试的Python、 Java语言之争
现在测试行业如果不会开发语言的话是很难找到工作的,即使是一些功能测试的岗位也会要求代码语言作为技术储备,因为如果做自动化测试或者测试工具脚本开发或者接口测试等都离不开开发语言,那作为测试如果没有代码经 ...
- League of Leesins
C - League of Leesins 首先找到每一串数字的头和尾两个数字,这两个数字有一个特点,就是它们在输入数据的时候都只会出现一次.我们在输出的时候用头和尾做第一数都可以. 然后第二个数只会 ...
- vue后台_实战篇
一.一些常用组件效果的实现 1)面包屑导航 主要是使用$route.mathed:一个数组,包含当前路由的所有嵌套路径片段的路由记录 .路由记录就是 routes 配置数组中的对象副本 (还有在 ch ...
- elasticsearch java client
1.集群名相同,且机器处于同一局域网同一网段,es会自动去发现其他的节点.2.集群不在同一局域网同一网段时,只需要在 elasticsearch.yml 中配置目标机器和端口即可discovery.z ...
- form表单无刷新提交
Ajax最大的特点就是可以不刷新页面而实现数据的通信及更改页面信息.那么用AJAX进行后台通信传递字符串还是可以的,遇到上传文件该怎么办呢?基于安全考虑,JS是不能直接进行文件操作的,只好用原始的fr ...
- Cesium入门-3-官方完整实例
实例核心代码 //资源访问令牌 Cesium token Cesium.Ion.defaultAccessToken='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ ...