基于gitlab和docker构建持续集成环境(三)

继上次搭建了Angular的集成开发环境后(基于gitlab和docker构建持续集成环境(一), 基于gitlab和docker构建持续集成环境(二) ),这次给大家带来php(yii2框架)的集成开发环境部署。
经过之前两篇博客的介绍,基本的搭建思路还是比较清晰的。由于我们项目采用的是yii2框架,所以以下的一些配置文件都是基于yii2的,其他php框架应该大同小异。

1.添加Dockerfile和docker-compose.yml

我采用的是yii2的高级模板,官方有详细的docker搭建方案,其中提到了yii2-app-advanced 还在开发,其实已经开发完毕了。具体使用方式参考这里,而相关配置文件可以从官方的资源库得到。
接下分析yii2的docker化部署思路。

1.1 Dockerfile

首先在高级模板的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中的同理。

1.2 docker-compose.yml

其次就是在根目录中加入了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集成部署有较大影响。

2.添加.gitlab-ci.yml

接下我们来对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

Dockerfile
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"]
crontab
* * * * * /usr/local/bin/php /app/yii schedule/run --scheduleFile=@console/config/schedule.php

@console/config/schedule.php
<?php
/**
 * @var \omnilight\scheduling\Schedule $schedule
 */

$schedule->command('test')->everyMinute();

最后还有一个问题待解决,即当composer.json中新加了一个依赖后,composer install下载的新的依赖包仍旧是root所有,现在的解决方案是,删掉已经生成的vendor,再从跑下job就能可以了。

20200622 补充

关于cache的问题,补充一下三点:
1.今天又碰到一个新的问题,job因为cache的问题失败,具体可以见下面的链接:
GitLab CI - Cache not working
解决思路就是:第一次跑job必须成功以后,才会创建cache。
2.并且之前说的最后一个问题,其实可以点击gitlab上面有个 Clear Runner Caches 的按钮,执行以下再跑job就行了
3.最后很重要的一点,当cache跑成功以后,vender还是会属于root,接下来再跑job又会出现Permission denied的问题,因为job还是会去删vender,这个时候去服务器手动删除下vendor,再跑job,vender就会属于gitlab-runner,之后再跑job就没问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

F_angT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值