一、知识储备
经过我们之前学习的Docker相关知识,现在我们来进行实战,以下介绍如何通过Docker Compose部署Django项目:
先前知识:
Docker学习笔记(一)概念理解-CSDN博客
Docker学习笔记(二)镜像、容器、仓库相关命令操作-CSDN博客
Docker学习笔记(三)Dockerfile-CSDN博客
Docker Compose | 菜鸟教程 (runoob.com)
二、项目目录结构说明
DjangoTest ## 项目根路径
│ docker-compose.yml # docker-compose文件
│ Dockerfile # 部署django项目的dockerfile
│ requirements.txt # 项目必须要安装的文件 pip freeze > requirements.txt
│
├─nginx ## nginx容器配置文件
│ │ nginx.conf # /etc/nginx/nginx.conf配置文件
│ │
│ └─conf # /etc/nginx/conf.d配置nginx文件夹
│ default.conf
│
└─djangoProject2 ## 部署django项目的web容器
│ manage.py
│ uwsgi.ini # django项目的uwsgi配置文件
│
├─app01
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ tasks.py # 配置celery任务文件
│ │ tests.py
│ │ urls.py
│ │ views.py
│ │ __init__.py
│ │
│ ├─migrations
│ │ __init__.py
│
│
└─djangoProject2
celery.py # celery配置文件
settings.py
urls.py
wsgi.py
__init__.py
三、项目文件说明
1.docker-compose.yml文件
version: '3'
services:
mysql:
image: mysql:8.0
volumes:
- ./mysql:/var/lib/mysql
expose:
- "3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=543720aini #mqsql服务器root密码
- MYSQL_DATABASE=test #数据库名
- MYSQL_USER=test #用户
- MYSQL_PASSWORD=543720aini #数据库密码
nginx:
image: nginx:alpine
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf:/etc/nginx/conf.d
ports:
- "80:80"
depends_on:
- web
redis:
image: redis:alpine
expose:
- "6379"
restart: always
web:
build: .
ports:
- "8000:8000" #主机端口和容器端口映射,要和下面的uwsgi.ini文件中的socket保持一致
command: ./start.sh
working_dir: /code/djangoProject2
volumes:
- .:/code
expose:
- "8000"
depends_on:
- mysql
- redis
celery:
build: .
command: celery -A djangoProject2 worker -l info
working_dir: /code/djangoProject2
volumes:
- .:/code
depends_on:
- mysql
- redis
celery-beat:
build: .
command: celery -A djangoProject2 beat -l info # 新增的服务,用于启动Celery Beat
working_dir: /code/djangoProject2
volumes:
- .:/code
depends_on:
- mysql
- redis
DjangoTest\djangoProject2\start.sh
#!/bin/bash
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000 #端口要和上面的web中的配置一样
uwsgi --ini uwsgi.ini
2.web向配置文件
Dockerfile
FROM python:3.7
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 && apt-get update && apt-get install -y uwsgi uwsgi-plugin-python3
DjangoTest\djangoProject2\uwsgi.ini
[uwsgi]
socket=:8000 #和docker-compose.yml文件中的web下暴露的端口一样
chdir=/code/djangoProject2
module=djangoProject2.wsgi:application
pidfile=/tmp/web-master.pid
master=True
vacuum=True
processes=1
max-requests=5000
post-buffering=8192
3.nginx容器相关配置文件
DjangoTest\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;
}
DjangoTest\nginx\conf\default.conf
server {
listen 8080;
server_name xxxx; #换成自己服务器的ip或域名(我用的是阿里云服务器,我这里配置的是阿里云的公网ip
charset utf-8;
client_max_body_size 10M;
location /static/ {
alias /django_static/;
}
location / {
include uwsgi_params;
proxy_pass http://web:8000; # 代理的端口
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
}
}
4.celery配置文件
DjangoTest\djangoProject2\djangoProject2\celery.py
import os
from celery import Celery
from django.conf import settings
# 只要是想在自己的脚本中访问Django的数据库等文件就必须配置Django的环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject2.settings')
# app名字
app = Celery('djnagoProject2')
app.conf.timezone = 'Asia/Shanghai'
app.conf.enable_utc = False
# 配置celery
class Config:
BROKER_URL = 'redis://redis:6379/1'
CELERY_RESULT_BACKEND = 'redis://redis:6379/2'
app.config_from_object(Config)
# 到各个APP里自动发现tasks.py文件
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
DjangoTest\djangoProject2\djangoProject2\__init__.py
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from djangoProject2.celery import app as celery_app
__all__ = ['celery_app']
DjangoTest\djangoProject2\app01\tasks.py
# Create your tasks here
import datetime
from celery.schedules import crontab
from celery.task import periodic_task
from django.db import transaction
from djangoProject2.celery import app
from .models import Worker
@periodic_task(run_every=crontab(minute="0",hour="0",day_of_week="1"))
def create_worker():
now_time = datetime.datetime.now()
with transaction.atomic():
Worker.objects.create(name=str(now_time.strftime("%H:%M:%S")), age=int(now_time.second))
@app.task
def update_worker():
now_time = datetime.datetime.now()
with transaction.atomic():
Worker.objects.update(age=int(now_time.second))
5.settings配置文件
修改配置文件相关信息
ALLOWED_HOSTS = ["*"]
#如果涉及跨域,则需要进行其他的配置,在这里不阐述
...
INSTALLED_APPS = [
...
'django_celery_results',
'django_celery_beat',
'app01'
]
#Celery相关配置
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' # 使用数据库调度器
#下面的配置和docker-compose.yml中的mysql下的environment配置一致
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "test",
"USER": "root",
"PASSWORD": "543720aini",
"HOST": "localhost",
"PORT": "3306",
}
}
6.初始化一个Django项目
DjangoTest\djangoProject2\djangoProject2\urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('app01/', include(('app01.urls', 'app01'), namespace='app01'))
]
DjangoTest\djangoProject2\app01\urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('index', views.index, name='index')
]
DjangoTest\djangoProject2\app01\views.py
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import resolve, reverse
from app01.tasks import update_worker
# Create your views here.
def index(request):
update_worker.delay()
return HttpResponse("Hello Docker")
DjangoTest\djangoProject2\app01\models.py
from django.db import models
# Create your models here.
class Worker(models.Model):
name = models.CharField("名字", max_length=64, default="")
age = models.IntegerField("年龄")
class Meta:
verbose_name = "劳动者"
四、使用 Compose 命令构建和运行您的应用
在DjangoTest目录下运行docker-compose up命令,看到如下图所示,则说明部署成功:
五、访问刚刚部署的应用
路由是你在DjangoTest\nginx\conf\default.conf中配置的service_name,端口是docker-compose.yml文件中web的port,如http://xxxx:8000/app01/index