官方手册明确说明,容器互联不要采用 link 的方式,而应该采用 network 的方式。

 

以下演示的以 centOS 上为例,如果你在 mac 上,就需要注意一下路径问题,mac 下一班把文件什么的放在用户目录下。

直接上步骤:

1、centOS下需要升级 yum —— 不然可能会有一些神经病的错误发生

yum update

2、将已经写好的 yml 包以及 Dockerfile 等下载到根目录:

git clone https://github.com/lftm1111/docker-compose-php-network.git

3、进入 docker-composer-php 目录,即 docker-compose.yml 所在的目录

cd docker-compose-php-network

4、配置并修改.env 文件

cp .env.example .env
vim .env

—— .env 配置建议:

使用 docker-compose 安装 php 运行环境 —— network 的方式
// mac上
DIR_WWW=/Users/linfeng/docker/data/www/
DIR_REDIS_DATA=/Users/linfeng/docker/data/redis/
DIR_MYSQL_DATA=/Users/linfeng/docker/data/mysql/

// centOS 上
DIR_WWW=/data/www/
DIR_REDIS_DATA=/data/redis/
DIR_MYSQL_DATA=/data/mysql/
使用 docker-compose 安装 php 运行环境 —— network 的方式

5、运行 docker-compose:

docker-compose up -d

6、如果要启动的是里面的 docker-compose.build.yml 文件,则执行:

docker-compose -f docker-compose.build.yml up -d

—— 关于docker-compose.yml 文件和 docker-compose.build.yml 的区别,请看下面的特别说明

—— 好了,执行成功后,会有四个容器在运行。配置虚拟主机和项目,这个都不知道那就没办法了。

7、配置虚拟主机并重启 nginx 容器服务:

docker-compose restart nginx

 

 // 虚拟主机示例:

server {
    listen       80;

    set $root /data/www/laravel/public;
    server_name  laravel.xxx.com;
    
    root   $root;
    index index.php index.html index.htm;

    if (!-e $request_filename) {
         rewrite ^/(.*) /index.php?$1 last;
    }

    location ~ index\.php {
        root           $root;
        fastcgi_pass   phpfpm:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

 

// nginx的配置参数含义: 

1、fastcgi_pass :这个是配置的【地址:端口号】。

// 以前未采用容器的时候,就在本机:
127.0.0.1:9000

// 采用容器下的三种方式
172.17.0.2:9000    //容器 IP:端口,请参考手动安装的文章
phpfpm:9000    // 服务名:端口,请参考 link 安装
fpm:9000    // 服务别名:端口,请参考本篇文章

 

2、fastcgi_param :这个是配置的是 phpfpm 找到 php 文件的路径。

我们的配置是:$root$fastcgi_script_name;  ==>> 说明,phpfpm 能够在容器内的 $root 路径下找到 index.php 。而我们挂载的时候,刚好把 volume 两边设置成了一样的路径。

 

// 以 DIR_WWW 配置为/data/www 为例

—— 项目目录:/data/www

—— 虚拟主机配置目录:/docker-compose-php/conf/nginx/conf.d

 

 

// 特别说明:

我们下载下来的包里面有两个文件,其中只有一处差别,在 phpfpm 那里,分别如下:

docker-compose.yml 部分:

phpfpm:
    image: raven666/ct-phpfpm:lastest
    container_name: myphpfpm
    expose:
      - "9000"

docker-compose.build.yml 部分:

使用 docker-compose 安装 php 运行环境 —— network 的方式
phpfpm:
    image: raven666/ct-phpfpm:latest
    container_name: myphpfpm
    build:
      context: .
      dockerfile: Dockerfile
    expose:
      - "9000"
使用 docker-compose 安装 php 运行环境 —— network 的方式

—— 因为 docker-compose.yml 文件的每个服务都需要指定镜像,指定的方式有两种:

1、直接指定 image,会从 dockerhub 拉取。

2、指定 build ,即指定本地的 Dockerfile文件进行构建镜像。

那么,docker-compose.build.yml 中指定了 build,image 参数表示的是构建后的名字。build.yml 的是指定了构建 phpfpm 镜像的文件。

—— 所以,第一种是直接拉取叫做 raven666/ct-phpfpm:v1 的镜像,其实这个镜像就是我构建后传到 dockerhub 的

—— 第二种,就是使用本地文件 Dockerfile 重新构建一次这个 phpfpm 镜像,并在本地命名为 raven666/ct-phpfpm:v1

 

 

  

其中,我们的 docker-compose.yml 文件如下:

version: '3'
services:
  nginx:
    image: nginx:1.15-alpine
    container_name: mynginx
    ports:
      - "80:80"
    volumes:
      - ${DIR_WWW}:${DIR_WWW}:rw
      - ./conf/nginx/conf.d:/etc/nginx/conf.d/:ro
      - ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./log/nginx/:/var/log/nginx/:rw
    networks:
      - front

  phpfpm:
    image: raven666/ct-phpfpm:latest
    container_name: myphpfpm
    expose:
      - "9000"
    volumes:
      - ${DIR_WWW}:${DIR_WWW}:rw
      - ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro
      - ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw
      - ./conf/supervisor/conf.d:/etc/supervisor/conf.d/:ro
      - ./log/php-fpm/:/var/log/php-fpm/:rw
      - ./log/supervisor/:/var/log/supervisor/:rw
    command: supervisord -n
    networks:
      - front
      - backend
      
  mysql:
    image: mysql:5.7
    container_name: mymysql
    env_file: .env
    ports:
      - "3306:3306"
    volumes:
      - ./conf/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
      - ${DIR_MYSQL_DATA}:/var/lib/mysql/:rw
      - ./log/mysql/:/var/log/mysql/:rw
    environment:
      MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
      MYSQL_DATABASE: "${MYSQL_DATABASE}"
    networks:
      - backend

  redis:
    image: redis:latest
    container_name: myredis
    env_file: .env
    command: redis-server --requirepass "${REDIS_PASSWORD}" --appendonly yes
    ports:
      - "6379:6379"
    volumes:
      - ${DIR_REDIS_DATA}:/data
    networks:
      - backend

networks:
  front:
  backend:

———— 这里我们需要特别说明,各个服务(service)的网桥如下:

nginx 加入 front 网络(网桥)

phpfpm 加入 front 和 backend 网络(网桥)

mysql、redis都加入了 backend 网络(网桥)

—— 意味着,phpfpm 技能连接 nginx,也能连接 mysql 和 redis (在同一个网络里,容器是能够互相联通的。)

—— 那么,他们是怎么连接的呢?我们的虚拟主机配置给出了答案:phpfpm:9000,就是通过【服务名:端口】 或者【别名:端口】就可以连接。当然,这里我们并没有设置端口。

 

// 验证使用 network 的容器互联:

// 1、登录 myphpfpm
docker exec -it nginx bash
// 2、安装 ping
apt-get install inetutils-ping
// 3、ping mysql 容器
ping mysql

——返回 :
PING mysql (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: icmp_seq=0 ttl=64 time=0.177 ms
64 bytes from 172.19.0.4: icmp_seq=1 ttl=64 time=0.191 ms
64 bytes from 172.19.0.4: icmp_seq=2 ttl=64 time=0.221 ms

—— 说明ping 通了,并且mysql 容器目前的 IP 地址是172.19.0.4

 

 

总结,我们可以总共有三种容器互联的方式:

第一种:IP+端口的方式,这种方式我们在centOS 手动 Docker 安装 LNMP 环境时候提到。

第二种:指定容器的 link,这种单向性和不可维护性,我们不建议使用,在使用 docker-compose 安装 php 运行环境 —— link 的方式】中有提到。

—— 请注意:前面两种已经不建议使用了。

第三种:通过 network 的方式,我们通过本篇文章阐述了。至于网络基础部分的内容,请查看我的系列文章网络基础概念docker 的 link 和 network 网络互连问题

 

 

 

 

 

 

 

 

 

 

——————占位符