宿主机 | Python包 | ||||
---|---|---|---|---|---|
操作系统 | MySQL | Docker | django | docker-compose | docker |
ubuntu 18.0.4 | 5.7 | 19.03.8 | 3.0.8 | 1.26.2 | 4.3.1 |
卸载旧版本,没有安装过 Docker 可以略过此步骤。
$ sudo apt-get remove docker docker-engine docker.io containerd runc
建立仓库,依次执行即可。
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
会出现如是提示
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <[email protected]>
sub rsa4096 2017-02-22 [S]
添加下载链接到 apt 仓库中,其中网址部分为获取的源链接(xue微有些慢),我感觉可以改为镜像源链接(但并未尝试)。
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
开始安装,详细介绍请看官网教程,下方的参考链接。
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
参考链接0 - Install Docker Engine on Ubuntu
$ sudo groupadd docker # 一般都初始化,已经存在
$ USER=user_name
$ sudo gpasswd -a ${USER} docker
$ sudo service docker restart
$ newgrp - docker
参考链接1 - Ubuntu:添加docker权限给当前用户(可以使docker命令免sudo)
参考链接2 - Ubuntu下docker使用非root权限运行docker
# 一般/etc/docker默认存在,可不执行下面的命令
$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
https://xxxxxxxx.mirror.aliyuncs.com 是通过阿里云容器加速服务进行获取,每个服务器有不同的加速地址。
参考链接3 - docker怎么修改拉取源从指定的国内仓库拉取镜像
MySQL 服务放在宿主机上,不放入 Docker,Nginx 一个 Docker 容器,Django+Gunicorn 一个 Docker 容器,只用 Docker 开启两个容器服务。
服务 | 位置 |
---|---|
MySQL | 宿主机 |
Nginx | Docker容器 |
Web | Docker容器 |
Dockerfile 内容
注意:nginx 容器的端口(在 docker-compose.yml 文件中设置)暴露给宿主机的为80,暴露给其它容器的为8000,因为其要反向代理 Web 服务,以上端口的设置都可以不在 Dockerfile 中进行,只需要在 docker-compose.yml 配置即可。其中 nginx.conf 文件的配置内容如下:
注意: 在 nginx.conf 文件中设置 server 属性中的 proxy_pass 为带与 gunicorn 端口一致的端口号的地址即 proxy_pass http://qsud:8000;
。
Dockerfile 内容
还有一个是容器运行起来后需要运行的命令,也就是 docker-compose.yml 文件中 Web 容器配置的 command 字段,其中 djangoProject 是我的项目名,命令一次的含义为,制作数据库迁移,迁移数据库,收集静态文件,使用 gunicorn 启动项目。
# 激活虚拟环境,其实完全可以不用虚拟环境了,但之前在本地开发时用到了,就直接搬过来了
$ cd papi
$ source venv/bin/activate
# 切换到docker-compose.yml文件的目录下
(venv)$ cd hms1
# 按照docker-compose.yml进行创建镜像,需要在虚拟环境下
(venv)$ docker-compose build
# 以后台模式运行容器,需要在虚拟环境下
(venv)$ docker-compose up -d
# 使用docker-compose命令查看正在运行的容器,需要在虚拟环境下
(venv)$ docker-compose ps
# 使用docker-compose命令移除正在运行的容器,需要在虚拟环境下
(venv)$ docker-compose down
# 使用docker命令查看正在运行的容器可显示id,无论是否虚拟环境
$ docker ps -a
参考链接4 - Docker部署Web应用(Django)
参考链接5 - 使用docker-compose部署Django项目
参考链接6 - docker部署Django项目(前后端分离项目)
$ sudo docker logs container_id
# 或者查看docker-compose的全部容器输出,-f 跟踪日志输出
(venv)$ docker-compose logs
$ sudo docker exec -it container_id /bin/bash
1. 首先设置宿主机 MySQL 的绑定地址,直接找到 MySQL 的配置文件。
# 你的配置文件位置可能不为此,但默认一般是这里
$ cd /etc/mysql/mysql.conf.d
其中的 bind-address 字段默认值为 127.0.0.1,直接把这一行用 # 注释掉(已尝试可行),或者改成 0.0.0.0 (未尝试)。
参考链接7 - 在docker容器内访问宿主机的mysql服务
2. 其次查看网卡
# 主要是得到Docker的虚拟网卡
$ ifconfig
下面 setting.py 文件中的数据库配置部分的主机名设置成 172.17.0.1。
在腾讯云服务器中,发现使用 172.17.0.1 连接数据库时,日志却报出错误的访问地址为 172.28.0.2。
而且每次停止容器,然后再运行容器后发现,都会是 172.28.0.2 中 28 位置的数字改变,猜测原因可能是动态分配地址,而且如果考虑可能多个应用访问该段地址的话,那么最终需要在 MySql 中设置该网段的 IP 地址可以访问数据库。第一个 % 代表可能动态分配的数字,第二个 % 代表可能有多个应用连接。
# 新建规则
GRANT ALL PRIVILEGES ON db_qsud.* TO 'root'@'172.%.0.%' IDENTIFIED BY '123456';
# 最后要进行刷新权限
flush privileges;
注1: 以上仅适用于我的腾讯云服务器,可能对其它人的腾讯云服务器或其它品牌的云服务器不适用。
注2: 以上是不使用SSL模式访问的情况(通俗理解 http://,监听80端口,不需要证书)下,如果是SSL访问情况(通俗理解 https://,监听443端口,需要有证书)下 IP 地址还会不一样,需要在MySql 中新增允许网段,具体设置为何网段的 IP 地址看日志即可。
参考链接8 - Docker容器内连接宿主机的Mysql服务器
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
# 允许访问此项目的地址
ALLOWED_HOSTS = ['*'] # 其实只添加你的IP地址或域名即可
# Application definition
INSTALLED_APPS = [
...
'gunicorn',
]
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db_qc',
'HOST': '172.17.0.1',
'PORT': '3306',
'USER': 'root',
'PASSWORD': '123456',
'CHARSET': 'utf8',
}
}
# Static files (CSS, JavaScript, Images)
# # 对外提供WEB访问时的URL地址
STATIC_URL = '/s/'
# # 然后会将项目中的静态文件(包括STATICFILES_DIRS、自带admin的静态文件)收集到该目录下面来(所以不应该在该目录下面放置自己的一些静态文件,因为会覆盖掉)
STATIC_ROOT = os.path.join(BASE_DIR, "static")
# Upload source
# # 对外提供WEB访问时的URL地址
MEDIA_URL = '/m/'
# # 放置项目接收的上传文件
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
在 gunicorn 的配置文件中如果设置成 gevent 模式
# gunicorn.conf文件
bind='0.0.0.0:8000'
proc_name='qsud'
pidfile='/tmp/qsud.pid'
workers=4
worker_class='gevent'
max_requests=6666
timeout = 30
注意1: 使用此模式需要安装 gevent,安装 gevent 的前提需要更新 pip ,更新 pip 命令已在制作 Web 容器时配置过了,只需要在 requirements.txt 中添加 gevent 包信息,或者直接使用下面命令,制作第三方库依赖文件。
注意2:gunicorn 绑定端口(在 gunicorn.conf 文件中设置)跟 Web 容器暴露给其它容器的端口一致(在 docker-compose.yml 文件中设置)。
# 在虚拟环境中
(venv)$ pip freeze > requirements.txt
肯定是没有正确获取到设置的收集静态文件的目录(在 Django 的 setting.py 中设置 STATIC_ROOT )才会这样,之前网页没有样式的问题,原因就是因为我的 nginx.conf 文件中的 location 的静态文件配置中没有最后的 “ / ” ,导致以为是个 static 文件,而非 static 文件夹。
注意 location 中 alias 的使用,注意最后的 “ / ” 字符不能丢,代表在此目录下,是个文件夹。
具体的 location 和 alias 使用请参照官网的说明。
参考文献9 - Nginx官网中 alias 和 location 字段的使用说明