项目架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| mydocker/ ├── compose │ ├── mysql │ │ ├── conf │ │ ├── init │ │ └── mysql-files │ ├── nginx │ │ ├── Dockerfile │ │ ├── log │ │ ├── nginx.conf │ │ └── ssl │ ├── redis │ │ └── redis.conf │ └── uwsgi │ ├── myproject-master.pid │ └── myproject-uwsgi.log ├── docker-compose.yml └── myproject ├── apps ├── db.sqlite3 ├── db_tools ├── Dockerfile ├── extra_apps ├── manage.py ├── media ├── mycelery ├── myproject ├── __pycache__ ├── requirements.txt ├── start.sh ├── static ├── staticfiles ├── templates ├── tests └── uwsgi.ini
|
docker-compose
- 1.为了方便修改各项配置文件、和数据的持久化我们需要挂载一些数据卷并且可以指定完整路径挂载到你想指定的路径下,
如果不指定完整路径需要在volumes中声明,一般会储存在/var/lib/docker/volumes/并以项目名_卷名为名称,如果定义
了external:true需要提前创建好该文件
- 2.build会找寻指定目录下的Dockerfile并生成对应image,通过image创造容器
- 3.注意端口是否占用
- 4.注意各个镜像的版本,不同版本需要不同配置
- 5.由于使用nginx反向代理,需要把静态文件和nginx做绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| version: "3"
volumes: # 自定义数据卷,位于宿主机/var/lib/docker/volumes内 myproject_db_vol: # 定义数据卷同步容器内mysql数据 myproject_redis_vol: # 定义数据卷同步redis容器内数据 myproject_media_vol: # 定义数据卷同步media文件夹数据
services: redis: image: redis command: redis-server /etc/redis/redis.conf # 容器启动后启动redis服务器 volumes: - myproject_redis_vol:/data # 通过挂载给redis数据备份 - ./compose/redis/redis.conf:/etc/redis/redis.conf # 挂载redis配置文 件 ports: - "6379:6379" restart: always # always表容器运行发生错误时一直重启 stdin_open: true tty: true
db: image: mysql env_file: - ./myproject/.env volumes: - myproject_db_vol:/var/lib/mysql:rw # 挂载数据库数据, 可读可写 - ./compose/mysql/conf/my.cnf:/etc/mysql/my.cnf # 挂载配置文件 - ./compose/mysql/init:/docker-entrypoint-initdb.d/ # 挂载数据初始化 sql脚本 - ./compose/mysql/mysql-files:/var/lib/mysql-files/ ports: - "3306:3306" # 与配置文件保持一致 restart: always
web: build: ./myproject # 使用myproject目录下的Dockerfile expose: - "8000" volumes: - ./myproject:/var/www/html/myproject # 挂载项目代码 - myproject_media_vol:/var/www/html/myproject/media # 以数据卷挂载容 器内用户上传媒体文件 - ./compose/uwsgi:/tmp # 挂载uwsgi日志 links: - db - redis depends_on: # 依赖关系 - db - redis environment: - DEBUG=False restart: always tty: true stdin_open: true
nginx: build: ./compose/nginx ports: - "80:80" - "443:443" expose: - "80" volumes: - ./myproject/static:/usr/share/nginx/html/static # 挂载静态文件 - ./compose/nginx/ssl:/usr/share/nginx/ssl # 挂载ssl证书目录 - ./compose/nginx/log:/var/log/nginx # 挂载日志 - myproject_media_vol:/usr/share/nginx/html/media # 挂载用户上传媒体 文件 links: - web depends_on: - web restart: always
|
web容器和配置文件
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| # myproject/Dockerfile # 建立 python3.8 环境
FROM python:3.8 MAINTAINER chunjianghuayueye
# 设置 python 环境变量 ENV PYTHONUNBUFFERED 1
# 创建 myproject 文件夹 RUN mkdir -p /var/www/html/myproject
# 将 myproject 文件夹为工作目录 WORKDIR /var/www/html/myproject
# 将当前目录加入到工作目录中(. 表示当前目录) ADD . /var/www/html/myproject
# 更新pip版本 RUN /usr/local/bin/python -m pip install --upgrade pip
# 利用 pip 安装依赖 RUN pip install -r requirements.txt
# 去除windows系统编辑文件中多余的\r回车空格 RUN sed -i 's/\r//' ./start.sh
# 给start.sh可执行权限 RUN chmod +x ./start.sh ENTRYPOINT /bash/bin ./start.sh
|
start.sh
1 2 3 4 5 6 7 8 9 10
| #!/bin/bash # 从第一行到最后一行分别表示: # 1. 收集静态文件到根目录, # 2. 生成数据库可执行文件, # 3. 根据数据库可执行文件来修改数据库 # 4. 用 uwsgi启动 django 服务 python manage.py collectstatic --noinput&& python manage.py makemigrations&& python manage.py migrate&& uwsgi --ini /var/www/html/myproject/uwsgi.ini
|
uwsgi.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| [uwsgi]
project=myproject uid=www-data gid=www-data base=/var/www/html
chdir=%(base)/%(project) module=%(project).wsgi:application master=True processes=2
socket=0.0.0.0:8000 chown-socket=%(uid):www-data chmod-socket=664
vacuum=True max-requests=5000
pidfile=/tmp/%(project)-master.pid daemonize=/tmp/%(project)-uwsgi.log
#设置一个请求的超时时间(秒),如果一个请求超过了这个时间,则请求被丢弃 harakiri = 60 post buffering = 8192 buffer-size= 65535 #当一个请求被harakiri杀掉会,会输出一条日志 harakiri-verbose = true
#开启内存使用情况报告 memory-report = true
#设置平滑的重启(直到处理完接收到的请求)的长等待时间(秒) reload-mercy = 10
#设置工作进程使用虚拟内存超过N MB就回收重启 reload-on-as= 1024 python-autoreload=1
|
nginx容器和配置文件
修改配置文件nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| # nginx配置文件 # compose/nginx/nginx.conf
upstream django { ip_hash; server web:8000; # Docker-compose web服务端口 }
server { listen 80; # 监听80端口 server_name localhost; # 可以是nginx容器所在ip地址或127.0.0.1,不能写宿主机外网ip地址
charset utf-8; client_max_body_size 10M; # 限制用户上传文件大小
location /static { alias /usr/share/nginx/html/static; # 静态资源路径 }
location /media { alias /usr/share/nginx/html/media; # 媒体资源,用户上传文件路径 } location / { include /etc/nginx/uwsgi_params; uwsgi_pass django; uwsgi_read_timeout 600; uwsgi_connect_timeout 600; uwsgi_send_timeout 600;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; # proxy_pass http://django; # 使用uwsgi通信,而不是http,所以不使用proxy_pass。 } }
access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn;
server_tokens off;
|
Dcokerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # nginx镜像compose/nginx/Dockerfile
FROM nginx:latest
# 删除原有配置文件,创建静态资源文件夹和ssl证书保存文件夹 RUN rm /etc/nginx/conf.d/default.conf \ && mkdir -p /usr/share/nginx/html/static \ && mkdir -p /usr/share/nginx/html/media \ && mkdir -p /usr/share/nginx/ssl
# 设置Media文件夹用户和用户组为Linux默认www-data, 并给予可读和可执行权限, # 否则用户上传的图片无法正确显示。 RUN chown -R www-data:www-data /usr/share/nginx/html/media \ && chmod -R 775 /usr/share/nginx/html/media
# 添加配置文件 ADD ./nginx.conf /etc/nginx/conf.d/
# 关闭守护模式 CMD ["nginx", "-g", "daemon off;"]
|
db数据库
my.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| compose/mysql/conf/my.cnf [mysqld] user=mysql default-storage-engine=INNODB character-set-server=utf8
port = 3306 # 端口与docker-compose里映射端口保持一致 # bind-address= localhost # 一定要注释掉,mysql所在容器和django所在容器不同IP default-authentication-plugin=mysql_native_password
basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock skip-name-resolve # 这个参数是禁止域名解析的,远程访问推荐开启skip_name_resolve。
[client] port = 3306 default-character-set=utf8
[mysql] no-auto-rehash default-character-set=utf8
|
init.sql
1 2
| GRANT ALL PRIVILEGES ON myproject.* TO dbuser@"%" IDENTIFIED BY "Password1"; FLUSH PRIVILEGES;
|
.env
1 2 3 4
| MYSQL_ROOT_PASSWORD=Password1 # 数据库密码 MYSQL_DATABASE=myproject # 数据库名称 MYSQL_USER=dbuser # 数据库用户名 MYSQL_PASSWORD=Password1 # 用户密码
|
settings配置
主要添加以下静态路径和修改一下mysql、redis配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'myproject', 'USER': 'root', 'PASSWORD': 'Zhanghaowei1', 'HOST': 'db', 'PORT': '3306', } }
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://redis:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }
STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_URL = 'static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, "staticfiles"), ] print(STATICFILES_DIRS) IMPORT_EXPORT_USE_TRANSACTIONS = True MEDIA_URL = "media/" MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
创建容器
1 2 3
| docker-compose build # 启动 docker-compose up
|