Tutorial - Automatic deploy from Gitlab CI to own virtual private server (VPS)

May 23, 2021

main Source: https://www.youtube.com/watch?v=pChVWAVY7RU

Generate SSH keys on VPS

  • login to VPS via SSH
  • cd ~/.ssh
  • key-gen (without a password)
  • cat id_rsa.pub >> ~/.ssh/authorized_keys
  • open private key file (e.g. cat id_rsa) and save it on your local machine.

Create an application that can be containerized with docker

  • for example with angular ng new deployment-test
  • create a Dockerfile in the root of the project for example like this

    FROM node:14.15.1 as build
    WORKDIR /app
    COPY . .
    RUN npm ci
    RUN npm run build:frontend:fifa-presentation
    
    FROM nginx:1.19.2-alpine as deploy
    RUN apk --no-cache add bash=~5.0
    COPY nginx.conf /etc/nginx/nginx.conf
    WORKDIR /usr/share/nginx
    COPY --from=build /app/dist/apps/fifa ./html
  • I personally use the following nginx.conf

    worker_processes  1;
    
    events {
        worker_connections  1024;
    }
    
    http {
        server {
            listen 80;
            server_name  localhost;
    
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            include /etc/nginx/mime.types;
    
            gzip on;
            gzip_min_length 1000;
            gzip_proxied expired no-cache no-store private auth;
            gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
            location / {
                try_files $uri $uri/ /index.html;
            }
        }
    }
  • setup Gitlab-repo
  • push your code to gitlab

Enable settings for Deployment in Gitlab

  • in the root-view of your repo, goto Settings -> Repository
  • expand Section Deploy tokens
  • insert gitlab-deploy-token as Name
  • check read_registry checkbox
  • goto Settings -> CI/CD
  • expand Variable section
  • you need to create two variables and one file
  • Press Add Variable, Key: MASTER_HOST, Value: the IP-Adress of your VPS, Press Add Variable
  • Press Add Variable, Key: MASTER_SSH_USER, Value: the user for whom you created the ssh key (e.g. root), Press Add Variable
  • Press Add Variable, Key: MASTER_SSH_KEY, Value: your private SSH key that you created and saved to your local machine in the first step

    1. :warning: you must alter the type field to File, then press Add Variable

Create Gitlab CI file

  • go into the root folder of your project
  • create gitlab-ci.yml
  • we need to define two stages

    • build (build the dockerfile)
    • deploy (move it to the server and serve it there)
  • the gitlab-ci.yml-configuration that I prefer looks like this

    stages:
    - build
    - deploy
    
    build:
        before_script:
            - 'docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY'
        image: 'docker:latest'
        script:
            - 'docker image build --tag registry.gitlab.com/<your-username>/<the-name-of-your-gitlab-repo>/<tag>:latest .'
            - 'docker push registry.gitlab.com/<your-username>/<the-name-of-your-gitlab-repo>/<tag>:latest'
        services:
            - 'docker:dind'
        stage: build
    
    deploy:
        image: kroniak/ssh-client
        stage: deploy
        script:
            - chmod 400 $MASTER_SSH_KEY
            # Login to Gitlab Container registry
            - ssh -o StrictHostKeyChecking=no -i $MASTER_SSH_KEY "${MASTER_SSH_USER}@${MASTER_HOST}" "docker login -u ${CI_DEPLOY_USER} -p ${CI_DEPLOY_PASSWORD} ${CI_REGISTRY}"
            - ssh -o StrictHostKeyChecking=no -i $MASTER_SSH_KEY "${MASTER_SSH_USER}@${MASTER_HOST}"'cd <directory-on-your-server-that-contains-a-docker-compose-file> && docker pull registry.gitlab.com/<your-username>/<the-name-of-your-gitlab-repo>/<tag>:latest && docker-compose up -d'