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

如何用Docker实现PHP命令行程序的CI-CD

时间:2023-03-30 00:17:04 PHP

今天树人云带来的文章将分享一下如何用Docker实现PHP命令行程序的CI/CD的整体思路以及需要注意哪些问题被重视。6月10日,《DevOps&SRE超越传统运维之道》的话题将在北京继续。四位行业专家齐聚一堂,基于传统运维现状和实际案例,畅谈DevOps&SRE的超越。点击注册。内容亮点:使用Jet设置环境并在本地运行测试配置CodeshipPro以在每次提交新代码时自动运行测试在上一步测试通过后自动将更新部署到服务器接下来要做的是设置一些连续的集成系统。虽然可以设置一个服务器来执行此操作,但这个过程需要更多的工作,因此推荐使用像CodeshipPro这样的服务。使用Jet进行本地测试在将代码提交到Codeship进行测试之前,建议先安装其本地版本的持续集成平台:Jet。这样可以更快地推进工作。在下面的示例配置文件中,需要根据应用的实际情况进行相应的调整。安装Jet后,在项目根目录下新建两个文件——1)codeship-services.yml——docker-compose.yml文件的变体,适用于Codeship2)codeship-steps.yml——持续集成时,命令及顺序说明codeship-services.yml文件与docker-compose.yml几乎相同。内容如下:version:"2.0"services:#PHPApplicationapp:build:.links:-databaseencrypted_env_file:.env.encryptedcommand:cron-f#Databasedatabase:image:mariadbencrypted_env_file:.env.encrypted#Composercomposer:image:composer/composervolumes:-./:/appcodeship-steps.yml的内容如下,例子中这个文件很简单,按顺序(一条一条)执行这些命令即可。如果应用程序允许,您还可以并行运行某些步骤:-type:serialsteps:-service:composercommand:install-service:appcommand:bashdocker/codeship-run.sh以确保应用程序容器和数据库容器已经启动了,可以看到codeship-steps.yml文件调用了一个还没有创建的shell脚本。如果迁移了数据库,则测试通过。将脚本放在./docker/codeship-run.sh中,内容如下:#!/usr/bin/envbash##确保数据库启动并运行functiontest_database{mysqladmin-h"$DB_HOST"-u"$DB_USERNAME"-p"$DB_PASSWORD"ping}count=0until(test_database)do((count++))##这将最多检查100次。if[${count}-gt100]thenecho"Servicesdidn'tbecomereadyintime"exit1fi##脚本在每次尝试之间等待一秒钟sleep1done##创建数据库mysql-h"$DB_HOST"-u"$DB_USERNAME"-p"$DB_PASSWORD"-e'CREATEDATABASEIFNOTEXISTSlaravel'##运行migrationsphpartisanmigrate##运行测试套件vendor/bin/phpunit首先,脚本将尝试连接到数据库。Codeship软件自动启动应用容器和数据库容器,但是MySQL初始化需要几秒,所以必须重试test_database()函数,直到连接数据库成功(或尝试100次)。这在Codeship的Docker文档中有更详细的概述。一旦脚本可以连接到数据库,它将创建默认数据库(名为laravel的数据库)。然后运行迁移以通过PHPUnit创建数据库表和测试套件。最后,为了测试配置是否正常运行,结果是否通过,使用Jet运行所有步骤:$jetsteps如果一切正常,那么在构建容器镜像的过程中,你会看到一堆输出,操作返回成功消息:{ContainerRunStdout=step_name:"serial_bash_docker/codeship-run.sh"service_name:"app"}:PHPUnit5.7.19bySebastianBergmannandcontributors.{ContainerRunStdout=step_name:"serial_bash_docker/codeship-run.sh"service_name:"app"}:.1/1(100%)时间:1.09秒,内存:12.00MBOK(1test,1assertion){StepFinished=step_name:"serial_bash_docker/codeship-run.sh"type:STEP_FINISHED_TYPE_SUCCESS}$将仓库连接到Codeship如果有没有提交本地代码到GitHub或Bitbucket。每次提交代码更改时,Codeship都会自动从私有或公共存储库中提取代码,因此您只需要设置Codeship来监控该存储库。在Codeship中创建一个新项目并将其连接到存储库:出现提示时,选择CodeshipPro作为项目类型。该项目现在链接到Codeship。下次提交代码时,Codeship会使用与本地相同的codeship-steps.yml编译运行。此时唯一的问题是使用本地.env文件,该文件未提交到存储库,但有一种简单的方法可以在不影响安全性的情况下设置环境变量。加密环境变量由于最好不要将.env文件推送到持续集成服务器,因此您需要想出一种安全地将变量传递给Codeship的方法——加密.env文件。首先,在Codeship中找到AES密钥(一般位于项目设置的General页面),将其放在本地根目录下一个名为codeship.aes的文件中。不要忘记将此文件添加到.gitignore,因为它是一个不应共享的密钥:接下来,更新codeship-services.yml文件以使用加密的.env文件而不是纯文本.env文件:版本:”2.0"services:#PHP应用程序app:build:.链接:-databaseencrypted_env_file:.env.encryptedcommand:cron-f#Databasedatabase:image:mariadbencrypted_env_file:.env.encrypted#Composercomposer:image:composer/composervolumes:-./:/app使用Jet加密.env文件转化为.env.encrypted,将加密后的.env.encrypted文件提交到软件仓库,然后推送到远程仓库:$jetencrypt.env.env。encrypted$gitadd-A&&gitcommit-am"Addingcodeshipconfig"$gitpushoriginCodeship正在编译代码:也可以点进去查看详细的编译过程和每一步:如果上面都正确执行,最后会看到asuccess编译结果:自动部署虽然持续集成服务会让人知道编译和测试是否通过,但是使用Codeship更大的价值在于自动化部署过程。为了做到这一点,需要做几件事:手动配置和部署存储库服务器上有一个SSH密钥,允许从存储库中提取代码服务器上有一个脚本可以更新代码并重新启动容器准备就绪后,您将构建一个部署容器,其工作是执行构建过程。完成后,登录SSH服务器并运行更新脚本。这只是使用容器部署代码的一种方式,可能不是最好的方式。另一种选择是使用DockerHub等容器存储库来编译,然后直接从DockerHub更新容器。Docker在生产中的最佳实践仍在探索中,这种方式更适用,也相对简单。第一次手动部署代码这个步骤因托管服务提供商而异,但只要服务器安装了Git、Docker和DockerCompose,就可以了。SSH登录服务器:新建一个SSHkey让SSHkey可以读取代码仓库访问克隆代码仓库settings.env文件,使用新的APP_KEY和数据库密码使用docker-composeup-d–build命令镜像,并运行容器,您现在可以运行dockerps来查看它。第一次在本地配置项目时,可以看到同样的两个容器在运行。添加一个脚本来更新服务器代码现在在本地版本的代码中,添加一个shell脚本,它将从存储库中获取更新的代码并重新启动容器:#!/usr/bin/envbash##Pullthelatestcodegitpulloriginmaster##重建容器docker-composeup-d--build##运行migrationsdockerexecdockerphpcliexample_app_1phpartisanmigrate--force该文件名为deploy.sh,位于docker/文件夹中。此时,您要确保文件在服务器上,因此将代码提交到存储库,然后从服务器上拉取它。通过在服务器上运行命令:$bashdocker/deploy.sh并确保容器仍在工作。创建一个DeployerContainer综上所述,经过编译测试,现在需要一个容器来在Codeship的CI服务器上远程运行部署脚本。在名为deployer/的存储库中创建一个新目录,其中包含Dockerfile、.env文件和execute.sh文件。Dockerfile:FROMalpine:latest#InstallopensshRUNapkupdate&&apkaddopenssh#PrepforthesshkeyRUNmkdir-p"$HOME/.ssh"RUNtouch$HOME/.ssh/id_rsaRUNchmod600$HOME/.ssh/id_rsa#添加shell脚本COPYexecute.shexecute.shCMDshexecute.sh.env:USER=HOST=PRIVATE_SSH_KEY=execute.sh:#!/usr/bin/envbashecho-e$PRIVATE_SSH_KEY>>$HOME/.ssh/id_rsassh-t-oStrictHostKeyChecking=no$USER@$HOST"cddocker-php-cli-example&&shdocker/deploy.sh"这个容器将使用.env文件中的环境变量,SSH登录服务器运行部署脚本。让CodeshipPro运行部署器容器要让Codeship了解部署器容器,请将其添加到codeship-services.yml文件中:-service:deployercommand:shexecute.sh加密deployer/.env文件,这样就可以在不暴露服务器的SSH密钥的情况下提交到代码仓库。就像对主代码库所做的那样,使用jet加密.env文件:$jetencryptdeployer/.envdeployer/.env.encrypted最后,将更新后的代码推送到github存储库以确保Codeship成功编译和部署代码:地址:https://blog.codeship.com/add...推荐活动:MeetupBeijing|DevOps&SRE超越传统运维方式DevOps&SRE超越传统运维方式北京!6月10日,4位业内专家齐聚一堂,结合传统运维现状和实际案例,畅谈超越DevOps&SRE之道。活动报名地址:http://www.bagevent.com/event...