使用 Docker 部署 Nginx + Uwsgi

最近,自己寫(xiě)了一些Django 的小應(yīng)用,因一直在本機(jī)做測(cè)試及使用,未將其部署至服務(wù)器。然而當(dāng)部署至公司服務(wù)器的時(shí)候,各種環(huán)境問(wèn)題頻出,如Python3沒(méi)有安裝加密模塊及Sqlite版本太低等,因?yàn)槭枪痉?wù)器無(wú)法找到比較干凈的環(huán)境,故考慮使用Docker來(lái)部署。

查閱網(wǎng)上資料,各個(gè)概念就不在這一一做介紹,開(kāi)始實(shí)戰(zhàn):
準(zhǔn)備:請(qǐng)?jiān)贒jango的setting文件中將DEBUG設(shè)置為False(部署在正式環(huán)境,該項(xiàng)肯定要設(shè)為False。同事,如果在調(diào)試環(huán)境中設(shè)置為false,則會(huì)出現(xiàn)找不到static路徑下資源的情況,如:加載不了css和js文件("Failed to load resource: the server responded with a status of 404 (Not Found)")。另外,設(shè)置 ALLOWED_HOSTS = ['*']

  1. 制作Docker Images
    Dockerfile 如下:
FROM python:latest                # 使用最新的python 鏡像制作
LABEL author="Jerry"
RUN mkdir /code                     # 創(chuàng)建一個(gè)工作目錄
ADD requirements.txt /code    # Django項(xiàng)目中需要使用的模塊,根據(jù)自己需要下載
WORKDIR /code
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt \
&& rm -f requirements.txt         # 使用清華鏡像源來(lái)下載所需的模塊
EXPOSE 8000                          # 暴露 8000 端口

requirment.txt 如下:

django
psycopg2
pymysql
uwsgi
docker
  1. 準(zhǔn)備好配置文件及 Django 程序
    uwsgi.ini 配置文件如下:
[uwsgi]
# Django程序所在目錄,放在Dockerfile中創(chuàng)建的code目錄中
chdir = /code/ziguan 
# 使用socket 方式與Nginx 連接
socket = /code/uwsgi.sock
# 使用root 用戶和組,注意:Nginx也需要設(shè)置啟動(dòng)用戶為root,否則會(huì)權(quán)限錯(cuò)誤
uid = root                                          
gid = root
# Django's wsgi文件,一般是"項(xiàng)目名.wsgi:application"
module = ziguan.wsgi:application
# 啟動(dòng)主進(jìn)程來(lái)管理其他進(jìn)程,其他進(jìn)程都是該進(jìn)程的子進(jìn)程
master = True
# 使用多少個(gè)進(jìn)程
processes = 2 
# 每個(gè)工作進(jìn)程的最大請(qǐng)求數(shù)。當(dāng)一個(gè)工作進(jìn)程達(dá)到該值,將被重啟
max-requests = 5000
# 指定pid所在路徑
pidfile  = /tmp/ziguan.pid
 # 當(dāng)服務(wù)器退出的時(shí)候自動(dòng)刪除socket和pid文件
vacuum = true
 # 允許用內(nèi)嵌的語(yǔ)言啟動(dòng)線程。允許app程序中產(chǎn)生一個(gè)子線程
enable-threads = true
 #  一個(gè)請(qǐng)求花費(fèi)的時(shí)間超過(guò)該值將被丟棄,并當(dāng)重啟處理這個(gè)請(qǐng)求的工作的進(jìn)程
harakiri = 30
# 后臺(tái)運(yùn)行,并且記錄日志的路徑;注意:如果需要在前臺(tái)運(yùn)行 uwsgi 請(qǐng)注釋該項(xiàng)
daemonize = /tmp/uwsgi.log
#  用戶uwsgi包解析的內(nèi)部緩存區(qū)大小為64k,默認(rèn)為4k;大于64k的包會(huì)被拒絕
buffer-size = 65536                           

PS: uwsgi 也可先使用命令啟動(dòng)來(lái)檢測(cè)程序是否正常: uwsgi --http :8000 --module ziguan.wsgi (使用http方式啟動(dòng),后面是ziguan.wsgi 而不是usgi, 請(qǐng)注意!?。?

Nginx配置文件

# 注意:如果這邊用戶使用普通用戶而uwsgi配置文件使用了root用戶,將造成nginx無(wú)法訪問(wèn)uwsgi的socket
user  root;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;

    server {
        listen       80;
        server_name  localhost;
            charset utf-8;

        location / {
            include uwsgi_params;
            uwsgi_connect_timeout 30;
                        # 指定uwsgi socket的位置
            uwsgi_pass unix:/usr/share/nginx/html/uwsgi.sock;
        }
                # 指定Django靜態(tài)資源所在路徑
        location /static {
            alias /usr/share/nginx/html/ziguan/static;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}
  1. 使用Docker-Compose 部署 Nginx + Uwsgi
    Docker-Compos 配置文件如下:
version: '3'
services:
  uwsgi:
    # 制作的鏡像名稱
    image: uwsgi:v1
    restart: always
    networks: 
      django:
        ipv4_address: 10.0.0.10
    volumes: 
     # 將項(xiàng)目掛載的容器中(uwsgi.ini配置文件一起放在了項(xiàng)目中)
      - /tmp/docker/django/ziguan:/code
    # 使用命令啟動(dòng)uwsgi
    command: uwsgi --ini uwsgi.ini
  web:
    image: nginx
    restart: always
    depends_on:
      - uwsgi
    ports: 
      # 將服務(wù)器端口與nginx端口做映射
      - "3333:80"
    networks: 
      django:
        ipv4_address: 10.0.0.11
    volumes: 
      # 掛載配置文件,并將項(xiàng)目也掛載到nginx相關(guān)目錄下
      - /tmp/docker/django/nginx.conf:/etc/nginx/nginx.conf
      - /tmp/docker/django/ziguan:/usr/share/nginx/html
# 創(chuàng)建一個(gè)網(wǎng)絡(luò),讓兩個(gè)docker互通
networks: 
  django:
    ipam:
      config:
        - subnet: 10.0.0.0/24

額外的補(bǔ)充:
當(dāng)我在K8s部署該環(huán)境是,發(fā)現(xiàn)兩個(gè)Nginx的Pod不能同時(shí)共享uwsgi創(chuàng)建的socket文件(部署環(huán)境為一個(gè)獨(dú)立的uwgi的Pod 和一個(gè)獨(dú)立的nginx的Pod),否則會(huì)出錯(cuò)(一個(gè)可以正常訪問(wèn),另一個(gè)訪問(wèn)404的問(wèn)題);可以將uwsgi 和 nginx部署至同一個(gè)Pod中,再使用Ingress + svc 進(jìn)行負(fù)載均衡。

參考:
https://blog.csdn.net/midion9/article/details/51354774
https://blog.csdn.net/Miss_Audrey/article/details/81874038

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容