当前位置: 代码迷 >> 综合 >> docker-compose部署django+nginx+uwsgi+celery+redis+mysql
  详细解决方案

docker-compose部署django+nginx+uwsgi+celery+redis+mysql

热度:48   发布时间:2024-01-27 03:23:37.0

1.1 项目环境介绍

1、项目图解

在这里插入图片描述

2、项目目录结构说明

项目地址:https://gitee.com/edushiyanlou/django-docker

django-docker                ## 项目根路径
│  .gitignore                    # git忽略不上传的文件
│  docker-compose.yml            # docker-compose文件
│  Dockerfile                    # 部署django项目的dockerfile
│  README.md                     # 项目Readme说明
│  requirements.txt              # 项目必须要安装的文件
│
├─nginx                      ## nginx容器配置文件
│  │  nginx.conf                 # /etc/nginx/nginx.conf配置文件
│  │
│  └─conf                        # /etc/nginx/conf.d配置nginx文件夹
│          default.conf
│
└─web                        ## 部署django项目的web容器│  manage.py│  uwsgi.ini                 # django项目的uwsgi配置文件 │├─demoapp│  │  admin.py│  │  apps.py│  │  models.py│  │  tasks.py               # 配置celery任务文件│  │  tests.py│  │  urls.py│  │  views.py│  │  __init__.py│  ││  ├─migrations│  │      __init__.py        # 引入celery│  ││  └─templates│      └─demoapp│              celery_detail.html          # 查看具体celery执行结果页面│              celery_index.html           # 查看对应celery任务页面│              index.html                  # 项目主页面│└─webcelery.py           # celery配置文件settings.pyurls.pywsgi.py__init__.py

1.2 项目文件说明

1、初始化一个django项目

1)项目文件

  • urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('', include('demoapp.urls')),path('admin/', admin.site.urls),
]
  • demoapp/urls.py
from django.urls import path
from . import viewsapp_name = 'demoapp'urlpatterns = [path('', views.index, name='index'),path('celery/', views.celery_index, name='celery_index'),path('celery/random_add/', views.random_add, name='celery_random_add'),path('celery/random_mul/', views.random_mul, name='celery_random_mul'),path('celery/random_xsum/', views.random_xsum, name='celery_random_xsum'),
]
  • demoapp/view.py
import random
from django.shortcuts import render
from . import tasksdef index(request):context = {}return render(request, 'demoapp/index.html', context)def celery_index(request):context = {}return render(request, 'demoapp/celery_index.html', context)def random_add(request):a, b = random.choices(range(100), k=2)tasks.add.delay(a, b)context = {'function_detail': 'add({}, {})'.format(a, b)}return render(request, 'demoapp/celery_detail.html', context)def random_mul(request):a, b = random.choices(range(100), k=2)tasks.mul.delay(a, b)context = {'function_detail': 'mul({}, {})'.format(a, b)}return render(request, 'demoapp/celery_detail.html', context)def random_xsum(request):array = random.choices(range(100), k=random.randint(1, 10))tasks.xsum.delay(array)context = {'function_detail': 'xsum({})'.format(array)}return render(request, 'demoapp/celery_detail.html', context)

2)celery配置文件

  • web/__init__.py
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app__all__ = ['celery_app']
  • web/celery.py
import os
from celery import Celery# 只要是想在自己的脚本中访问Django的数据库等文件就必须配置Django的环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web.settings')# app名字
app = Celery('web')# 配置celery
class Config:BROKER_URL = 'redis://redis:6379'  # redis://127.0.0.1:6379CELERY_RESULT_BACKEND = 'redis://redis:6379'app.config_from_object(Config)
# 到各个APP里自动发现tasks.py文件
app.autodiscover_tasks()
  • demoapp/tasks.py
# Create your tasks here
from celery import shared_task@shared_task
def add(x, y):return x + y@shared_task
def mul(x, y):return x * y@shared_task
def xsum(numbers):return sum(numbers)
  • 2、nginx容器相关配置文件
  • django-docker/nginx/nginx.conf
user  nginx;
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;include /etc/nginx/conf.d/*.conf;
}
  • django-docker/nginx/conf/default.conf
server {listen                  80;server_name             localhost;charset                 utf-8;client_max_body_size    10M;location /static/ {alias   /django_static/;}location / {include     uwsgi_params;uwsgi_pass  web:8000;}
}
  • 3、web向配置文件
  • django-docker/Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED=1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# ADD . /code/
  • django-docker/web/uwsgi.ini
[uwsgi]
socket=:8000
chdir=/code/web
module=web.wsgi:application
pidfile=/tmp/web-master.pid
master=True
vacuum=True
processes=1
max-requests=5000
  • 4、docker-compose.yml文件
  • docker-compose.yml
version: '3'services:mysql:image: mysql:5.7volumes:- ./mysql:/var/lib/mysqlexpose:- "3306"restart: alwaysenvironment:- MYSQL_ROOT_PASSWORD=root- MYSQL_DATABASE=djangodocker- MYSQL_USER=django- MYSQL_PASSWORD=djangonginx:image: nginx:alpinevolumes:- ./nginx/nginx.conf:/etc/nginx/nginx.conf- ./nginx/conf:/etc/nginx/conf.d- ./web/staticfiles:/django_staticports:- "80:80"depends_on:- webredis:image: redis:alpineexpose:- "6379"restart: alwaysweb:build: .# command: python manage.py runserver 0:8000# ports:# - "8000:8000"command: uwsgi --ini uwsgi.iniworking_dir: /code/webvolumes:- .:/codeexpose:- "8000"depends_on:- mysql- rediscelery:build: .command: celery -A web worker -l infoworking_dir: /code/webvolumes:- .:/codedepends_on:- mysql- redis

1.3 docker-compose.yml详释

  • 1、docker-compose.yml详解
version: '3'                       # cocker compose版本号services:                          # 顶级配置文件mysql:                           # 服务名: 容器建通信、管理容器image: mysql:5.7               # 引入官方mysql镜像volumes:- ./mysql:/var/lib/mysql         # 把当前文件夹下的 ./mysql文件夹挂载到docker容器 /var/lib/mysql 路径下expose:- "3306"                        # 将当前容器的端口3306端口暴露给link到本容器的容器restart: always                   # 宿主机重启自动拉起这个docker容器environment:- MYSQL_ROOT_PASSWORD=root             # mysql服务器root密码root- MYSQL_DATABASE=djangodocker          # 创建数据库 djangodocker- MYSQL_USER=django                    # 创建一个用户 django- MYSQL_PASSWORD=django                # 用户密码为djangonginx:image: nginx:alpinevolumes:- ./nginx/nginx.conf:/etc/nginx/nginx.conf- ./nginx/conf:/etc/nginx/conf.d- ./web/staticfiles:/django_staticports:- "80:80"                             # 绑定容器的80端口到主机的80端口depends_on:- web                                 # 必须先启动web容器然才能启动nginx容器redis:image: redis:alpineexpose:- "6379"restart: alwaysweb:build: .# command: python manage.py runserver 0:8000# ports:# - "8000:8000"command: uwsgi --ini uwsgi.ini             # 启动uwsgi命令working_dir: /code/web                     # 项目工作路径volumes:- .:/code                                # 将当前文件夹下所有文件挂载到容器的 /code 文件夹expose:- "8000"depends_on:                                # 必须mysql和reids容器启动后才能启动web容器- mysql- rediscelery:build: .command: celery -A web worker -l infoworking_dir: /code/webvolumes:- .:/codedepends_on:- mysql- redis
  • 2、相似指令比较
'''1. expose 与 ports 比较'''
# ports: 绑定容器的端口到主机的端口,这样就可以在外网访问docker容器的服务
# expose: 将当前容器的端口3暴露给link到本容器的容器,expose不会将端口暴露给主机'''2. depends_on 与 links区别'''
# depends_on: 指定本容器启动依赖的容器必须先启动
# links: 保证容器如果ip变化也能访问(基本已经弃用,因为不使用link仍然可以通过容器名称访问)
  相关解决方案