docker-compose 部署nginx+php+mysql+redis

  第一次听说docker可以一条指令部署一整套的运行环境的时候,心里是很好奇的,平时虽然用phpstudy或者manp也没多大的麻烦,但是开发中由于工作环境差异性,有时候在本地开发环境测试没问题的代码,到线上就莫名其妙的不行了。抱着好奇的心里决定一窥究竟。

  跟学习一门新语言一样。先看一下什么是docker,工作原理是什么,运行要求等,开始整活,先搞个nginx,简单,几分钟ok。接下来就是nginx+php,花了点时间,每个docker容器,或者说是应用服务,都是一个独立的沙箱,通过特定的端口号互相作用,比如nginx的fastcgi_pass可以配置为127.0.0.1:9000(9000是php容器的端口号)来访问php-fpm。

  docker-compose:一键执行搭建服务,非常方便,通过创建专有网络将一个个的nginx、php、mysql等等等都系统的管理起来,使用之前要准备好image字段所指明的镜像。


version: "2"


services:

  nginx:

     image: nginx:1.19.3

     restart: always

     container_name: nginx

     volumes:

      - "/home/www/wwwroot/web:/www/home"

      - "/home/www/docker-compose.d/nginx/nginx.conf:/etc/nginx/nginx.conf"

      - "/home/www/docker-compose.d/nginx/conf.d:/etc/nginx/conf.d"

      - "/home/www/docker-compose.d/nginx/logs:/var/log/nginx"

     ports:

      - "80:80"

     depends_on:

      - php

      - mysql

      - redis

     networks:

      docker_composer_net:

       aliases:

         - nginx

  php:

    image: php:7.4.11-fpm

    restart: always

    ports:

      - "9000:9000"

    container_name: php

    volumes:

      - "/home/www/wwwroot/web:/www/home"

      - "/home/www/docker-compose.d/php/php-fpm.d/www.conf:/opt/bitnami/php/etc/php-fpm.d/www.conf"

    networks:

      docker_composer_net:

        aliases:

          - php

  mysql:

    image: mysql:8.0.22

    restart: always

    container_name: mysql

    volumes:

      - "/home/www/docker-compose.d/mysql/conf:/etc/mysql/conf.d"

      - "/home/www/docker-compose.d/mysql/logs:/logs"

      - "/home/www/docker-compose.d/mysql/data:/var/lib/mysql"

    ports:

      - "3306:3306" #最好改成其他端口,避免黑客入侵

    #command:  -e MYSQL_ROOT_PASSWORD=123456

    command: [

      '--default-authentication-plugin=mysql_native_password',

      '--character-set-server=utf8mb4', #设置数据库表的数据集

      '--collation-server=utf8mb4_unicode_ci', #设置数据库表的数据集

    ]

    environment:

      MYSQL_ROOT_PASSWORD: "123456"

      #MYSQL_USER: 'ylc' #不懂为啥,不会创建,所以注释,后面再去研究

      #MYSQL_PASS: 'ylc123'

      MYSQL_DATABASE: "wowonew"

    networks:

      docker_composer_net:

        aliases:

          - mysql

  redis:

    image: redis:6.0.8

    restart: always

    container_name: redis

    volumes:

      - "/home/www/docker-compose.d/redis/redis.conf:/etc/redis/redis.conf:rw"

      - "/home/www/docker-compose.d/redis/data:/data:rw"

      - "/home/www/docker-compose.d/redis/redis.log:/dev/null"

    ports:

      - "6379:6379" #最好改成其他端口,避免黑客入侵

    command: redis-server /etc/redis/redis.conf --appendonly yes #数据持久化,启动的时候指定redis.conf。这边的redis.conf要是容器的地址

    networks:

      docker_composer_net:

        aliases:

          - resis

networks:

  docker_composer_net:

  dockerfile:刚开始的时候有时候,测试要看一看容器里面的东西,发现直接执行vi .....,提示我“-bash:vi command not found”,想想也是,人家都把镜像往最小的做,怎么可能每个镜像都有一套linux的一套软件。于是就在容器里安装vi,但是每次重新生成容器后都要重新安装vim一次,实在是烦,其实只需要将要查看的目录通过volumes字段挂在出来就可以了,只是这引出了我的一些思考和折腾。于是我发现了dockerfile,用户来在容器生成的时候执行相关的指令,我就想要把安装vim的shell指令写进去让执行而已,然后发现docker-compose文件里有个build的字段用来指定dockerfile的。我就想每次只需要一条up就能安装各种各样的扩展,就很方便,可是光是在容器里安装一个vim都要花费五六分钟,每个容器安装一次半个钟都算少了。先实践一下,进入到安装了vim的容器确实是能使用vi了。但是也发现create完容器之后,仓库多了个$rootDir_$containerName命名的镜像,例如web_nginx(web是我执行docker-compose up -d的目录,也就是根目录,nginx是我的容器名称)。由此知道,dockerfile的执行会伴随一个自定义的镜像生成,然后当再次执行up的时候,重点来了,docker内核会根据镜像的上下文目录。一般是dockerfile所在的目录,来查看是否存在之前在该目录创建过的镜像,有则直接使用,无则创建。一般有两个方法创建镜像,1、docker build -t nginx:v3。2、在docker-compose.yml的build字段指定dockerfile的路径。生成$rootDir_$containerName格式命名的镜像。也就是我用的方法。建议使用第一种,起码能控制一下镜像的命名嘛,问就是强迫症。其实这么做对理解docker是很有意义的,直接拿别人的docker-compose来用,不如自己一个个推敲。还有一点,就是当存在以某个目录为上下文目录生成的镜像时,修改原有的dockerfile再执行up是不会生成新的镜像和容器的,up命令不负责镜像的更新,最后还是得单独执行docker build靠谱。

  简而言之,要使用docker-compose有两个步骤,1、准备镜像,包括五花八门的自己定制的dockerfile生成的镜像。2、编写docker-compose.yml文件,并将各个挂载的目录、配置文件准备好。最后up。

  文字多一点,可能无法准确表达遇到问题的解决方法,参考一下让大伙少走弯路。

推荐阅读更多精彩内容