Gitlab CI 如何通过 SSH 部署应用程序

35
我正在使用托管的Gitlab来托管我的Git存储库,最近我一直在使用它来构建/部署PHP和Java应用程序到服务器。
我想做的是,在构建完成后,使用SSH部署应用程序。有时这可能只是通过SSH将最终构建的内容(PHP文件)上传到服务器,而其他时间则可能是上传已编译的.jar文件,然后在远程服务器上执行命令以重新启动服务。
我已经设置了自己的Docker容器作为构建环境,其中包括Java、PHP、Composer和Maven等所有需要完成构建的东西。我使用这个镜像来运行构建。
我想知道的是,如何通过SSH进入外部服务器以执行我可以在gitlab-ci.yaml文件中指定的部署命令?
6个回答

44

您可以将SSH密钥作为一个秘密变量存储在gitlab-ci.yaml中,并在构建过程中使用它来执行SSH命令。有关详细信息,请参阅我们的文档此处

一旦您获得了SSH访问权限,您就可以使用诸如rsyncscp之类的命令将文件复制到服务器上。我在另一篇帖子中找到了一个示例此处,您可以用作参考。


3
你能否简要概括一下这篇文章,以防页面失效? - tutuca
1
嗨,我已经成功将我的jar文件复制到远程服务器,但我面临的问题是ssh登录到远程服务器并运行Spring应用程序。我尝试了以下命令: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
1
@Adam-Mulvany,恕我直言,第一个链接在用通俗易懂的语言解释“为什么”和“如何”方面做得非常糟糕。而且对我来说它并不起作用——我得到了一个退出状态码1,但没有任何解释。我认为人们不应该被要求开发额外的专业知识才能让GitLab CI/CD执行一些简单的操作。如果我们已经有一个共享的ssh密钥来将东西从服务器推送到Gitlab,为什么我们还需要做这么多工作才能让Gitlab发送命令来运行我们的服务器?大部分部署代码都是基本的复制和锁定文件。谢谢。 - user7969724
1
第一个链接无法打开 - siiraaj
你的第一个链接已经变了。请把你的第一个链接更新为这个链接:https://docs.gitlab.com/ee/ci/ssh_keys/ - Pixelbog

11

举个例子,假设您已经安装了所需的服务器,并希望使用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

注意权限,这取决于您要复制的目录。


2
Johan,不清楚PRIVATE_KEY是在哪里生成的,对应的PUBLIC KEY存储在哪里?我猜管理员登录QA_SERVER并生成密钥对,将私钥复制粘贴到gitlab的PRIVATE_KEY变量中。 - ace
1
@ace 没错,首先我们必须按照正常的ssh密钥生成步骤,将公钥放在服务器上,然后将私钥复制到gitlab变量中。在我的教程视频中,我谈到了仅使用shh进行CI的内容Gitlab CI/CD Tutorial, Pain SSH(对于这个问题,请参考第7分钟之后的内容)。关于Gitlab,因为SSH密钥生成与平常一样。 - Johan Durán

6

在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"


1

使用镜像。在设置 -> 存储库 -> 镜像存储库下。

它会生成一个ssh公钥,您应该将其放置在您的服务器上。

您可以选择方向(拉或推),以及拉取或推送哪些分支。还等待管道。

非常出色。


1
这太棒了,谢谢你。另一个优点是它不会在Gitlab管道上使用任何时间。 - bfontaine

0

另一个重要的事情是屏蔽相关包含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密钥时,请考虑这一点。


0

我有一个使用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'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接