docker 构建django项目发布镜像

说明

基础镜像采用centos7.5,docker 版本为19.03.8,宿主机版本为Ubuntu 18.04.1。第一次做django项目发布,尝试用docker镜像打包,并且顺利成功。项目中涉及的es、mysql、redis等组件未采用docker部署。
项目路径是~/mywu/所有dockerfile、nginx配置、uwsgi配置、启动脚本都放在此项目目录下方便打包。
先构建centos+python+nginx打包基础镜像包。后续项目镜像包以此镜像包作为基础镜像包。

基础镜像包

下载centos7.5镜像包 docker pull centos:centos7.5.1804

(xm) pyvip@VIP:~/mywu$ docker pull centos:centos7.5.1804
centos7.5.1804: Pulling from library/centos
Digest: sha256:7a45e4a1efbaafc1d9aa89925b6fdb33288a96d35ea0581412316e2f0ad3720a
Status: Downloaded newer image for centos:centos7.5.1804
docker.io/library/centos:centos7.5.1804

下载nginx包nginx-1.13.7.tar.gz。

(xm) pyvip@VIP:~/mywu/$ wget http://nginx.org/download/nginx-1.13.7.tar.gz
--2020-05-06 02:18:10--  http://nginx.org/download/nginx-1.13.7.tar.gz
正在解析主机 nginx.org (nginx.org)... 62.210.92.35, 95.211.80.227, 2001:1af8:4060:a004:21::e3
正在连接 nginx.org (nginx.org)|62.210.92.35|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 990836 (968K) [application/octet-stream]
正在保存至: “nginx-1.13.7.tar.gz”
nginx-1.13.7.tar.gz     100%[=================================================================================================================================================================>] 967.61K  29.3KB/s    用时 29s
2020-05-06 02:18:40 (33.8 KB/s) - 已保存 “nginx-1.13.7.tar.gz” [990836/990836])

在项目路径下编写dockerfile vim basedocker

vim basedocker
FROM centos:centos7.5.1804
#MAINTAINER 维护者信息
MAINTAINER wu
#ENV 设置环境变量
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
#RUN 执行以下命令
RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y  python36 python3-devel gcc pcre-devel zlib-devel make net-tools
COPY nginx-1.13.7.tar.gz  /opt
#安装nginx
RUN tar -zxf /opt/nginx-1.13.7.tar.gz -C /opt  && cd /opt/nginx-1.13.7 && ./configure --prefix=/usr/local/nginx && make && make install &
& ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

构建docker包 docker build . -t centos7.5-nginx:v1.0 -f basedocker

(xm) pyvip@VIP:~/mywu/deploy$ docker build . -t centos7.5-nginx:v1.0 -f basedocker 
Sending build context to Docker daemon  994.3kB
Step 1/8 : FROM centos:centos7.5.1804
 ---> cf49811e3cdb
Step 2/8 : MAINTAINER wu
 ---> Running in f49add210551
Removing intermediate container f49add210551
 ---> 552e325d722f
Step 3/8 : ENV LANG en_US.UTF-8
 ---> Running in ccddd013a72d
Removing intermediate container ccddd013a72d
 ---> 58dc7eb0f88d
Step 4/8 : ENV LC_ALL en_US.UTF-8
 ---> Running in 7ba7aa8be90c
Removing intermediate container 7ba7aa8be90c
 ---> add9d0067325
Step 5/8 : RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
 ---> Running in a5671c21df3a
Removing intermediate container a5671c21df3a
 ---> fa4b94c50599
Step 6/8 : RUN yum install -y  python36 python3-devel gcc pcre-devel zlib-devel make net-tools
 ---> Running in d07bad00130e
Loaded plugins: fastestmirror, ovl
Repository base is listed more than once in the configuration
......
Removing intermediate container e483f4cec428
 ---> dd6609c08cfa
Successfully built dd6609c08cfa
Successfully tagged centos7.5-nginx:v1.0

查看镜像

(xm) pyvip@VIP:~/mywu/deploy$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
centos7.5-nginx           v1.0                dd6609c08cfa        14 seconds ago      449MB
nginx                     latest              6678c7c2e56c        2 months ago        127MB
centos                    centos7.5.1804      cf49811e3cdb        13 months ago       200MB
delron/fastdfs            latest              8487e86fc6ee        2 years ago         464MB
delron/elasticsearch-ik   2.4.6-1.0           095b6487fb77        2 years ago         689MB

构建项目镜像

项目采用nginx+uwsgi部署
在xshell中生成pipenvll.txt文件(将项目中安装的包,存放到pipenvll.txt文件中)

(xm) pyvip@VIP:~/mywu/deploy$ pip freeze >pipenvll.txt
(xm) pyvip@VIP:~/mywu$ more pipenvll.txt 
asgiref==3.2.3
baidu-aip==2.2.18.0
bce-python-sdk==0.8.37
certifi==2019.11.28
chardet==3.0.4
Django==2.1.7
django-haystack==2.8.1
django-redis==4.11.0
elasticsearch==2.4.1
future==0.18.2
idna==2.8
Pillow==7.0.0
pycrypto==2.6.1
PyMySQL==0.9.3
pytz==2019.3
redis==3.4.1
requests==2.22.0
six==1.14.0
sqlparse==0.3.0
urllib3==1.25.8
uWSGI==2.0.18

编写项目dockerfile mysitedockerf

(xm) pyvip@VIP:~/mywu$ more mysitedockerf 
FROM centos7.5-nginx:v1.0
#MAINTAINER 维护者信息
LABEL maintainer="wu"
#工作目录
WORKDIR /opt/mysite
#拷贝文件至工作目录
COPY . .
RUN cp mysite-nginx.conf /usr/local/nginx/conf/mysite.conf
#安装依赖的插件
RUN pip3 install -i https://pypi.doubanio.com/simple -r pipenvll.txt
RUN chmod +x start.sh && rm -rf ~/.cache/pip
#EXPOSE 映射端口
EXPOSE 80
#容器启动时执行命令
CMD ["./start.sh"]

下面就是dockerfile中涉及的文档编写了
nginx配置文件编写mysite-nginx.conf

(xm) pyvip@VIP:~/mywu$ more mysite-nginx.conf 

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       80;
        server_name  127.0.0.1;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
 location /media  {
        alias /opt/mysite/xmb1/media;
        }
       # 静态文件
  location /static {
        alias /opt/mysite/static;
        }

location / {
    uwsgi_pass  127.0.0.1:8001;
    include    /usr/local/nginx/conf/uwsgi_params;
    }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
      root   html;
        }
    }
}

uwsgi配置文件

(xm) pyvip@VIP:~/mywu$ more uwsgi.ini 
[uwsgi]
# 使用nginx连接时使用,Django程序所在服务器地址
# 选择内网IP和端口
socket=127.0.0.1:8001
# 项目根目录
chdir=/opt/mysite
#项目中wsgi.py文件的相对目录
wsgi-file=xmb1/wsgi.py
# 进程数
processes=2
# 线程数
threads=2
# uwsgi服务器的角色
master=True
# 存放进程编号的文件
pidfile=uwsgi.pid
# 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。以前的runserver是依赖终端的
daemonize=logs/uwsgi.log

启动配置文件 start.sh

(xm) pyvip@VIP:~/mywu$ more start.sh 
#!/bin/bash
python3 manage.py collectstatic
uwsgi --ini ./uwsgi.ini 
nginx -c /usr/local/nginx/conf/mysite.conf -g 'daemon off;'

最后一步构建项目镜像。第一次构建容器有问题起不来,后来修改配置又构建了一遍。最终成功的镜像是mysite:v1.1版本。
docker build . -t mysite:v1.1 -f mysitedockerf

Sending build context to Docker daemon  126.5MB
Step 1/9 : FROM centos7.5-nginx:v1.0
 ---> dd6609c08cfa
Step 2/9 : LABEL maintainer="wu"
 ---> Running in 3b8a0a621cb1
Removing intermediate container 3b8a0a621cb1
 ---> e3adf22c56da
Step 3/9 : WORKDIR /opt/mysite
 ---> Running in 3126416f7129
Removing intermediate container 3126416f7129
 ---> c1b6a38c8703
Step 4/9 : COPY . .
 ---> f895dd2917e6
Step 5/9 : RUN cp mysite-nginx.conf /usr/local/nginx/conf/mysite.conf
 ---> Running in 5f67e5d9c314
Removing intermediate container 5f67e5d9c314
 ---> 9d25fe83d066
Step 6/9 : RUN pip3 install -i https://pypi.doubanio.com/simple -r pipenvll.txt
 ---> Running in 332c05091602
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting asgiref==3.2.3 (from -r pipenvll.txt (line 1))
  Downloading https://pypi.doubanio.com/packages/a5/cb/5a235b605a9753ebcb2730c75e610fb51c8cab3f01230080a8229fa36adb/asgiref-3.2.3-py2.py3-none-any.whl
      Running setup.py install for uWSGI: finished with status 'done'
.4.1 requests-2.22.0 six-1.14.0 sqlparse-0.3.0 uWSGI-2.0.18 urllib3-1.25.8
Removing intermediate container 332c05091602
 ---> c84f013fb85a
Step 7/9 : RUN chmod +x start.sh && rm -rf ~/.cache/pip
 ---> Running in 5d4bc7ff6e9a
Removing intermediate container 5d4bc7ff6e9a
 ---> c96b1f194911
Step 8/9 : EXPOSE 80
 ---> Running in 1af335420466
Removing intermediate container 1af335420466
 ---> 145247f80859
Step 9/9 : CMD ["./start.sh"]
 ---> Running in 95f633ef1cf1
Removing intermediate container 95f633ef1cf1
 ---> d68a50415dca
Successfully built d68a50415dca
Successfully tagged mysite:v1.0
(xm) pyvip@VIP:~/mywu$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
mysite                    v1.1                7c3c6f2af288        12 hours ago        627MB
mysite                    v1.0                d68a50415dca        12 hours ago        627MB
centos7.5-nginx           v1.0                dd6609c08cfa        13 hours ago        449MB
nginx                     latest              6678c7c2e56c        2 months ago        127MB
centos                    centos7.5.1804      cf49811e3cdb        13 months ago       200MB
delron/fastdfs            latest              8487e86fc6ee        2 years ago         464MB
delron/elasticsearch-ik   2.4.6-1.0           095b6487fb77        2 years ago         689MB

最后启动容器,验证服务正常。

(xm) pyvip@VIP:~/mywu$ docker run -dit --name mysite1 --net=host mysite:v1.1
a8a68ad874714bc96fa767a157e999d4bb4d604b09c163668dbb1244447374b4
(xm) pyvip@VIP:~/mywu$  
(xm) pyvip@VIP:~/mywu$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a8a68ad87471        mysite:v1.1         "./start.sh"        28 seconds ago      Up 27 seconds                           mysite1

由于我项目使用的数据库都是填的127.0.0.1。容器内部无法调用宿主机的127.0.0.1。因此我使用net=host主机网络模式启动容器。
为使得日后上K8S平台应该使用端口映射的模式部署,需要修改部分代码。
首先Django中setting配置文件中各配置连接使用环境变量设置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite',
        'USER': os.environ.get("MYSQL_USER", 'root'),
        'PASSWORD': os.environ.get("MYSQL_PASSWD", '123456'),
        'HOST': os.environ.get("MYSQL_HOST", '127.0.0.1'),
        'PORT': os.environ.get("MYSQL_PORT", '3306')
    }
}

然后启动容器时指定环境变量即可。

docker run -dti -p 80:80 --name mysite -e MYSQL_HOST=10.0.2.15 -e MYSQL_USER=root -e MYSQL_PASSWD=123456  mysite:v1.2
上一篇:PHP Use CURL with SNI


下一篇:Django框架创建运行最小程序过程记录