docker下多容器 快速搭建dnmp环境 并实现一键自动化部署

需求

假如有这样一个项目,在家开发需要搭建环境,在公司开发需要搭建环境,到测试需要搭建环境,到线上还需要搭建环境。而且搭建环境的时候,还要安装各种依赖,还可能出现,本地能用,测试不能用等各种情况。这个情况下,我们只需要在系统中装上Docker,写好Dockerfile,运行docker-compose.yml 就自动完成部署,保证了在各个平台上的一致性,岂不是既方便又高效。

多个容器的好处

搭建PHP环境,必需要启动的容器: nginx、php。当然,除了这些容器,还可能涉及到如:mysql、redis、Memcached 等相关扩展。

相比采用单容器部署(原生安装lnmp),多容器部署比较灵活,比如 在安装nginx的时候,出现了未知错误,而又不能解决,只能重装的时候,这时,我们只需要删除旧的ngxin容器,启动一个新nginx容器就行了,php等相关容器,不受任何影响。但是采用单容器部署,就相当于删除了整个环境,所有的东西都要重新安装部署。当然,单容器也好处,在保证正常运行的情况下,可以将此容器构建成一个新的镜像,每次使用的时候,只需要以此镜像启动一个容器就可以了。

资源

关于本次搭建涉及的相关文件跳转:资源
关于docker的安装跳转:docker安装
关于docker的使用命令跳转:

一、手动构建

  1. 拉取需求镜像

    docker pull php:7.2-fpm
    docker pull nginx
    docker pull mysql:5.7
    docker pull redis:3.2
    #版本号可根据实际需求选择
    
  2. 通过redis镜像启动一个redis容器

    docker run --name master-redis -p 6379:6379 -d redis:3.2
    
  3. 通过mysql镜像启动一个mysql容器

    docker run --name master-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
    

    # -e MYSQL_ROOT_PASSWORD 给mysql设置初始密码

  4. 通过php镜像启动一个php容器

    docker run -d -p 9000:9000 --name master-php -v d:/dnmp/www:/var/www/html -v d:/dnmp/php:/usr/local/etc/php --link master-db:master-db --link master-redis:master-redis --privileged=true php:7.2-fpm
    
  5. 通过ngxin镜像启动一个nginx容器

    	docker run --name master-nginx -d -p 80:80 -v d:/dnmp/www:/usr/share/nginx/html -v d:/dnmp/nginx:/etc/nginx -v d:/dnmp/logs/nginx.logs:/var/log/nginx --link master-php:master-php --privileged=true nginx
    

    参数说明:
    # --name 容器别名,此名将用于建立容器之间的连接、ngxin配置、PHP代码中连接配置等,因此,一旦变更容器名,则使用该容器名的地方也必须更改

    # -v 启动PHP容器时,需映射容器内部某些路径 到 宿主机路径,保证文件同步。(挂载一个空文件夹是会覆盖容器中的内容,所以配置文件要事先准备好。这里要注意当前项目的路径,不要直接拷贝使用)

    # --link 使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,解除了容器之间通信对容器IP的依赖。

    # --privileged=true 给容器特权,在挂载目录后容器可以访问目录以下的文件或者目录若修改了–name 容器名,需修改对应配置文件。

  6. PHP扩展库安装

    #进入master-php容器
    docker exec -it  master-php  /bin/bash  
    #安装pdo_mysql扩展
    docker-php-ext-install pdo pdo_mysql  
    #由于php源码中没有redis,则需要手动拉取redis包
    #拉取redis扩展包
    curl -L -o /tmp/redis.tar.gz  https://github.com/phpredis/phpredis/archive/4.2.0.tar.gz
    #解压包
    tar zxvf  /tmp/redis.tar.gz
    #删除包
    rm -r /tmp/redis.tar.gz
    #创建执行目录
    mkdir -p /usr/src/php/ext
    #将解压后的redis扩展移到执行目录
    mv phpredis-4.2.0 /usr/src/php/ext/redis
    #安装redis
    docker-php-ext-install redis
    #退出容器
    exit
    #重启容器
    docker restart master-php
    

二、自动化构建(docker-compose)

docker-compose是编排容器的。
如,有一个php镜像,一个mysql镜像,一个nginx镜像。如果没有docker-compose,那么每次启动的时候,你需要敲各个容器的启动参数,环境变量,容器命名,指定不同容器的链接参数等等一系列的操作,相当繁琐。而用了docker-composer之后,你就可以把这些命令一次性写在docker-composer.yml文件中,以后每次启动这一整个环境(含3个容器)的时候,你只要敲一个docker-composer up命令就ok了。

1.编写docker-compose.yml文件

version: "2"
services:
  master-db:
    container_name: "master-db"
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - d:/dnmp/mysql/conf.d/:/etc/mysql/conf.d/
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    image: mysql:5.7
  master-redis:
    container_name: "master-redis"
    restart: always
    ports:
      - "6379:6379"
    volumes:
      -  d:/dnmp/redis:/data
    image: redis:3.2
  master-php:
    container_name: "master-php"
    restart: always
    ports:
      - "9000:9000"
    volumes:
      -  d:/dnmp/www:/var/www/html
      -  d:/dnmp/php:/usr/local/etc/php
    links:
      - "master-db"
      - "master-redis"
    image: php:7.2-fpm
  master-nginx:
    container_name: "master-nginx"
    restart: always
    ports:
      - "80:80"
    links:
      - "master-php"
    volumes:
      -  d:/dnmp/www:/usr/share/nginx/html
      -  d:/dnmp/nginx:/etc/nginx
      -  d:/dnmp/logs/nginx.logs:/var/log/nginx
    image: nginx:latest

	#container_name  				指定一个自定义容器名称,而不是生成的默认名称。
    #restart: always				容器重新启动参数,always:容器总是重新启动
    #ports:  				        暴露端口信息
    #volumes: 						卷挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro),挂载数据卷的默认权限是读写(rw),可以通过ro指定为只读
    #environment:					添加环境变量
    #MYSQL_ROOT_PASSWORD: 			设置数据库默认密码
    #image:							指定镜像

2.执行docker-compose.yml

进入docker-compose.yml文件目录,执行命令
docker-compose up -d
一键创建对应容器,但是PHP扩展还得手动安装

三 、完整构建

上面docker-compose实现一键式操作 但问题是PHP的扩展库还是得自己单独装
这里用Dockerfile来构建自定义容器镜像实现真正的一键完成

mysql/Dockerfile

FROM mysql:5.7
MAINTAINER qyh "[email protected]"

# set timezome
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

redis/Dockerfile

FROM redis:4.2
MAINTAINER qyh "[email protected]"

# set timezome
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

nginx/Dockerfile

FROM nginx
MAINTAINER qyh "[email protected]"

# set timezome
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

php/Dockerfile

FROM php:7.2-fpm
MAINTAINER qyh "[email protected]"

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
        && docker-php-ext-install zip \
        && docker-php-ext-install pdo_mysql \
        && docker-php-ext-install opcache \
        && docker-php-ext-install mysqli

RUN pecl install redis && docker-php-ext-enable redis \
	&& pecl install xdebug && docker-php-ext-enable xdebug

RUN echo "" >> /usr/local/etc/php/php.ini
RUN usermod -u 1000 www-data

docker-compose.yml

version: "2"
services:
  master-db:
    build: ./mysql
    container_name: "master-db"
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - d:/dnmp/mysql/conf.d/:/etc/mysql/conf.d/
    environment:
      MYSQL_ROOT_PASSWORD: 123456
  master-redis:
    build: ./redis
    container_name: "master-redis"
    restart: always
    ports:
      - "6379:6379"
    volumes:
      -  d:/dnmp/redis:/data
  master-php:
    build: ./php
    container_name: "master-php"
    restart: always
    ports:
      - "9000:9000"
    volumes:
      -  d:/dnmp/www:/var/www/html
      -  d:/dnmp/php:/usr/local/etc/php
    links:
      - "master-db"
      - "master-redis"
  master-nginx:
    build: ./nginx
    container_name: "master-nginx"
    restart: always
    ports:
      - "80:80"
    links:
      - "master-php"
    volumes:
      -  d:/dnmp/www:/usr/share/nginx/html
      -  d:/dnmp/nginx:/etc/nginx
      -  d:/dnmp/logs/nginx.logs:/var/log/nginx

将docker-compose.yml文件放置和各Dockerfile目录同级下
进入该目录 并执行命令
docker-compose up -d

docker-compose.yml和前面不同的是,当采用Dockerfile创建时,不再需要指定官方镜像image:,而是直接build:./目录 来引用目录中配置好的Dockerfile来创建新的镜像。
注意:一旦创建,下次docker-compose会直接取已有镜像而不会build创建 若你修改了Dockerfile配置请记得删除之前镜像

如宿主机上需要用shell调度php执行脚本,可以执行下面命令

docker exec -it master /bin/bash -c '/usr/local/bin/php /var/www/html/blog/public/index.php

你可能感兴趣的:(docker,PHP)