Centos7用docker-compose部署nginx、mysql、django

centos7用docker-compose部署nginx、mysql、django

1. 前期准备

想体验一下docker的便利,遂在本机用docker部署自己的django项目

准备:vmware虚拟机 + centos 7系统

1.1 docker安装

  1. 更新yum包
sudo yum update
  1. 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 设置yum源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  1. 可以查看所有仓库中所有docker版本,并选择特定版本安装
yum list docker-ce --showduplicates | sort -r
  1. 安装docker
sudo yum install docker-ce  #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版17.12.0
  1. 启动并加入开机启动
sudo systemctl start docker
sudo systemctl enable docker
  1. 验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
docker version

链接1

1.2 docker-compose 安装

  1. 方法一:(网络原因经常失败,或者速度很慢)
curl -L https://get.daocloud.io/docker/compose/releases/download/2.28.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 若上面的链接失效,则使用该链接
curl -L https://github.com/docker/compose/releases/download/v2.28.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 权限
sudo chmod +x /usr/local/bin/docker-compose

# 确认是否安装成功
docker-compose -v
  1. 方法二:

    1. 安装python-pip

      yum -y install epel-release

      yum -y install python-pip

    2. 安装docker-compose

      pip install docker-compose

      待安装完成后,执行查询版本的命令

      docker-compose version

1.3 路径及代码准备

mkdir /data/
mkdir /data/django_code

接着把已有的django项目内容整个拷贝到django_code路径下,结构如下

django_code
  - Dockerfile
  - requirements.txt
  - manage.py
  - myproject # 项目
  - myapp # 项目下的app
  - appfront # 前端代码

(Dockerfile以及requirements.txt后面会讲)

1.3.1 nginx配置文件

新建nginx的配置文件,放在/data/config/nginx/下。

后面会映射到 nginx 容器的 config/nginx/django_app.conf :

upstream app {
# "app" (domain_name)
  ip_hash;
  server app:8000; # "app" docker_server_name
}

server {
  listen 8000;
  server_name localhost;
  
  location /static/ {
    autoindex on;
    alias /code/appfront/dist/static/;
  }
  
  location / {
    proxy_pass http://app/;
    # "app" (domain_name)
  }
}

domain_name这个改动主要是为了照顾各种第三方登录的回调地址(不改这里, GitHub、Weibo 三方登录都会失败)。如果你没有类似的需求,不改也是可以的。比如个人网站是 www.betterhy.com,所以这里的 domain_name 就修改为 www.betterhy.com

1.3.2 requirements.txt
# 在项目根目录(这个文件通常在最外层)执行,可将所需库输入到文件中
pip freeze > requirements.txt
# 或者自己根据项目,手动添加进去

这里贴一下个人的依赖库

Django==2.1.2
django-cors-headers==2.4.0
django-extensions==2.2.1
django-redis==4.10.0
django-secure==1.0.1
django-sslserver==0.20
django-werkzeug-debugger-runserver==0.3.1
mysqlclient==1.3.13
Pillow==5.3.0
requests==2.21.0
wechatpy==1.8.5
cryptography==2.9.2
gunicorn==19.9.0

至此前期准备完成

2. Dockerfile

Docker 允许通过文本格式的配置文件来构建镜像,默认名称为 Dockerfile。因此在项目根目录新建文件Dockerfile,写入:

# 从仓库拉取 带有 python 3.7 的 Linux 环境
FROM python:3.7

# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1

# RUN  sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
# 或者
# 添加 Debian 清华镜像源
#	RUN echo \
#	deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free\
#	deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free\
#	deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free\
#	deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free\
#	    > /etc/apt/sources.list
# 上述二选一
# RUN  apt-get clean
# RUN  apt-get update
# 以下两项如果安装太慢,该步可暂缓
# RUN apt-get install -y mysql-client
# RUN apt-get install python3-dev default-libmysqlclient-dev -y

# 创建 code 文件夹并将其设置为工作目录
RUN mkdir /code
WORKDIR /code
# 更新 pip
RUN pip install pip -U -i https://pypi.tuna.tsinghua.edu.cn/simple
# 将 requirements.txt 复制到容器的 code 目录
ADD requirements.txt /code/
# 安装库
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 将当前目录复制到容器的 code 目录
ADD . /code/

# RUN server after docker is up
# CMD ./start.sh
# RUN python manage.py runserver 0.0.0.0:8000

3. Docker-compose

前期准备完成后,在根目录创建docker-compose.yml,并写入

version: "3"
services:
  app:
    restart: always
    build: .
    command: bash -c "python3 manage.py collectstatic --no-input && python3 manage.py migrate && gunicorn --timeout=30 --workers=4 --bind :8000 myproject.wsgi:application"
    volumes:
      - .:/code
      - static-volume:/code/appfront/dist/static
    expose:
      - "8000"
    depends_on:
      - db
    networks:
      - web_network
      - db_network
  db:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3306:3306"
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=rainrose
    networks:
      - db_network
  nginx:
    restart: always
    image: nginx:latest
    ports:
      - "8000:8000" 
      # 这里可以修改为80:8000,这样访问机器的时候就可以不用加端口号访问,因为浏览器默认访问80端口
    volumes:
      - static-volume:/code/appfront/dist/static
      - ./config/nginx:/etc/nginx/conf.d
    depends_on:
      - app
    networks:
      - web_network
      
networks:
  web_network:
    driver: bridge
  db_network:
    driver: bridge

volumes:
  static-volume:

先单解析一下app配置

这里定义了一个名叫 app 的容器。后面的内容都是 app 容器的相关配置:

  • restart :除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。
  • build :指定一个包含 Dockerfile 的路径,并通过此 Dockerfile 来构建容器镜像。注意那个 “.” ,代表当前目录。
  • command :容器运行时需要执行的命令。这里就是我们很熟悉的运行开发服务器了。
  • volumes卷,这是个很重要的概念。前面说过容器是和宿主机完全隔离的,但是有些时候又需要将其连通;比如我们开发的 Django 项目代码常常会更新,并且更新时还依赖如 Git 之类的程序,在容器里操作就显得不太方便。所以就有,它定义了宿主机和容器之间的映射:“.” 表示宿主机的当前目录,“:” 为分隔符,“/code” 表示容器中的目录。即宿主机当前目录和容器的 /code 目录是连通的,宿主机当前目录的 Django 代码更新时,容器中的 /code 目录中的代码也相应的更新了。这有点儿像是在容器上打了一个洞,某种程度上也是实用性隔离性的一种妥协。

严格意义上讲,这里用到的 .:/code 并不是,而是叫挂载,它两是有区别的,只不过 docker-compose 允许将挂载写到卷的配置中。后面章节会讲到。

配置大体解析:

  • 定义了 3 个容器,分别是 appdbnginx 。容器之间通过定义的端口进行通讯。
  • 定义了 2 个网络,分别是 web_networkdb_network 。只有处在相同网络的容器才能互相通讯。不同网络之间是隔离的,即便采用同样的端口,也无法通讯。
  • 定义了 1 个数据卷static-volume 。数据卷非常适合多个容器共享使用同一数据,你可以看到 appnginx 都用到了它。
  • exposeports 都可以暴露容器的端口,区别是 expose 仅暴露给其他容器,而 ports 会暴露给其他容器和宿主机。

3.1 网络 network

Docker 允许用户给每个容器定义其工作的网络,只有在相同的网络之中才能进行通讯。你可以看到 nginx 容器处于 web_network 网络,而 db 容器处于 db_network 网络,因此它两是无法通讯的,实际上确实也不需要通讯。而 app 容器同时处于 web_networkdb_network 网络,相当于是桥梁,连通了3个容器。

定义网络可以隔离容器的网络环境,也方便运维人员一眼看出网络的逻辑关系。

3.2 数据卷

前面我们见识过的用于映射宿主机和容器目录的卷了,实际上称为挂载;现在新出现的 static-volume 才叫。它的使用方式像这样:static-volume:/code/appfront/dist/static ,冒号后面还是容器内的目录,但冒号前的却不是宿主机目录、仅仅是卷的名称而已。从本质上讲,数据卷也是实现了宿主机和容器的目录映射,但是数据卷是由 Docker 进行管理的,你甚至都不需要知道数据卷保存在宿主机的具体位置。

相比挂载,数据卷的优点是由于是 Docker 统一管理的,不存在由于权限不够引发的挂载问题,也不需要在不同服务器指定不同的路径;缺点是它不太适合单配置文件的映射。

和挂载一样,数据卷的生命周期脱离了容器,删除容器之后卷还是存在的。下次构建镜像时,指定卷的名称就可以继续使用了。

数据卷有个很重要的特性:启动时如果卷是空的,则会将容器映射目录的所有内容复制到卷里去。换句话说就是,只要卷初始化完成后,容器原始的 collected_static 目录就不会再使用了,新增的文件也只存在于卷中,容器中是没有的。

实际上 static 静态文件(以及 media 媒体文件)的持久存储,通过挂载或者数据卷都可以实现;具体用哪种,这个就见仁见智了,你自己选择。

4. 构建并启动容器(这个过程可能出现各种问题)

docker-compose up

当出现问题时候就用docker logs id命令查看对应id容器的日志,解决问题

若拉取镜像出现速度慢的问题,这时候使用阿里云Docker加速 阿里云容器镜像服务地址
配置镜像加速器:
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

5. 其他(部署过程中我自己遇到过的一些坑0.0)

5.1 一些命令

docker ps #查看所有运行中的容器

docker ps -a# 查看所有的运行过的容器

docker exec -it id /bin/bash #进入指定id容器

docker stop id #停止容器运行 (id可输前几位,能确定到某一容器即可)

docker start id #运行容器

docker rm id #删除容器

docker images #查看镜像

docker rmi images #删除镜像

5.2 错误太多,导致构建太多次,然后空间不够用

docker image prune -a # 删除未使用到的镜像

docker image prune -a -f   #-f强制,不需要确认

包括上述的删除镜像指令,自行斟酌

5.3 docker-compose生成命令以及它们的区别

  1. 以下仅生成image,构建image,不启动容器(只生成image,不启动):

    docker-compose build

  2. 如果image不存在,则以下将构建image并启动容器(可能不生成image,然后启动):

    docker-compose up

    它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。链接的服务都将会被自动启动,除非已经处于运行状态。

    选项:

    • -d 在后台运行服务容器

    • –no-color 不使用颜色来区分不同的服务的控制台输出

    • –no-deps 不启动服务所链接的容器

    • –force-recreate 强制重新创建容器,不能与–no-recreate同时使用

    • –no-recreate 如果容器已经存在了,则不重新创建,不能与 –force-recreate 同时使用

    • –no-build不自动构建缺失的服务镜像

    • -t,–timeout TIMEOUT 停止容器时候的超时(默认为10秒)

    • –build 则即使不需要时,也会强制生成image(重新生成image,然后启动)

5.4 docker-compose在dockerfile更新后自动更新image

docker-compose stop
docker-compose up -d --build

5.5 解决docker启动错误 error creating overlay mount to /var/lib/docker/overlay2

原文

最近在centos7.1使用docker运行redis镜像,出现下面的错误:

/usr/bin/docker-current: Error response from daemon: error creating overlay mount to /var/lib/docker/overlay2/65f3c109fb903539820f84856d2725af784f2f03f95b1f0214e34184e4d61ff7-init/merged: invalid argument.
See '/usr/bin/docker-current run --help'.

在网上搜索一番后,一个可行的方案如下(改变storage driver类型, 禁用selinux):

停止docker服务

systemctl stop docker

清理镜像

rm -rf /var/lib/docker

修改存储类型

vi /etc/sysconfig/docker-storage

把空的DOCKER_STORAGE_OPTIONS参数改为overlay:

DOCKER_STORAGE_OPTIONS="--storage-driver overlay"

禁用selinux

vi /etc/sysconfig/docker

去掉option的–selinux-enabled

启动docker应该就可以了

systemctl start docker

5.6 路径文件权限问题

这时候需要禁用centos的SELinux

  1. 查看SELinux的状态:

    /usr/sbin/sestatus -v | grep SELinux

  2. 关闭:

    vi /etc/selinux/config

    SELINUX=enforcing改为SELINUX=disabled
    重启生效

配置说明的部分参照:Django-Docker容器化部署:Django-Docker本地部署

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值