继上次搭建了Angular的集成开发环境后(基于gitlab和docker构建持续集成环境(一), 基于gitlab和docker构建持续集成环境(二) ),这次给大家带来php(yii2框架)的集成开发环境部署。
经过之前两篇博客的介绍,基本的搭建思路还是比较清晰的。由于我们项目采用的是yii2框架,所以以下的一些配置文件都是基于yii2的,其他php框架应该大同小异。
我采用的是yii2的高级模板,官方有详细的docker搭建方案,其中提到了yii2-app-advanced 还在开发,其实已经开发完毕了。具体使用方式参考这里,而相关配置文件可以从官方的资源库得到。
接下分析yii2的docker化部署思路。
首先在高级模板的backend和frontend中均加入了一个dockerfile,以backend中的举例:
FROM yiisoftware/yii2-php:7.2-apache
# Change document root for Apache
RUN sed -i -e 's|/app/web|/app/backend/web|g' /etc/apache2/sites-available/000-default.conf
配置比较简单,首先用到了yiisoftware官方定制的镜像,基于的是php7.2、apache的版本;然后复写了apache配置文件,定位到了backend/web下面,这都比较好理解。frontend中的同理。
其次就是在根目录中加入了docker-compose.yml文件:
version: '3.2'
services:
frontend:
build: frontend
ports:
- 20080:80
volumes:
# Re-use local composer cache via host-volume
- ~/.composer-docker/cache:/root/.composer/cache:delegated
# Mount source-code for development
- ./:/app
backend:
build: backend
ports:
- 21080:80
volumes:
# Re-use local composer cache via host-volume
- ~/.composer-docker/cache:/root/.composer/cache:delegated
# Mount source-code for development
- ./:/app
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=verysecret
- MYSQL_DATABASE=yii2advanced
- MYSQL_USER=yii2advanced
- MYSQL_PASSWORD=secret
...
配置文件中建立了三个服务,分别是前台,后台和数据库,比较好理解。唯一要关注的就是这里用到了volumes挂载代码,所以代码是加载在host机上的。这点对后面的gitlab-ci集成部署有较大影响。
接下我们来对gitlab-ci集成开发做相应的配置,以下以开发分支为例。配置文件如下:
deploy_dev:
stage: deploy
only:
- develop
tags:
- dev
script:
- docker-compose run --rm backend composer install
- docker-compose run --rm backend /app/init --env=Development --overwrite=All
- docker-compose run --rm backend yii migrate --interactive=0
- docker-compose up -d
cache:
untracked: true
这里有两点要注意,首先script中的脚本来自yii2官方docker指南,即Installing using Docker。由于是脚本运行,所以加了一些参数,去掉了交互。
其次是cache的配置,因为这里配到了一个比较大的问题,即gitlab-runner执行的时候,会先同步代码,然后删除在.gitignore文件定义的文件和文件夹,而上面配置文件中composer install安装的vender,所有者为root,导致脚本执行失败。
关于这个问题,我参考了一些文章:
gitlab runner failed to remove cache files
理解 docker 容器中的 uid 和 gid
Handling File Permissions When Writing to Volumes from #Docker Containers
每个 Job 开始的时候,Runner 都会删掉 .gitignore 里面的文件
cache:untracked – 这是最终解决方案,不过有个弊端,看文章最后
这个问题同样影响到了runtime生成的缓存文件,由于上文中提高了,docker-compose.yml中用volumes挂载代码,所以yii2自带的runtime缓存系统,就会在相应的地方生成缓存文件,而生成的缓存文件所有者则是由docker中的apache拥有者。于是这里我对Dockerfile做部分修改:
FROM yiisoftware/yii2-php:7.2-apache
# Change document root for Apache
RUN sed -i -e 's|/app/web|/app/backend/web|g' /etc/apache2/sites-available/000-default.conf
# Change owner for apache
RUN useradd --comment 'GitLab Runner' -u 1006 --create-home gitlab-runner --shell /bin/bash
RUN sed -i -e 's|www-data|gitlab-runner|g' /etc/apache2/envvars
其中里面的1006,取得是host机中gitlab-runner这个用户的userid,这样runtime生成的缓存文件的所有者正好就属于gitlab-runner。 (可以用以下命令更改宿主机的userid:usermod -u 1006 gitlab-runner && groupmod -g 1006 gitlab-runner )
补充
yii2的官方只给了backend和frontend两个service的dockerfile,但并没有针对console里面计划任务的service。在参考了以下几篇文章后,我自己写了一个dockerfile,供大家参考。
how-to-run-a-cron-job-inside-a-docker-container
why-is-crond-failing-to-run-a-non-root-crontab-on-alpine-linux
yii2-scheduling
FROM yiisoftware/yii2-php:7.2-apache
# install cron
RUN apt-get update && apt-get -y install cron
# Change owner for crontab
RUN useradd --comment 'GitLab Runner' -u 1006 --create-home gitlab-runner --shell /bin/bash
# Add crontab file in the cron directory
ADD crontab /etc/cron.d/cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/cron
# Apply cron job
RUN crontab -u gitlab-runner /etc/cron.d/cron
# Run the command on container startup
CMD ["cron", "-f"]
* * * * * /usr/local/bin/php /app/yii schedule/run --scheduleFile=@console/config/schedule.php
command('test')->everyMinute();
最后还有一个问题待解决,即当composer.json中新加了一个依赖后,composer install下载的新的依赖包仍旧是root所有,现在的解决方案是,删掉已经生成的vendor,再从跑下job就能可以了。