社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

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

云技术实践 • 8 年前 • 952 次点击  

内容要点:

  • 使用Jet设置环境并在本地运行测试

  • 配置Codeship Pro每次新代码提交时,自动运行测试

  • 上一步的测试通过后,自动将更新部署到服务器


持续集成


应用程序和测试套件已经在本地运行,下一步要做的是建立一些持续集成系统。虽然可以设置服务器来执行此操作,但这个过程工作量略大,因此推荐一个像Codeship Pro的服务。


  • 使用Jet进行本地测试


代码提交到Codeship测试前,建议先安装其本地版本的持续集成平台:Jet。这会更快地推进工作,下面示例配置文件中,需要根据应用的实际情况,做出相应调整。


安装Jet后,在项目的根目录中创建两个新文件——


1)codeship-services.yml docker-compose.yml文件的变种,适用于Codeship

2)codeship-steps.yml – 在持续集成过程中,命令和顺序的说明


codeship-services.yml文件与 docker-compose.yml几乎一样。内容如下:


version: "2.0"

services:

  # PHP Application

  app:

    build: .

    links:

      - database

    encrypted_env_file: .env.encrypted

    command: cron -f

  # Database

  database:

    image: mariadb

    encrypted_env_file: .env.encrypted

  # Composer

  composer:

    image: composer/composer

    volumes:

      - ./:/app


codeship-steps.yml内容如下,这个文件在例子里很简单,按顺序执行这些的命令(一个接一个地)就好。如果应用程序允许,也可以并列地跑某几个步骤:


-type: serial
  steps:
  -service: composer
    command: install
  -service: app
    command: bash docker/codeship-run.sh


为了确保应用程序容器和数据库容器已启动,可以看到codeship-steps.yml文件调用了一个尚未创建的shell脚本。若数据库迁移,说明测试通过。把脚本放在./docker/codeship-run.sh,内容如下:


#!/usr/bin/env bash
 
## Ensure that the database is up and running
function test_database {
  mysqladmin -h"$DB_HOST"-u"$DB_USERNAME"-p"$DB_PASSWORD"ping
}
 
count=0
until( test_database )
do
  ((


    
count++))
  ## This will check up to 100 times.
  if[${count}-gt 100]
  then
    echo"Services didn't become ready in time"
    exit1
  fi
  ## And the script waits one second between each try
  sleep1
done
 
## Create the database
mysql -h"$DB_HOST"-u"$DB_USERNAME"-p"$DB_PASSWORD"-e 


    
'CREATE DATABASE IF NOT EXISTS laravel'
 
## Run migrations
php artisan migrate
 
## Run the test suite
vendor/bin/phpunit


首先,该脚本会尝试连接到数据库。Codeship软件会自动启动应用程序容器和数据库容器,但MySQL初始化需要几秒,所以必须重试该test_database()功能,直到成功连接数据库(或尝试100次)。这在Codeship的Docker文档中有更详细的概述。


一旦脚本能连接到数据库,它将创建默认数据库(数据库名为laravel)。然后会运行迁移,通过PHPUnit创建数据库表和测试套件。


最后,为了测试配置正常运行和且结果通过,用Jet来运行所有步骤:


$ jet steps


如果一切正常,那么在构建容器镜像过程中,会看到一堆输出,运行返回一条成功消息:


{ContainerRunStdout


    
=step_name:"serial_bash_docker/codeship-run.sh" service_name:"app"}: PHPUnit 5.7.19 by Sebastian Bergmann and contributors.
{ContainerRunStdout=step_name:"serial_bash_docker/codeship-run.sh" service_name:"app"}:.                                                                   1/1(100%)
 
Time:1.09 seconds, Memory:12.00MB
 
OK (1test,1 assertion)
{StepFinished=step_name:"serial_bash_docker/codeship-run.sh"type:


    
STEP_FINISHED_TYPE_SUCCESS}
$


  • 将仓库连接到Codeship


如果尚未提交本地代码到GitHub或Bitbucket上。每次提交代码更改时,Codeship都自动会从私有或公共仓库中拉取代码,所以只需要设置Codeship去监视那个仓库。


在Codeship中创建一个新项目,并将其连接到仓库:



跳出提示框时,选择Codeship Pro做为项目类型。



现在项目已经链接到Codeship。下次提交代码时,Codeship将会编译且使用与本地相同的codeship-steps.yml来运行。此时唯一的问题是使用本地的 .env文件,此文件不会提交到代码仓库,不过有个简单方法来设置环境变量且又不会影响安全性。


  • 加密环境变量


因为最好的做法是不要将.env文件推送到持续集成服务器,所以需要提出一种安全地将变量传递给Codeship方法——加密.env文件


首先,在Codeship找到AES密钥(通常位于项目设置的常规页面中),并将其放在一个名为 codeship.aes的本地根目录文件中。不要忘记将此文件添加到.gitignore,因为它是不应共享的密钥:



下一步,更新codeship-services.yml文件,让其使用加密的.env文件,而非明文.env文件


version:"2.0"
services:
  # PHP Application
  app:
    build: .
    links:
      - database
    encrypted_env_file: .env.encrypted
    command: cron -f
  # Database
  database:
    image: mariadb
    encrypted_env_file: .env.encrypted
  # Composer
  composer:
    image: composer/composer
    volumes:
      - ./:/app


使用Jet将.env文件加密成.env.encrypted,将加密后的.env.encrypted文件提交到软件仓库,然后将其推送到远程仓库:


$ jet encrypt .env.env.encrypted
$ git add -A &&git commit -am "Adding codeship config"
$ git push origin


Codeship正在编译代码:



也可以点击进去,查看编译详细过程和每个步骤:



如果上述都无误地执行,最后会看到一个成功的编译结果:



自动部署


虽然持续集成服务会让人知道编译和测试是否通过,但使用Codeship更大的价值在于自动化部署过程,为了做到这一点,需要做几件事情:


  • 在服务器上手动配置和部署代码库

  • 服务器上有一个SSH密钥,允许从代码库拉取代码

  • 服务器上有一个脚本,用来更新代码并重新启动容器


准备齐全后,就可以构建一个部署者容器,其工作就是在编译过程结束后,登陆到SSH服务器中,运行更新脚本。


这只是利用容器来部署代码的一种方法,也许并不是最佳的方法。另一个选择是使用Docker Hub等容器仓库来编译,然后直接从Docker Hub那里更新容器。Docker在生产中的最佳做法仍在探索中,这种方法更适用也相对简单。

  • 首次手动部署代码


此步骤根据主机服务提供商而有所不同,但只要服务器满足安装了Git,Docker和Docker Compose就可以。SSH登陆服务器:


  • 创建一个新的SSH密钥

  • 赋予SSH密钥可以从代码库读取访问

  • 克隆代码库

  • 设置.env文件,使用一个新的APP_KEY和数据库密码

  • 使用docker-compose up -d –build 命令来制作镜像,并且运行容器


现在可以运行docker ps查看,当第一次在本地配置好这个项目时,可以看到同样的两个容器在运行。


  • 添加脚本更新服务器代码


现在在本地版本的代码中,添加一个shell脚本,该脚本将从仓库中获取更新的代码,并重启容器:


#!/usr/bin/env bash
 
## Pull the latest code
git pull origin master
 
## Rebuild the containers
docker-compose up -d --build
 
## Run migrations
docker exec


    
 dockerphpcliexample_app_1 php artisan migrate --force



文件名叫deploy.sh 位于docker/文件夹中。


此时,要确保文件位于服务器上,因此提交代码到代码库,又将其从服务器中拉出。通过在服务器上运行命令: $ bash docker/deploy.sh ,并确保容器仍然工作。


  • 创建一个部署者容器


综上所述,在编译和测试结束后,现在需要一个容器在Codeship的CI服务器远程运行此部署脚本。在仓库中创建一个名为deployer/ 的新目录,里面包含 Dockerfile文件,.env文件和execute.sh文件。


Dockerfile:


FROM alpine:latest
 
# Install openssh
RUN apk update && apk add openssh
 
# Prep for the ssh key
RUN mkdir-p "$HOME/.ssh"
RUN touch$HOME/.ssh/id_rsa
RUN chmod600$HOME/.ssh/id_rsa
 
# Add the shell script
COPY execute.sh execute.sh
 
CMD sh execute.sh


.env:


USER=<SERVER_SSH_USERNAME>



    
HOST=<SERVER_HOST>
PRIVATE_SSH_KEY=<SSH_KEY (with linebreaks replaced with `\n`)>


execute.sh:


#!/usr/bin/env bash
echo-e $PRIVATE_SSH_KEY>>$HOME/.ssh/id_rsa
ssh-t -oStrictHostKeyChecking=no $USER@$HOST"cd docker-php-cli-example && sh docker/deploy.sh"


这个容器将使用.env文件中的环境变量,SSH登陆到服务器运行部署脚本。


  • 让Codeship Pro运行部署者容器


为了让Codeship知道部署者容器,把它添加到 codeship-services.yml文件中:


# Deployer
  deployer:
    build: ./deployer
    encrypted_env_file: deployer/.env.encrypted


codeship-steps.yml 文件:


-service: deployer
    command: sh execute.sh


加密deployer/.env 文件,这样可以提交到代码库,并且不会暴露服务器的SSH密钥。正如对主代码库那样,用jet来加密.env文件:


$ jet encrypt deployer


    
/.env deployer/.env.encrypted


最后,把更新的代码推到github仓库,确保Codeship成功地编译和部署了代码:



原文地址:  https://blog.codeship.com/adding-ci-and-cd-to-a-php-command-line-app-with-docker/


本文转载自数人云

ID:dmesos




相关阅读:

高端私有云项目交流群,欢迎加入!

加入中国最活跃的kubernetes技术讨论QQ群,加群主QQ:502207183,并注明城市、行业、技术方向。




今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/amP9ezMWPv
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/2523
 
952 次点击