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 ...
,在檔案末尾加入:
并修改 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 參數表示背景運作。
檢視項目運作情況
項目運作正常,執行完此指令後可以看到此項目的兩個容器,容器狀态為 Up,如需進入容器内部操作,可通過以下指令實作:
通過浏覽器檢視項目運作情況
在浏覽器中輸入 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/