前言
使用docker一般是为了部署方便,我这边的需求也是因为本地测试基本完成之后准备将一个Django项目上云。但是因为我这个项目使用了channels,要用到Redis,同时数据库是MySQL。如果是纯手动部署时真的很麻烦,因此找资料的时候发现了Docker-compose可以帮我完成部署这个工作。
Docker-compose能够将我的项目与MySQL、Redis三个容器一起拉起运行,从而省去了配置环境的麻烦。
具体操作
1.Django项目创建
创建Django项目的步骤可以参考网上,我参考的是菜鸟教程。接下来我们的操作要定位到根目录。
2.编写本项目的Dockerfile
首先先要定义本服务的镜像。
各文件的位置如图,都是项目根目录下:
Dockerfile文件
先定位到Django项目的根目录编写Dockerfile文件,
FROM python:3.6
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY pip.conf /root/.pip/pip.conf
COPY requirements.txt /usr/src/app/
RUN pip install -r /usr/src/app/requirements.txt
RUN rm -rf /usr/src/app
COPY . /usr/src/app
RUN chmod +x ./start.sh
该镜像是基于官方的python3.6镜像生成的,具体解释可以看我之前的文章《使用Docker本机部署Django项目》。
其中最后一句做了修改,该行命令赋予start.sh文件执行权限。
接下来说明几个需要另外编写的文件:
requirements.txt文件
这个是项目的依赖文件
django
xlrd
xlwt
channels
mysqlclient
channels_redis
pip.conf文件
这个是为了修改镜像的下载源
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
start.sh文件
这个是项目启动文件,以前都是手动生成数据库的,用了docker当然不能这个愚蠢。所以直接写一个启动文件,在运行项目之前将数据进行迁移。当然我这个是完全空的数据库,有迁移需要的可以将数据导出后导入。
#!/bin/bash
# 从第一行到最后一行分别表示:
# 1. 收集静态文件到根目录,
# 2. 生成数据库可执行文件,
# 3. 根据数据库可执行文件来修改数据库
# 4. 用 uwsgi启动 django 服务
python manage.py collectstatic --noinput&&
python manage.py makemigrations&&
python manage.py migrate&&
python manage.py runserver 0.0.0.0:8000
3.docker-compose相关操作
我们需要有三个容器web、mysql和redis。
docker-compose.yml文件如下所示:
version: "3"
volumes: # 自定义数据卷,位于宿主机/var/lib/docker/volumes内
myproject_db_vol: # 定义数据卷同步容器内mysql数据
services:
db:
image: mysql:5.7 # 使用最新的MySQL镜像
container_name: dev_mysql_latest # 指定一个容器名
restart: always # 自动重启(开机后也自动启动)
network_mode: bridge # 指定网络为桥接
ports:
- "3307:3307" # 将容器的3307端口映射到本地的3307
environment:
- MYSQL_ROOT_PASSWORD=root # MySQL的root密码「必填」
- MYSQL_DATABASE=DB_NAME# 数据库名称
- MYSQL_USER=USERNAME # 数据库用户名
- MYSQL_PASSWORD=PASSWORD # 用户密码
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脚本
redis:
image: redis:5
container_name: dev_redis_latest
network_mode: bridge
restart: always
ports:
- "6379:6379"
web:
build: .
network_mode: bridge # 指定网络为桥接
command: bash start.sh # 启动项
ports:
- "8000:8000"
depends_on: # 依赖关系
- db
- redis
links:
- db
- redis
restart: always
mysql
我使用的是mysql5.7的镜像,这边需要编写一个数据库的配置文件,在根目录创建一个compose文件夹,然后再创建一个mysql文件夹。这个compose文件夹还可以加redis的配置文件,具体可以看我参考的几篇文章,但我这边只需要配置mysql所以就没写了。
其中my.cnf是配置文件,init.sql是初始化脚本。
my.cnf
这边我修改了端口防止与本地的数据库产生冲突。
# compose/mysql/conf/my.cnf
[mysqld]
user=mysql
default-storage-engine=INNODB
character-set-server=utf8
port = 3307 # 端口与docker-compose里映射端口保持一致
#bind-address= localhost #一定要注释掉,mysql所在容器和django所在容器不同IP
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 = 3307
default-character-set=utf8
[mysql]
no-auto-rehash
default-character-set=utf8
init.sql
# compose/mysql/init/init.sql
GRANT ALL PRIVILEGES ON myproject.* TO dbuser@"%" IDENTIFIED BY "password";
FLUSH PRIVILEGES;
redis
redis好像完全不需要其他配置,开放默认的6379端口即可。
web
.
表示选用当前路径下的Dockerfile进行创建,其中command表示创建完成之后用bash启动服务,这一步非常重要。此外得说明一下该web容器的依赖。
4.settings.py修改
这一步是我之前失败的原因,就是没有改好配置文件,我们要修改数据库以及channels的配置。其中要HOST的名称改成和docker-compose的名称一致,这样docker会自动将地址找到。
具体如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'DB_NAME', # 数据库名称,
'HOST': 'db', # 主机地址
'USER': 'USERNAME', # 数据库用户
'PASSWORD': 'PASSWORD', # 密码
'PORT': 3307 # mysql的端口默认3306,现在修改3307
}
}
# 【channels】后端
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('redis', 6379)],
},
},
}
5.启动容器
全部完成之后定位到项目根目录开始构建,会生成三个镜像,如果你之前没有缓存的话需要下载一会
docker-compose build
然后启动三个容器
docker-compose up
一段时间过后直接访问8000端口即可~
参考链接
- https://blog.just666.com/2019/11/14/docker-mysql-redis/
- https://juejin.im/post/6844904095950569480
- https://zhuanlan.zhihu.com/p/145364353
- https://www.runoob.com/docker/docker-compose.html