I’ve decided to move my server from DigitalOcean to Scaleway. The reason for this is mainly because of the pricing. Even though DigitalOcean is not expensive, Scaleway is much cheaper and I’m getting more in return.

Pricing & Specs

The main initiative for moving was pricing.

I was paying $10/month at DigitalOcean for this VPS:

CPU: Intel(R) Xeon(R) CPU E5-2630L v2 @ 2.40GHz (Single Core)

Memory: 1 GB

Hard Drive: 30 GB SSD

Bandwidth: 2 TB

I am now paying $3.35/month at Scaleway for this VPS:

CPU: Intel(R) Atom(TM) CPU C2750 @ 2.40GHz (Dual Core)

Memory: 2 GB

Hard Drive: 50 GB SSD

Bandwidth: Unlimited

That’s almost 3 times cheaper for a more powerful setup!

Moving all of my services was a bit of a hassle. I am running many services, e.g. Apache, Nginx, MySQL, PostgreSQL, ZNC, GitLab CE, Postfix, etc. and moving them and all of their data took a lot of time and effort. I read about others having this issue and there I saw mentioned Docker.

Docker to the rescue!

I decided to read up on Docker and experiment with it. The thought of the ability to move a single image to a new server and running it in the previous state, was too good to be true. My decision to experiment with Docker was to make moving to new servers easier in the future, and would ease scaling the infrastructure if needed. Also everything is in its isolated environment and I don’t need to pollute the host.

Learning Docker was a lot of trial and error. I first tried to make my own Dockerfiles for everything with a Ubuntu base image, adding apt-get install and my own ENTRYPOINT‘s and CMD‘s for running the services, but that was hard and cumbersome. The hardest part was getting the container’s services to start correctly and stop gracefully. So I decided to start with official vendor images. That made things easier.

Docker Volumes

Docker volumes are basically directory mounts in the container. I had a bit of a hard time understanding volumes in Docker at the beginning, how they worked and how they were reused. One of my image had a volume defined but when I ran a container for that image, it created a new directory hash under /var/lib/docker/volumes/. So when I ran a new container with the same image, it created another directory hash and all of my previous data was gone. Then I stumbled upon named volumes. That surely made my life easier.

I learned the hard way there are four types of volumes in Docker:

1. Regular volumes

docker run -v /data

This volume is stored under a random directory, something like /var/lib/docker/volumes/1fd1d58792db3e133d4f854481a1f1104f84d7c819e3f30ec10d63249b7fb820 on the host and under /data in the container.

This volume is not persisted between container instances of an image!

2. Named volumes

docker run -v some-data:/data

This volume is stored under /var/lib/docker/volumes/some-data/ on the host and under /data in the container. This is the best option in my opinion and is the volume type I use for all volumes in my containers.

This volume is persisted between container instances of an image!

3. Host volumes

docker run -v /some-data:/data

This volume is stored under /some-data on the host and under /data in the container.

This volume is persisted between container instances of an image!

4. Data volume containers

docker run --volumes-from <container_with_volume>

The container uses the volumes defined in the other container. This is the most recommended way by Docker experts, but for small servers I think this adds unnecessary complexity and choose to use named volumes.

This volume is persisted between container instances of an image!

My Docker containers

As of now I have 5 running Docker containers based on official vendor images. For all of them I use unless-stopped restart-policy, so they are always started on boot if they were previously in a running state. Some of them are linked together, so they can communicate with each other. For example the Apache container is linked with the MySQL, PostgreSQL and GitLab containers and the GitLab container is linked with the PostgreSQL container.

The run commands for the containers are the following:

-- MariaDB

docker run --name mysql-server --restart=unless-stopped -d -e MYSQL_ROOT_PASSWORD=<pass> -p 3306:3306 -v mysql:/var/lib/mysql/ gaui/mariadb

-- PostgreSQL

docker run --name postgres-server --restart=unless-stopped -d -e POSTGRES_PASSWORD=<pass> -p 5432:5432 -v postgresql:/var/lib/postgresql/data/ gaui/postgres

-- GitLab

docker run --name gitlab --restart=unless-stopped -d -p 1380:80 -p 1322:22 -v gitlab-conf:/etc/gitlab/ -v gitlab-logs:/var/log/gitlab/ -v gitlab-data:/var/opt/gitlab/ --link postgres-server gitlab/gitlab-ce:latest

-- Apache2 + PHP 5.6

docker run --name apache-server --restart=unless-stopped -d -p 80:80 -p 443:443 -v /home/gaui/public_html/:/home/gaui/public_html/ -v apache2-conf:/etc/apache2/ -v apache2-www:/var/www/ --link mysql-server --link postgres-server --link gitlab gaui/apache2-php5.6

-- ZNC

docker run --name znc-server --restart=unless-stopped -d -p 31337:6667 -v znc-data:/znc-data/ gaui/znc

I’m really starting to love the Docker life!