Automatic Deployment of Docker Containers to AWS EC2 Using GitLab

Kim Rinnewitz
plapadoo
Published in
2 min readDec 16, 2019

For our game reaktron, we are running a server infrastructure on AWS. While the actual server for a each match is started on demand, one of the servers, the so-called “Matchmaking Server”, has to be up and running 24/7.

We decided to use AWS Fargate for the short-lived game servers, but to operate an “always-on” EC2 instance for the matchmaking server, which is much cheaper than just running a Fargate container 24/7.

This article explains how we utilize GitLab and EC2 to automatically deploy the Matchmaking Server.

What the EC2 instance does

Since the Matchmaking Server is wrapped in a Docker image, the EC2 instance needs a Docker daemon to run the container. Also, we want to have the latest system updates applied to the EC2 instance. To achieve all of this, we are using the following cloud config which defines what the EC2 instance should do when started:

#cloud-config
cloud_final_modules:
- [scripts-user, always]
repo_update: true
repo_upgrade: all
package_upgrade: true
packages:
- docker

When the EC2 instance starts up, it will apply the latest system updates and install Docker. The cloud config continues with:

runcmd:
- sudo mkdir /root/.aws
- echo -e "$HOST_MATCHMAKING_CREDENTIALS" | sudo tee /root/.aws/credentials
- sudo chown 400 /root/.aws/credentials
- sudo systemctl start docker
- sudo sh -c '$(aws ecr get-login --no-include-email --region $MATCHMAKING_REGION)'
- sudo docker rm -f reaktron-matchmaking-prod || true
- sudo docker rmi -f $HOST_REGISTRY_AWS/reaktron-matchmaking:prod || true
- sudo docker run --publish $PORT_PROD:$PORT_PROD/tcp -name=reaktron-matchmaking-prod --env REAKTRON_MATCHMAKING_BIND_PORT=$PORT_PROD --env REAKTRON_STACK=prod --restart=always --detach $HOST_REGISTRY_AWS/reaktron-matchmaking:prod

This script performs the main part of the actual deployment. First, it writes AWS credentials into /root. These are necessary to access the Amazon ECR Docker registry which contains the image with the Matchmaking Server. After starting the Docker daemon and logging in to the ECR registry, any old containers and images are removed. Finally, the new container is started.

What GitLab does

In GitLab, we use GitLab CI to build the Matchmaking Server’s Docker image and push it to the ECR registry. Once this is done, the GitLab CI job restarts the EC2 instance by running the following script:

#!/usr/bin/env bashINSTANCE_ID=`AWS_SHARED_CREDENTIALS_FILE=$CREDENTIALS_RUNNER aws ec2 describe-instances --region $MATCHMAKING_REGION | jq --raw-output ".Reservations[0].Instances[0].InstanceId"`
echo "Restarting ec2 instance $INSTANCE_ID"
AWS_SHARED_CREDENTIALS_FILE=$CREDENTIALS_RUNNER aws ec2 reboot-instances --instance-ids $INSTANCE_ID --region $MATCHMAKING_REGION

As soon as the EC2 instance is fully started, the latest version of the Matchmaking Server is live.

--

--