docker-django-nginx-uwsgi-postgres-supervisor
进行docker封装之前
安装Django
新建一个 Django 项目目录 my_django ,创建一个新的 project ,并cd
到这个目录下:
pip install Django
mkdir my_django
cd my_django
django-admin.py startproject mysite
cd mysite
关于域和端口
在这篇文档中,将称使用的域为 localhost,也可以自行替换为所使用的 IP 。
通篇将使用 8000 端口来部署web服务,就如 Django 运行环境默认的一样。
关于项目目录
manage.py 文件所在位置为项目目录。
部署静态文件及配置数据库
在运行nginx之前,要把Django的静态文件集中到static文件夹中。修改 /my_django/mysite/mysite
文件夹下 settings.py 文件,修改 ALLOWED_HOSTS 的值为 [‘ip’ , ‘localhost’] (ip为你所使用的IP,可自行修改),不修改该值的话在启动django项目时会报错DisallowedHost at / Invalid HTTP_HOST ...
,在文件末尾加入:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
并修改 DATABASES 的值为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
返回到项目目录下,执行:
python manage.py collectstatic
使用docker进行封装
用 Dockerfile 封装项目,并使用 supervisor 进行管理
将 nginx,uwsgi,django 用 Dockerfile 进行封装,并使用 supervisor 管理 nginx 与 uwsgi 的运行情况,nginx,uwsgi,supervisor 的具体配置文件在下方,在项目目录下新建 Dockerfile 文件如下:
FROM ubuntu:14.04
ADD sources.list /etc/apt/sources.list
#RUN echo "nameserver=8.8.8.8" >> /etc/resolv.conf
#RUN rm -rf /var/lib/apt/lists/* \
# && mkdir /var/lib/apt/lists/partial
RUN apt-get update && apt-get install -y nginx python-pip python-dev supervisor vim \
&& apt-get clean all
RUN python -m pip install --upgrade pip
COPY pip.conf /root/.pip/pip.conf
RUN pip install uwsgi
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/requirements.txt
RUN pip install -r /usr/src/app/requirements.txt
ADD . /usr/src/app
# Symlink to this file from /etc/nginx/sites-enabled so nginx can see it
RUN ln -s /usr/src/app/mysite_nginx.conf /etc/nginx/sites-enabled/
RUN mkdir -p /var/log/supervisor /var/log/uwsgi
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
EXPOSE 8000
CMD ["/usr/bin/supervisord","-n"]
Nginx配置文件
这一配置文件告诉 nginx 从文件系统为文件提供服务,以及处理需要 Django 的请求。在项目目录下新建 mysite_nginx.conf 文件如下:
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream mysite {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
#server 127.0.0.1:8001; # for a web port socket (we'll use this first)
server unix:///tmp/mysite.sock;
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name localhost; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
# location /media {
# alias /path/to/your/mysite/media; # your Django project's media files - amend as required
# }
#location /static {
# alias /usr/src/app/static; # your Django project's static files - amend as required
#}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass mysite;
include /usr/src/app/uwsgi_params; # the uwsgi_params file you installed
}
}
uWSGI配置文件
配置uwsgi,将参数放在文件中,然后运行该.ini文件以运行uwsgi,在项目目录下新建 mysite_uwsgi.ini 文件如下:
# mysite_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /usr/src/app
# Django's wsgi file
module = mysite.wsgi
# the virtualenv (full path)
#home = /usr/src/app
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
# the socket (use the full path to be safe
socket = /tmp/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
# clear environment on exit
vacuum = true
Supervisor配置文件
Supervisor 可以很方便的监听、启动、停止、重启一个或多个进程。用 Supervisor 管理的进程,当一个进程意外被kill掉,supervisort 监听到进程状态后,会自动将它重新拉起,很方便的做到进程自动恢复的功能。在项目目录中新建 supervisord.conf 文件如下:
; supervisor config file
;[unix_http_server]
;file=/tmp/supervisor.sock ;(the path to the socket file)
;chmod=0700 ;socket file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ;(main log file;default $CWD/supervisor.log)
;logfile_maxbytes=50MB
;logfile_backups=10
;loglevel=info
;pidfile=/tmp/supervisord.pid ;(supervisord pidfile;default supervisord.pid)
;childlogdir=/var/log/supervisor ;('AUTO' child log dir,default $TEMP)
nodaemon=true
;minfds=1024
;minprocs=200
;umask=022
;user=nobody
;identifier=supervisor
;nocleanup=true
;strip_ansi=false
[program:nginx]
command=service nginx start
autostart=true
autorestart=true
stdout_logfile=/var/log/nginx/nginx_out.log
stderr_logfile=/var/log/nginx/nginx_err.log
[program:uwsgi]
command=/usr/local/bin/uwsgi --ini /usr/src/app/mysite_uwsgi.ini
autostart=true
autorestart=true
stdout_logfile=/var/log/uwsgi/uwsgi_out.log
stderr_logfile=/var/log/uwsgi/uwsgi_err.log
;[include]
;files = /etc/supervisor/*.conf
;files = /etc/supervisor/conf.d/*.ini
修改pip源
为修改 pip 源,在项目目录下新建 pip.conf 文件如下:
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host = mirrors.aliyun.com
新建requirments.txt文件
requirements.txt 文件用于记录所有依赖包及其精确的版本号,以便新环境部署。在项目目录下新建 requirements.txt 文件如下:
django==1.11.14
psycopg2
更换项目源为阿里源
ubuntu 默认使用的是国外的源,在更新的时候会很慢,使用国内的源速度很快,如阿里源。在项目目录下新建 sources.list 文件如下:
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
建立uwsgi_params文件
uwsgi_params 文件在 /etc/nginx/ 目录下,拷贝一份到项目目录中,内容如下:
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;
使用docker-compose编排容器
使用 docker-compose 编排两个容器,mysite_db_1 和 mysite_web_1(自动命名),其中db容器中运行的是 postgresql 数据库,web 容器通过 links 参数与它相连,将自带的 sqlite 数据库更换为 postgresql 数据库。web 容器是基于前面 Dockerfile 文件所创建镜像运行的容器,在项目目录下新建 docker-compose 的配置文件 docker-compose.yml 如下:
version: '2'
services:
db:
image: postgres
web:
build: .
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
depends_on:
- db
运行项目
通过 docker-compose 命令运行该项目
在项目目录中:
sudo docker-compose up -d
-d 参数表示后台运行。
查看项目运行情况
sudo docker ps
项目运行正常,执行完此命令后可以看到此项目的两个容器,容器状态为 Up,如需进入容器内部操作,可通过以下命令实现:
sudo docker exec -it <container name> bash
通过浏览器查看项目运行情况
在浏览器中输入 http://ip:8000 项目运行正常会出现 django 界面。
问题处理
通过Dockerfile构建镜像进行到RUN pip install -r /usr/src/app/requirements.txt
层时报错 :SSLError: The read operation timed out。
解决办法:
对该层代码进行优化,增加响应时间。
RUN pip --default-timeout=100 install -r /usr/src/app/requirements.txt
发生错误后,进入容器中查看错误日志,定位错误发生原因
Nginx 错误日志位置:/var/log/nginx/
uWSGI 错误日志位置:/var/log/uwsgi/
Supervisor 错误日志位置:/var/log/supervisor/