原创

[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

centos8安装docker-compose

$ yum update
$ pip3 install docker-compose

分析整体配置项

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

| 服务名称 | 服务软件 | 用途 | 版本 | 网络 | | --------- | -------- | --------------- | ----------------------- | ------ | | djc8nginx | nginx | tcp/ip,代理转发 | nginx:1.18.0 | djc8net | | djc8php | php | 服务器编程支持 | php:8-fpm,djc8/php:8fpm | djc8net | | djc8mysql | mysql | 数据持久化 | mysql:8.0.22 | djc8net | | djc8redis | Redis | 高速缓存工具 | redis:6.0.9 | djc8net |

确认服务关系: | 服务名称 | 依赖服务 | | --------- | ------------------- | | djc8mysql | 无依赖 | | djc8redis | 无依赖 | | djc8php | djc8mysql,djc8redis | | djc8nginx | djc8php |

确认服务挂载映射目录: |服务名称|宿主机地址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| - |-|

确认服务环境变量:

| 服务名称 | 环境变量名 | 环境变量值 | | --------- | ------------------- | --------------- | | djc8mysql | MYSQL_ROOT_PASSWORD | djc8learndocker |

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 format|Docker Engine release| |---|---| |Compose specification | 19.03.0+| |3.8 |19.03.0+| |3.7 | 18.06.0+| |3.6 | 18.02.0+| |3.5 | 17.12.0+| |3.4 | 17.09.0+| |3.3 | 17.06.0+| |3.2 | 17.04.0+| |3.1 | 1.13.1+| |3.0 | 1.13.0+| |2.4 | 17.12.0+| |2.3 | 17.06.0+| |2.2 | 1.13.0+| |2.1 | 1.12.0+| |2.0 | 1.10.0+| |1.0 | 1.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编排容器-小码农,转载请保留本条链接,感谢!

温馨提示:
本文最后更新于 2021年09月05日,已超过 935 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我
正文到此结束
该篇文章的评论功能已被站长关闭
本文目录