当前位置: 首页 > 后端技术 > PHP

使用Docker搭建自己的PHP开发环境

时间:2023-03-29 14:28:16 PHP

1.前言1.1为什么要使用Docker?有没有这种场景,你启动了一个项目,本地开发的时候需要搭建环境,上线的时候也需要搭建环境。有相当多的环境依赖性。如果这时候你有Docker,只需要在机器上安装Docker,把写好的Dickerfile放进去,一条命令自动完成这件事情,方便高效,是不是很棒?1.2准备接下来本文介绍如何搭建PHP开发环境,以zPhal-dockerfiles为例,这是我为自己的博客系统准备的一套Dockerfile。现在无论是windows、mac还是linux,docker都能很好的支持,包括windows系统。DockerforWindows其实在win10系统下还是挺不错的,就是比较耗内存。通过Docker命令行,我们可以做很多事情,拉取镜像,运行容器,在容器中执行命令等等,但是现在,我们需要用更简单粗暴的方式编写dockerfile,然后通过docker-compose来管理这些文件,简化操作流程。什么是Dockerfile?Dockerfile是由一系列命令和参数组成的脚本。这些命令应用于拉取的基础镜像并最终创建一个新镜像。通过Dockerfile,我们可以创建一个你需要的镜像,里面包含了你要安装的软件。相当于预先自定义好要安装的扩展、要执行的命令等,然后一键执行,大大简化了操作流程。按照本文搭建环境需要:首先了解Docker和Docker的一些基本操作,以及docker-compose是什么。然后需要安装Docker和docker-compose,我将使用docker-compose来管理我的dockerfiles。注意,写dockerfile是活的,不是死的,每个人写的dockerfile都会不一样,看你的需求。Docker的官方文档写的很清楚。虽然是英文的,但是基本上什么都有。如果有问题,转向文档是非常明智的:DockerDocumentation2。开始写然后以zPhal-dockerfiles为例。完整的可以点击链接进入查看,后面只是一个片段。2.1预览首先我们来看一下。我创建的dockerfile项目大致分为以下几个目录(当然这是我自己设置的,不需要你这样格式化你的文件):zPhal-dockerfilesapp/index.phpphpinfo.phpdata/.gitignore文件/mysql/conf.d/mysql-file.cnfDockerfilenginx/conf.d/default.confzphal.confDockerfilenginx.confphp/pkg/.gitignoreDockerfilephp.iniphp-dev.iniphp-fpm.confredis/Dockerfiledocker-compose.ymllogs/.gitgnoreREADME.md在这个项目中,我使用了PHP、MySQL、Nginx、Redis;以及Composer、Phalconextension等。总的来说,我们有三个过程来做这件事:编写每个软件的dockerfile;编写配置文件;通过docker-compose处理所有的dockerfile,包括将configuration配置文件丢到dockerfile将构建的镜像中。2.2编写Dockerfile2.2.1PHP下面是PHP的Dockerfile:FROMphp:7.2-fpmMAINTAINERgoozp"gzp@goozp.com"#设置时区ENVTZ=Asia/ShanghaiRUNln-snf/usr/share/zoneinfo/$TZ/etc/localtime&&echo$TZ>/etc/timezone#更新并安装依赖和PHP核心扩展RUNapt-getupdate&&apt-getinstall-y\git\libfreetype6-dev\libjpeg62-turbo-dev\libpng-dev\&&docker-php-ext-configuregd--with-freetype-dir=/usr/include/--with-jpeg-dir=/usr/include/\&&docker-php-ext-install-j$(nproc)gd\&&docker-php-ext-installzip\&&docker-php-ext-installpdo_mysql\&&docker-php-ext-installopcache\&&docker-php-ext-installmysqli\&&rm-r/var/lib/apt/lists/*#从宿主机复制预下载的扩展包COPY./pkg/redis.tgz/home/redis.tgzCOPY./pkg/cphalcon.tar.gz/home/cphalcon.tar。gz#安装PECL扩展,这里我们安装了RedisRUNpeclinstall/home/redis.tgz&&echo"extension=redis.so">/usr/local/etc/php/conf.d/redis.ini#安装第三方扩展,这里是Phalcon扩展RUNcd/home\&&tar-zxvfcphalcon.tar.gz\&&mvcphalcon-*phalcon\&&cdphalcon/build\&&./install\&&echo"extension=phalcon.so">/usr/local/etc/php/conf.d/phalcon.ini#安装ComposerENVCOMPOSER_HOME/root/composerRUNcurl-sShttps://getcomposer.org/installer|php----install-dir=/usr/local/bin--filename=composerENV路径$COMPOSER_HOME/vendor/bin:$PATHRUNrm-f/home/redis.tgz\rm-f/home/cphalcon.tar.gzWORKDIR/data#WritePermissionRUNusermod-u1000www-data第一行定义基础镜像,这里我们使用PHP7.2的fpm版本,这里第二行line定义一个maintainer,然后定义时区,这句话定义在每个dockerfile中,主要是为了同步所有容器与宿主机的时间,其实我们可以在docker-composer.yml文件中这样定义:services:php-fpm:volumes:-/etc/localtime:/etc/localtime:ro但是当运行我在非linux系统中,例如Windows,我们无法获取/etc/localtime。为了更加兼容所有平台,我把时间同步写在了dockerfile中。接下来,安装一些扩展。其实安装扩展的过程和在linux中徒手安装PHP扩展类似。值得一提的是作曲家。我直接在php-fpm的镜像里安装了Composer。其实官方也提供了Composer的镜像。拉取composer镜像也可以达到目的,因为我们使用composer只是为了执行composer命令来管理我们的包。如果composer是单独一个容器的话,我们可以在不用的时候把容器关掉;但是这里,我直接将composer安装到php-fpm镜像中,主要是因为我的项目安装了一些PHP扩展,而我在编写composer.json文件中,定义了扩展的依赖,这样composer执行的时候,会检查环境是否安装了这些依赖。如果我直接用composer镜像的话,需要把我用的扩展安装到镜像里,麻烦多了,所以我直接在php镜像里做了这个,没有什么区别,就看你怎么用了它。2.2.2Nginx下面是Nginx的dockerfile:FROMnginx:1.12#settimezomeENVTZ=Asia/ShanghaiRUNln-snf/usr/share/zoneinfo/$TZ/etc/localtime&&echo$TZ>/etc/timezone这个很简单More,我只定了一个时间。因为我不需要安装其他东西,直接使用官方镜像就可以了。当然我们需要修改配置文件,只要提前写好配置文件,最后在docker-compose.yml文件中,把配置文件丢进去,下面会讲到,包括PHP配置文件和MySQL配置文件相同。2.2.3MySQL下面是MySQLdockerfile:FROMmysql:5.7#settimezomeENVTZ=Asia/ShanghaiRUNln-snf/usr/share/zoneinfo/$TZ/etc/localtime&&echo$TZ>/etc/timezoneMySQLisnothing特别是,直接使用官方镜像。2.2.4Redis下面是Redis,直接使用官方镜像:FROMredis:3.2#settimezomeENVTZ=Asia/ShanghaiRUNln-snf/usr/share/zoneinfo/$TZ/etc/localtime&&echo$TZ>/etc/timezone2.3写配置文件如何处理配置文件,我会把配置文件分类,PHP配置文件放在PHP目录下,Nginx配置放在Nginx目录下,至于是否新建子文件夹就可以了看情况,比如conf.d文件夹。以Nginx配置文件为例。首先,nginx目录是这样的:nginx/conf.d/default.confzphal.confDockerfile除了nginx.conf,nginx.conf还有一个子文件夹conf.d存放所有的域名配置文件,应该熟悉linux下搭建过php环境的。这些配置文件就是我们当时要传入容器中的文件,我们在宿主机上是不会用到这些文件的。所以,最需要注意的是,配置文件中的路径是容器内部环境的路径,而不是宿主机的路径。每个容器都有一个运行环境,是一个微型系统。这些路径是容器内的路径。我们可以通过容器挂载和通信来同步文件。命令行启动容器也需要挂载文件路径,现在我们也是使用docker-compose来解决挂载这一步。这是一个示例配置文件:server{listen80default;indexindex.htmlindex.htm;server_namelocalhost泊坞窗;根目录/数据/www;indexindex.phpindex.htmlindex.htm;location/{try_files$uri$uri//index.html;}location~\.php{includefastcgi_params;fastcgi_passphp-fpm:9000;fastcgi_indexindex.php;fastcgi_paramSCRIPT_FILENAME/data/www/$fastcgi_script_name;}}whileroot/data/www,/data/www路径是当时nginx容器的路径,不是当前运行主机的路径,所以我们此时会把web程序的位置挂载到这个路径时间。2.4编写docker-compose.yml在php、nginx等目录同级,我们创建一个docker-compose.yml。当我们执行docker-compose相关命令时,会自动找到这个文件,并根据里面的内容执行。按照上面的nginx例子,我们先说挂载,因为这是最重要的一步。在docker-compose.yml中,nginx的一部分:nginx:build:./nginxdepends_on:-php-fpmlinks:-php-fpm:php-fpmvolumes:-../app:/data/www:rw-./nginx/conf.d:/etc/nginx/conf.d:ro-./nginx/nginx.conf:/etc/nginx/nginx.conf:ro-../logs/nginx:/var/log/nginx端口:-“80:80”-“8080:8080”-“443:443”重新启动:始终命令:nginx-g'守护程序关闭;'有一个volumes参数,这里是我们要挂载目录的相关配置,第一个我们挂载../app到/data/www,也是我们配置文件中定义的默认监听根目录,app目录是我们主机中的一个目录。通过这种方式挂载,我们可以将我们的项目文件直接放到app中,docker会帮你把它们转移到容器中的/data/www目录下。其他参数:build定义了你的dockerfile的位置。如果您不编写dockerfile,则不需要构建。可以使用images参数定义官方镜像,如image:mysql:5.7;depends_on表示会依赖其他镜像,比如nginx依赖php-fpm,没有它我玩不了nginx;links定义连接,比如连接到php-fpm容器,就是php-fpm:php-fpm,后面是别名;ports表示端口映射,80:80表示映射80端口到主机80端口restart重启,restart:always表示会自动重启command是自动执行的命令...参数很多,更多可以参考官方文件。下面是一个完整的docker-compose.yml文件:version:'3.2'services:php-fpm:build:./php/ports:-"9000:9000"links:-mysql-db:mysql-db-redis-db:redis-dbvolumes:-../app:/data/www:rw-./php/php-dev.ini:/usr/local/etc/php/php.ini:ro-./php/php-fpm.conf:/usr/local/etc/php-fpm.conf:ro-../logs/php-fpm:/var/log/php-fpm:rw重启:始终命令:php-fpmnginx:构建:./nginxdepends_on:-php-fpm链接:-php-fpm:php-fpmvolumes:-../app:/data/www:rw-./nginx/conf.d:/etc/nginx/conf.d:ro-./nginx/nginx.conf:/etc/nginx/nginx.conf:ro-../logs/nginx:/var/log/nginxports:-"80:80"-"8080:8080"-“443:443”重启:总是命令:nginx-g'daemonoff;'mysql-db:build:./mysqlports:-"3306:3306"volumes:-../data/mysql:/var/lib/mysql:rw-../logs/mysql:/var/lib/mysql-日志:rw-./mysql/conf.d:/etc/mysql/conf.d:ro环境:MYSQL_ROOT_PASSWORD:123456MYSQL_DATABASE:zphaldbMYSQL_USER:zphalMYSQL_PASSWORD:zphal123重新启动:始终命令:“--character-set-server=utf8”redis-db:构建:./redis端口:-“6379:6379”卷:-../data/redis:/datarestart:always3.我们如何使用这套写法?3.1使用搭建环境首先进入项目dockerfiles目录,这里是files目录:cdzPhal-dockerfiles/fileswgethttps://pecl.php.net/get/redis-3.1.6.tgz-Ophp/pkg/redis.tgzwgethttps://codeload.github.com/phalcon/cphalcon/tar.gz/v3.3.1-Ophp/pkg/cphalcon.tar.gz然后下载我们要用到的PHP扩展包,执行命令:docker-composeupdocker会通过写入的docker-compose.yml内容自动构建镜像并启动容器。如果没问题,你可以在下次启动时以守护进程模式启用它,所有容器将在后台运行:docker-composeup-d关闭容器你可以关闭容器并删除服务,这样:docker-composedown使用docker-compose基本上就这么简单,使用stop、start等命令来操作容器服务。更多的工作在于编写dockerfile和docker-compose.yml文件。3.2使用Composer想使用Composer应该怎么办?我们已经在php-fpm中安装了composer。使用docker-compose进行操作:docker-composerun--rm-w/data/www/zPhalphp-fpmcomposerupdate-w/data/www/zPhal为php-fpm的工作区,zPhal项目也是挂载在里面的,所有我们可以直接在容器中运行composer。或者进入宿主app目录,使用docker命令:cdzPhal-dockerfiles/appdockerrun-it--rm-v`pwd`:/data/www/-w/data/www/zPhalfiles_php-fpmcomposerupdate4.注意事项当构建挂载路径失败时,请注意容器中是否报错以加速镜像。如果下载图片的过程很慢,可以使用国内的图片加速服务,比如阿里云、道云。