第一次听说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。
文字多一点,可能无法准确表达遇到问题的解决方法,参考一下让大伙少走弯路。
网友评论