Automate Docker deployment with Gitlab

Automate Docker deployment with Gitlab
Going to deploy single Docker container to remote server.
Good for all sorts of small projects and pages, like this blog :)


Create .gitlab-ci.yml file in project root

# Setup 2 steps:
#   dockerize Build container
#   deploy    Deploy to remote server
  - dockerize
  - deploy
  stage: dockerize
  image: docker
  # Run this step only when code is pushed into master branch.
  # Might want to make it "tags" to dockerize only releases
    - master
  # Use Docker in Docker service, to build Docker in Docker
    - docker:dind
    # Login to Gitlab Docker registry using built-in variables
    - docker login
      -u "$CI_REGISTRY_USER"
	# About Nginx static files Dockerfile setup: 
    # Build it! Name will be project_name:branch_name
    - docker build --pull -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG .
    # Push freshly built image to Gitlab registry

  stage: deploy
  # Use this as base image to get small SSH container
  image: instrumentisto/rsync-ssh
    - master
    # Add key, it needs to be set up as pipeline variable
    - eval $(ssh-agent -s)
    - echo "$DEPLOYER_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    # Remove known hosts check
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    # Explained down below
    - ssh -t [email protected] "docker login -u "$CI_DEPLOY_USER" -p "$CI_DEPLOY_PASSWORD" $CI_REGISTRY &&
      docker stop example-name; docker rm example-name;
      docker run -d -p 31227:80 --name example-name $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"

Deploy script explained line by line

# SSH into server, run last argument as command and disconnect
ssh -t [email protected] ""
# From remote server login into Gitlab registry
# how to get and setup deploy tokens
# Pull new Docker image
# Stop and remove existing container, use ";" instead of &&
# since server does not have this container when deploying first time
docker stop example-name; docker rm example-name;
# Start container in background, expose port 80 to 31227 and name it
docker run -d -p 31227:80 --name example-name $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"

Basic Nginx server block for web services

Really basic server block is needed to proxy traffic to Docker container

Location of it is based on your host operating system. For most Debian based OSes it is /etc/nginx/sites_available/ and linked to /etc/nginx/sites_enabled/

For OpenSUSE it is /etc/nginx/vhosts.d/

server {

    location ~ / {
        # Add headers, so application knows it is behind proxy
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        # Proxy to container. Port must be same as in deploy script

It does not do any GZIP / caching / certing etc. But it is really easy to enable, based on server block on host machine.

Will write another short post about it in future