我想做的是,在构建完成后,使用SSH部署应用程序。有时这可能只是通过SSH将最终构建的内容(PHP文件)上传到服务器,而其他时间则可能是上传已编译的.jar文件,然后在远程服务器上执行命令以重新启动服务。
我已经设置了自己的Docker容器作为构建环境,其中包括Java、PHP、Composer和Maven等所有需要完成构建的东西。我使用这个镜像来运行构建。
我想知道的是,如何通过SSH进入外部服务器以执行我可以在gitlab-ci.yaml文件中指定的部署命令?
举个例子,假设您已经安装了所需的服务器,并希望使用ssh将其部署到该服务器上。
image: ubuntu:latest
stages:
- deploy
deploy_QA:
stage: deploy
environment:
name: Staging
url: "$QA_URL"
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ssh-add <(echo "$PRIVATE_KEY")
- ssh -o StrictHostKeyChecking=no user@"$QA_SERVER" 'rm -rf /var/www/html/*'
- scp -P22 -r . ubuntu@"$QA_SERVER":/var/www/html
首先,在这个例子中,我们使用的是Ubuntu镜像。同时请注意我们使用了一些GitLab的秘密变量。$QA_URL,$PRIVATE_KEY,$DB_CONNECTION,$QA_SERVER。其中最重要的是$PRIVATE_KEY和$QA_SERVER。私钥是您需要用来验证QA_SERVER身份的(如果您正在使用私钥)。而QA_SERVER显然是您想要部署代码的地址。
要创建新的变量,请访问GitLab->设置->CI/CD。
在before_script中,我们正在创建并添加SSH密钥,同时禁用命令行请求密码。'StrictHostKeyChecking no'
ssh-add <(echo "$PRIVATE_KEY")
将ssh密钥添加到代理。
ssh -o StrictHostKeyChecking=no user@"$QA_SERVER" 'rm -rf /var/www/html/*'
不需要:这一行使用ssh删除/var/www/html目录下的任何文件 scp -P22 -r . ubuntu@"$QA_SERVER":/var/www/html 最后,将文件从当前目录复制到/var/www/html
注意权限,这取决于您要复制的目录。
在gitlab.com上处理ssh并不是一件简单的事情。
所以我写了一个.gitlab-ci.yml文件的SSH助手。
你可以在这里查看:https://gitlab.com/gitlab-cd/ssh-template
只需要将它包含(include)到你的.gitlab-ci.yml文件中,然后你就可以使用以下命令:
ssh_run root myhostname $MYHOST_PKEY "touch foo; cp foo bar; ls -al; rm foo bar; ls -al"
使用镜像。在设置 -> 存储库 -> 镜像存储库
下。
它会生成一个ssh公钥,您应该将其放置在您的服务器上。
您可以选择方向(拉或推),以及拉取或推送哪些分支。还等待管道。
非常出色。
另一个重要的事情是屏蔽相关包含SSH私钥的GitLab变量。
由于某种原因,GitLab不允许我们直接这样做。在粘贴密钥后,屏蔽它的选项变得不可能。
关于此问题,GitLab有一个公开的问题: https://gitlab.com/gitlab-org/gitlab/-/issues/220187
可能的解决方法: Gitlab masking variables
只需使用base64 -w0
选项对SSH私钥进行编码,然后将编码的SSH密钥添加到GitLab变量值中。之后,您可以像这样连接到远程服务器,而密钥不会被暴露(这并不正确)。
echo "${ENCODED_PRIVATE_KEY}" | base64 -d | ssh-add - > /dev/null
更新:不幸的是,GitLab没有掩盖解码后的掩码变量。在使用SSH密钥时,请考虑这一点。
我有一个使用SSH部署的例子,希望能帮到你。
首先,在服务器上配置SSH密钥,生成一个密钥(https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/),并将公钥粘贴到用户主目录下的".ssh/authorized_keys"文件中。
仍然在服务器上,编辑文件"/etc/ssh/sshd_config"。
找到它:
AcceptEnv LANG LC_*
替换为:
AcceptEnv LANG LC_* CI_*
这将使服务器使用 Git-Lab 变量
之后,我建议您将公钥和服务器地址存储在 GitLab CI 变量中(https://docs.gitlab.com/ee/ci/variables/#protected-cicd-variables)
声明变量后,只需基于下面的 gitlab-ci.yml 进行操作:
Deploy:
stage: Deploy
image: dwdraju/ssh-client-alpine
before_script:
- mkdir -p ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n SendEnv CI_* \n" > ~/.ssh/config
- echo -n $SSH_PRIVATE_KEY > ~/.ssh/id_rsa
- chmod 700 ~/.ssh
- chmod 600 ~/.ssh/id_rsa
script:
- ssh $SSH_HOST 'echo $CI_PROJECT_NAME'
sshpass -p "pwd" ssh -t -t usr@x.x.x.x "if exist service.bat ( nssm restart spring-app & exit ) else ( echo 'java -jar spring-app-1.1.jar' > service.bat ) && nssm install spring-app 'C:\Users\user\Documents\gitlab_ci\spring-app\service.bat' && nssm start spring-app && exit"
请协助。 - DaviesTobi alex