使用Gitlab CI进行构建和部署?

时间:2020-04-17 21:11:16

标签: docker continuous-integration gitlab

我有一个要通过GitLab CI进行部署的Dockerized Angular / Node.js应用程序。

我使用GitLab CI,使用带有Runner的专用构建VM /服务器来构建映像并将其推送到GitLab容器注册表,然后应在其他服务器(即生产服务器)中将图像作为容器拉出并启动。

这是我的gitlab-ci.yml文件现在的样子:

image: docker:latest

#services:
#    - docker:dind

stages:
    - build
    - deploy

build-1:
    stage: build
    only:
        - deploy
    script:
        - docker login -u $GITLAB_USERNAME -p $CI_ACCESS_TOKEN $CI_REGISTRY
        - docker build -t $FRONTEND_IMG .
        - echo Pushing Docker image to GitLab
        - docker push $FRONTEND_IMG
    when: manual
    tags:
        - my-runner

build-2:
  stage: build
  only:
    - deploy
  script:
    - docker login -u $GITLAB_USERNAME -p $CI_ACCESS_TOKEN $CI_REGISTRY
    - docker build -t $BACKEND_IMG .
    - docker push $BACKEND_IMG
  when: manual
  tags:
    - my-runner

deploy-live:
    stage: deploy
    only:
        - deploy
    before_script:
        ## Install ssh-agent if not already installed, it is required by Docker.
        ## (change apt-get to yum if you use an RPM-based image)
        ##
        - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'

        ##
        ## Run ssh-agent (inside the build environment)
        ##
        - eval $(ssh-agent -s)

        ##
        ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
        ## We're using tr to fix line endings which makes ed25519 keys work
        ## without extra base64 encoding.
        ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
        ##
        - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -

        ##
        ## Create the SSH directory and give it the right permissions
        ##
        - mkdir -p ~/.ssh
        - chmod 700 ~/.ssh

        # - mkdir -p ~/.ssh && touch ~/.ssh/known_hosts
        # - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
        ##
        ## Use ssh-keyscan to scan the keys of your private server. Replace gitlab.com
        ## with your own domain name. You can copy and repeat that command if you have
        ## more than one server to connect to.
        ##
        - ssh-keyscan $SERVER_IP_ADDRESS >> ~/.ssh/known_hosts
        - chmod 644 ~/.ssh/known_hosts
    script:
        - echo SSH to prod server
        - ssh $SERVER_USERNAME@$SERVER_IP_ADDRESS && ip addr show && docker login -u $GITLAB_USERNAME -p $CI_ACCESS_TOKEN $CI_REGISTRY && docker pull $FRONTEND_IMG && docker pull $BACKEND_IMG && docker-compose -f docker-compose.yml up -d
    when: manual
    tags:
        - my-runner
  • 问题是,docker命令似乎在构建服务器上执行(而不是在我们的ssh生产服务器上),并且可以从那里访问应用程序,但不能从生产服务器上访问该应用程序。

  • 在部署后在生产服务器上运行docker images时,该列表显示为空。但是,当我在构建服务器中执行此操作时,已构建的图像就在其中。

  • 该作业似乎成功完成,没有任何错误消息,但我确实收到了以下消息:

Pseudo-terminal will not be allocated because stdin is not a terminal.

Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-66-generic x86_64)
  * Documentation:  https://help.ubuntu.com
  * Management:     https://landscape.canonical.com
  * Support:        https://ubuntu.com/advantage
   System information as of Wed Apr 15 00:58:45 UTC 2020
   System load:  0.0               Processes:              110
   Usage of /:   6.0% of 24.06GB   Users logged in:        2
   Memory usage: 26%               IP address for eth0:    x.x.x.x
   Swap usage:   0%                IP address for docker0: x.x.x.x
 121 packages can be updated.
 73 updates are security updates.
 mesg: ttyname failed: Inappropriate ioctl for device

我想念什么或做错什么了?

2 个答案:

答案 0 :(得分:1)

在查看您的 ci 代码后,当您想在生产服务器上运行容器时,您应该使用 ansible

Ansible 优于

ssh myserver "command1 && command2 &&....."

答案 1 :(得分:0)

我可以与您分享我的 ansible 文件 deploy.yml

# https://stackoverflow.com/questions/59384708/ansible-returns-with-failed-to-import-the-required-python-library-docker-sdk-f/65495769#65495769
---
- name: Build
  hosts: local
  connection: local
  tags:
    - build
  tasks:
    - name: Build Image
      community.general.docker_image:
        build:
          path: .
          pull: no
        name: registry.digitalocean.com/main/example-com
        push: true
        source: build
        force_source: yes
      environment:
        DOCKER_BUILDKIT: 1
- name: Deploy
  hosts: remote
  tags:
    - deploy
  vars:
    path: /root/example.com
  tasks:
    - name: Creates directory
      file:
        path: "{{ path }}"
        state: directory
    - name: Copy Docker Compose
      copy:
        src: docker-compose.yml
        dest: "{{ path }}/docker-compose.yml"
    - name: Reload Compose
      community.general.docker_compose:
        pull: yes
        project_src: "{{ path }}"

和 gitlab ci 文件 .gitlab-ci.yml

variables:
  DOCKER_REGISTRY_DOMAIN: "registry.digitalocean.com"
  DOCKER_HOST: tcp://docker:2375
  DOCKER_TLS_CERTDIR: ""
  DOCKER_DRIVER: overlay2

image: docker:latest

services:
  - docker:dind

.deploy:
  image: archlinux:latest
  stage: deploy
  before_script:
    - pacman -Sy make ansible python python-pip openssh docker --noconfirm
    - docker login -u ${DOCKER_TOKEN} -p ${DOCKER_TOKEN} ${DOCKER_REGISTRY_DOMAIN}
    - pip3 install docker docker-compose
    - eval $(ssh-agent -s)
    - ssh-add <(echo $SSH_PRIVATE_KEY_BASE64 | base64 -d)
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - ansible-playbook -i hosts deploy.yml

deploy:
  extends: .deploy
  environment:
    name: production
    url: https://example.com
  only:
    refs:
      - prod

终于hosts

[local]
127.0.0.1 env=prod

[remote]
xxx.xxx.xxx ansible_user=root env=prod

fei yang 一样,我也建议将 ssh 命令替换为 ansible


我认为可能存在这个问题:

ssh $SERVER_USERNAME@$SERVER_IP_ADDRESS && ip addr show

在我的电脑上我可以运行:

curl ipinfo.io

并得到:

{
  "ip": "193.118.225.242"
...

然后我输入:

ssh root@104.248.40.145 && curl ipinfo.io

我明白了:

Last login: Thu Jun 17 07:53:38 2021 from 193.118.225.242

我已登录到服务器,但看不到 ipinfo

的结果

当我打字时

exit

从远程服务器注销我可以看到:

logout
Connection to 104.248.40.145 closed.
{
  "ip": "193.118.225.242",

要通过 ssh 远程执行命令,您不应使用 && 而应使用 "" 例如。

ssh root@104.248.40.145 "curl ipinfo.io"