简体   繁体   中英

Build and deploy with Gitlab CI?

I have a Dockerized Angular/Node.js app that I'm trying to deploy via GitLab CI.

Using GitLab CI, I build and push the images to the GitLab container registry using a dedicated build VM/server with a Runner on it, and then the images should be pulled and started as containers in another server, ie the production server.

This is what my gitlab-ci.yml file looks like right now:

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
  • The problem is, the docker commands seem to get executed on the build server (instead of the production server where we ssh ) and the app is accessible from there but not from the production server.

  • When I run docker images on the production server after the deployment, the list comes up empty. But when I do that in the build server, the images that were built are there.

  • The job seems to complete successfully with no error messages, but I do get these messages:

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

What am I missing or doing wrong?

after taking a look at your ci code, you should use ansible when you want to run your container on the production server.

Ansible is better than

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

I can share with you my ansible file 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 }}"

And gitlab ci file .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

Finally hosts

[local]
127.0.0.1 env=prod

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

Like fei yang I too recommend replace ssh command by ansible .


I think that problem can be there:

ssh $SERVER_USERNAME@$SERVER_IP_ADDRESS && ip addr show

In my computer I can run:

curl ipinfo.io

and get:

{
  "ip": "193.118.225.242"
...

Then I typed:

ssh root@104.248.40.145 && curl ipinfo.io

I see:

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

I am logged in to server and I can't see resutls of ipinfo

When I typed

exit

to logout from remote server I can see:

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

To execute command remotelly by ssh you should not use && but "" eg.

ssh root@104.248.40.145 "curl ipinfo.io"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM