[docker]使用docker-compose编排容器

前言

完整上线一个php+nginx+mysql+redis架构的网站中,我全程用docker搭建了基于php+nginx+mysql+redis的站点。
我目前遇到了一些问题:

  1. 重启很繁琐
  2. 修改配置,需要先docker stop,然后docker rm,再docker run,麻烦!
  3. 迁移到新站点麻烦。需要重复docker run,如果忘记了某一个命令,还要再查,麻烦!
    为此,我打算,将容器使用docker-compose进行编排,达到一次命令,运行所有内容。

安装docker-compose

centos 下的安装
$ yum install docker-compose
安装好后,使用-v查看版本号:

$ docker-compose -v 
docker-compose version 1.18.0, build 8dd22a9

分析整体配置项

docker-compose最重要的就是这个配置文件了,一切的容器都在这份文件中配置。
完整上线一个php+nginx+mysql+redis架构的网站为例,我们将docker容器进行编排。
首先确认所有的服务名称:

服务名称服务软件用途版本网络
djc8nginxnginxtcp/ip,代理转发nginx:1.18.0djc8net
djc8phpphp服务器编程支持php:8-fpm,djc8/php:8fpmdjc8net
djc8mysqlmysql数据持久化mysql:8.0.22djc8net
djc8redisRedis高速缓存工具redis:6.0.9djc8net

确认服务关系:

服务名称依赖服务
djc8mysql无依赖
djc8redis无依赖
djc8phpdjc8mysql,djc8redis
djc8nginxdjc8php

确认服务挂载映射目录:

服务名称宿主机地址1容器地址1宿主机地址2容器地址2
djc8mysql/www/mysql/date/var/lib/mysql--
djc8nginx/www/nginx/logs/var/log/nginx//www/nginx/conf/nginx.conf/etc/nginx/nginx.conf
djc8nginx/www/nginx/conf/vhost/etc/nginx/vhost/www/nginx/conf/cert//etc/nginx/cert/
djc8nginx/www/web/public_html/www--
djc8php/www/web/public_html/var/www/html/www/php/conf.d/usr/local/etc/php/conf.d
djc8php/www/php/php-fpmconf//usr/local/etc/php-fpm.d--

确认服务环境变量:

服务名称环境变量名环境变量值
djc8mysqlMYSQL_ROOT_PASSWORDdjc8learndocker

dockerfile编写

关于php的版本,因为还需要增加必要的插件,所以我自己弄了一个,dockerfile,内容如下:
可以参考php的dockerfile文件先把镜像生成出来,或者直接在docker-compose中一起编译
创建dockerfile存放的路径:

$ mkdir -p /www/php
$ cd /www/php

创建dockerfile文件:

$ touch /www/php/Dockerfile

dockerfile内容如下:

FROM  php:8-fpm
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
    echo deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib >/etc/apt/sources.list && \
    echo deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib >>/etc/apt/sources.list && \
    echo deb http://mirrors.aliyun.com/debian-security stretch/updates main >>/etc/apt/sources.list && \
    echo deb-src http://mirrors.aliyun.com/debian-security stretch/updates main >>/etc/apt/sources.list && \
    echo deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib >>/etc/apt/sources.list && \
    echo deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib >>/etc/apt/sources.list && \
    echo deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib >>/etc/apt/sources.list && \
    echo deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib >>/etc/apt/sources.list
RUN apt-get update
RUN pecl install redis-5.3.2 \
    && docker-php-ext-enable redis \
    && docker-php-ext-install mysqli pdo pdo_mysql

这里不多介绍Dockerfile文件的语法结构,只简单说下。
第一个RUN,执行结束后,会将apt-get的数据源修改为aliyun,加速国内访问,如果你是国外的机器,请取消这一条,否则会很慢。
第二个RUN则是安装必要的依赖,因为我这里使用redis做缓存,使用mysql做持久化,所以需要安装这两个扩展。

在/www/php/目录下,执行docker build -t djc8/php:8fpm .进行镜像构建,这里-t参数代表了这个镜像的名称,重要,后面会用到。

docker-compose.yml编写

首先是第一行,根据docker-compose版本对应的version快速对应关系,确认你的版本号
我摘抄了下来:

Compose file formatDocker Engine release
Compose specification19.03.0+
3.819.03.0+
3.718.06.0+
3.618.02.0+
3.517.12.0+
3.417.09.0+
3.317.06.0+
3.217.04.0+
3.11.13.1+
3.01.13.0+
2.417.12.0+
2.317.06.0+
2.21.13.0+
2.11.12.0+
2.01.10.0+
1.01.9.1.+

我这里按照第一步安装的时候查看的版本号是.1.18,详细的对应关系,也可以看这里compose-versioning。所以我这里选择了3.5

先新建一个文件

$ cd /www/php
$ touch docker-compose.yml

修改docker-compose.yml
这块内容是面向新手,所以,我会将每一步添加的内容,都贴出来,配置文件是属于递增方式,如果不想看,直接拉到最后一步。

  • 增加版本号
version: "3.5"
  • 增加网络:
version: "3.5"

networks:
  djc8net:
    driver: bridge
  • 增加服务:
version: "3.5"

services:
  djc8nginx:
  djc8mysql:
  djc8php:
  djc8redis:
networks:
  djc8net:
    driver: bridge
  • 增加服务中的使用镜像:

version: "3.5"

services:
  djc8nginx:
    image: nginx:1.18.0
  djc8mysql:
    image: mysql:8.0.22
  djc8php:
    image: djc8/php:8fpm
  djc8redis:
    image: redis:6.0.9
    
networks:
  djc8net:
    driver: bridge
  • 增加服务中的网络:
version: "3.5"

services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
  djc8php:
    image: djc8/php:8fpm
    networks:
      djc8net:
        aliases:
          - djc8php
  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis


networks:
  djc8net:
    driver: bridge
  • 增加服务与服务的依赖(依赖管理)
version: "3.5"
services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
  djc8php:
    image: djc8/php:8fpm
    networks:
      djc8net:
        aliases:
          - djc8php
    depends_on:
      - djc8mysql
      - djc8redis
  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis
networks:
  djc8net:
    driver: bridge
  • 增加对外端口(或者内部端口)
version: "3.5"
services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
    ports: 
      - 443:443
      - 80:80
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
  djc8php:
    image: djc8/php:8fpm
    networks:
      djc8net:
        aliases:
          - djc8php
    depends_on:
      - djc8mysql
      - djc8redis
    ports:
      - 9000:9000
    expose:
      - "9000"
  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis
networks:
  djc8net:
    driver: bridge
  • 增加服务与服务的链接
version: "3.5"
services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
    ports: 
      - 443:443
      - 80:80
    links:
      - djc8php
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
  djc8php:
    image: djc8/php:8fpm
    networks:
      djc8net:
        aliases:
          - djc8php
    depends_on:
      - djc8mysql
      - djc8redis
    ports:
      - 9000:9000
    expose:
      - "9000"
    links:
      - djc8mysql
  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis
networks:
  djc8net:
    driver: bridge
  • 增加服务的环境变量
version: "3.5"
services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
    ports: 
      - 443:443
      - 80:80
    links:
      - djc8php
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
    environment:
      MYSQL_ROOT_PASSWORD: djc8learndocker
  djc8php:
    image: djc8/php:8fpm
    networks:
      djc8net:
        aliases:
          - djc8php
    depends_on:
      - djc8mysql
      - djc8redis
    ports:
      - 9000:9000
    expose:
      - "9000"
    links:
      - djc8mysql
  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis
networks:
  djc8net:
    driver: bridge
  • 增加挂载路径
version: "3.5"
services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
    ports: 
      - 443:443
      - 80:80
    links:
      - djc8php
    volumes:
      - /www/nginx/logs:/var/log/nginx
      - /www/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - /www/nginx/conf/vhost:/etc/nginx/vhost
      - /www/nginx/conf/cert/:/etc/nginx/cert
      - /www/web/public_html:/www
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
    environment:
      MYSQL_ROOT_PASSWORD: djc8learndocker
    volumes:
      - /www/mysql/date:/var/lib/mysql
  djc8php:
    image: djc8/php:8fpm
    networks:
      djc8net:
        aliases:
          - djc8php
    depends_on:
      - djc8mysql
      - djc8redis
    ports:
      - 9000:9000
    expose:
      - "9000"
    links:
      - djc8mysql
    volumes:
      - /www/web/public_html:/var/www/html

  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis
networks:
  djc8net:
    driver: bridge

以上便是docker-compose的内容

那么因为我们php是自己编写的dockerfile作为镜像,所以需要将编译一起放到docker-compose中,这样以后修改dockerfile的时候,直接用docker-compose进行更新就可以了。

修改上面的docker-compose

version: "3.5"
services:
  djc8nginx:
    image: nginx:1.18.0
    networks:
      djc8net:
        aliases:
          - djc8nginx
    ports: 
      - 443:443
      - 80:80
    links:
      - djc8php
    volumes:
      - /www/nginx/logs:/var/log/nginx
      - /www/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - /www/nginx/conf/vhost:/etc/nginx/vhost
      - /www/nginx/conf/cert/:/etc/nginx/cert
      - /www/web/public_html:/www
  djc8mysql:
    image: mysql:8.0.22
    networks:
       djc8net:
        aliases:
          - djc8mysql
    environment:
      MYSQL_ROOT_PASSWORD: djc8learndocker
    volumes:
      - /www/mysql/date:/var/lib/mysql
  djc8php:
    build: .
    networks:
      djc8net:
        aliases:
          - djc8php
    depends_on:
      - djc8mysql
      - djc8redis
    ports:
      - 9000:9000
    expose:
      - "9000"
    links:
      - djc8mysql
    volumes:
      - /www/web/public_html:/var/www/html
  djc8redis:
    image: redis:6.0.9
    networks:
      djc8net:
        aliases:
          - djc8redis
networks:
  djc8net:
    driver: bridge

可以看到只修改了djc8php服务的,image镜像为build: .

部署并运行

在当前目录下输入命令:

$ docker-compose up -d 

该命令会自动编译dockerfile,自动下载镜像,创建容器,创建网络等。

进入目录/www/web/public_html/,,如果没有该目录,可创建一个:

$ mkdir /www/web/public_html
$ touch /www/web/public_html/index.php

修改index.php文件为如下内容

<?
    $mysqli = new mysqli("djc8mysql", "root", "djc8learndocker", "djc8db");
    $sql = "SELECT * FROM djc8learndocker";
    $result = $mysqli->query($sql);
    $row = $result->fetch_assoc();
 
    $redis = new Redis();  
    $redis->connect('djc8redis', 6379);
    //$redis->auth('mypassword');
    if(!$redis->exists("index.php")){
        $redis ->set( "index.php" , 'this page by '.$row["author"].' | '.$row["mail"].' use redis');   
    }
    echo $redis ->get( "index.php");
     $result->free();  
     $mysqli->close(); 

不出所料,页面会出现:
this page by djc8 | admin@djc8.cn use redis

如果出现错误,可以使用命令查看:
docker-compose logs 服务名

最后

可以在这里复制/www目录所有的内容,该目录包含了配置域名,服务器路径等内容。
我已经提交到github上。


本文作者:小蚊子
本文链接:[docker]使用docker-compose编排容器 - https://djc8.cn/archives/docker-using-docker-compose-to-arrange-containers.html
版权声明: 知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

标签: mysql, php, docker, nginx, redis, docker-compose

添加新评论