Skip to content

Deploy FreeCC to AWS

Anjia Wang edited this page Jun 9, 2020 · 88 revisions

1. Introduction

Before you get started, you may want to quickly review the important concepts involved in deploying this system since many different technologies are invovled. All the technical jargons can be very confusing to beginners.

Also, since FreeCC is a customization of the official Play-with-docker pakcage (PWD). You may want to gain some experiences of installating PWD on a local machine first (this is simpler) before trying out FreeCC on an AWS instance (which is more complex).

FreeCompilerCamp (FreeCC) is composed of two parts, both are dockerized:

  • the compiler classroom web server that contains the text tutorials and
  • the Play-With-Compiler (PWC) server that contains the sandbox for users.

The classroom website is hosted using GitPages and Jekyll.

The PWC server is hosted by a composite container on port 5010:3000 (external port:internal port). It's composed of three docker images

  • haproxy: the portal web site,
  • l2: after login, the users will see this web interface to start and manage sessions, and to show a terminal
  • pwd: the actual docker-in-docker terminal container
  • The source code of the PWC is hosted at https://github.com/freeCompilerCamp/play-with-compiler

HAProxy is free, open source software that provides a high availability load balancer and proxy server for TCP and HTTP-based applications that spreads requests across multiple servers. It is written in C and has a reputation for being fast and efficient.

2. Prerequisite

An Instance on AWS

With the following configuration

  • OS: Ubuntu 18.04
  • t2.xlarge, more cpus/memory, better, if you can afford it
  • 20 GB SSD, more is better
  • Network Security group: open ssh (22), http (80), https(443) and one more Custom TCP ports 5010 for inbound traffic

Read more about how to configure the network security group and assign your instance's network settings to use it:

Enable kernel modules:

sudo modprobe overlay
sudo modprobe xt_ipvs

Overlay filesystem allows one, usually read-write, directory tree to be overlaid onto another, read-only directory tree. All modifications go to the upper, writable layer.

You can run the following command to check if the required modules are loaded

lsmod | grep overlay
lsmod | grep xt_ipvs

You can add two lines into /etc/modules-load.d/modules.conf to automatically load the modules at boot time

overlay
xt_ipvs

Install Docker

Follow the official guide to install docker. https://docs.docker.com/install/linux/docker-ce/ubuntu/

Mostly you need to run the following command lines:

# install apt-repo first
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update

# Install docker 
 sudo apt-get install docker-ce docker-ce-cli containerd.io

test the installation, type

docker

The help info. of docker should show up.

We create a Docker swarm because this is needed by PWD:

sudo docker swarm init

Configure user and group

Add your current user account in Ubuntu to docker group.

sudo usermod -aG docker $USER

The current account is added into to the docker group to run the Docker commands without sudo .

And then logout and login the user once. This is needed to make sure the user is added to the group.

Install Goland and Others

Install golang-go 1.14+ because we need it later for the Play With Docker dependencies. https://golang.org/dl/

Also Install docker-compose because we need it later to start Play With Docker.

sudo apt install docker-compose

Prepare proper domains

While you can use IP address to access your server, it is more convenient for users if you register your domain.

For example,

  • mydomain.com for the main entry, using gitpages customized domain name support
  • lab.mydomain.com for PWC, the sandbox terminal using dockers. It is forwarded to mydomain.com:5010 Exactly how this can be done depends on the domain regstration company you use. Please Refer to their documentation to configure your domain and sub domain names.

Here is some more info.

3. Play-With-Compiler Deployment

Total deployment time can range anywhere for about one hour. The time will be spent in making sure of all prerequisites and other deployment steps.

Clone FreeCC repository

# download the source code to proper folder.
# here we use user home folder as example
cd ~
git clone https://github.com/freeCompilerCamp/play-with-compiler

Prepare Docker image

We customized the default PWD's docker image to

  • install both ROSE and Clang/LLVM compilers on Ubuntu 16.04.
  • The image also has a user account without sudo priviledge for enhanced security.
  • The size of this image is about 13GB. It may take a while to download from DockerHub.

You can get our docker image for the PWC sandbox as follows.

docker pull freecompilercamp/pwc:18.04

If for whatever reason, you'd like to create your own docker image from scratch, please check https://github.com/chunhualiao/freeCompilerCamp/wiki/Docker-Files.

Setup GO environment

cd ~/play-with-compiler

# Download dependencies of the go project used to program PWD
go mod vendor

We could make some modifications manually based on the needs.

Setup playground domain

Check the configuration file config/config.go and go to the following line.

flag.StringVar(&PlaygroundDomain, "playground-domain", "localhost", "Domain to use for the playground")

Change localhost to lab.mydomain.com.

Setup the customized docker image

After building the customized docker image, we need to set PWC to use this particular image. To do this, check the file ./api.go. Go to the following line.

playground := types.Playground{Domain: config.PlaygroundDomain, DefaultDinDInstanceImage: "franela/dind", AvailableDinDInstanceImages: []string{"franela/dind"}, AllowWindowsInstances: config.NoWindows, DefaultSessionDuration: d, Tasks: []string{".*"}, Extras: map[string]interface{}{"LoginRedirect": "http://localhost:3000"}}

Change the default franela/dind to freecompilercamp/pwc:1.0.

Setup example

Please check the following modification we made for reference. Since our server uses Apache to listen to port 80, we use the port 5010 instead for this specific purpose.

diff -r /home/ubuntu/play-with-docker/api.go play-with-docker/api.go
55c55
<       playground := types.Playground{Domain: config.PlaygroundDomain, DefaultDinDInstanceImage: "franela/dind", AvailableDinDInstanceImages: []string{"franela/dind"}, AllowWindowsInstances: config.NoWindows, DefaultSessionDuration: d, Tasks: []string{".*"}, Extras: map[string]interface{}{"LoginRedirect": "http://localhost:3000"}}
---
>     playground := types.Playground{Domain: config.PlaygroundDomain, DefaultDinDInstanceImage: "freecompilercamp/pwc:1.0", AvailableDinDInstanceImages: []string{"freecompilercamp/pwc:1.0"}, AllowWindowsInstances: config.NoWindows, DefaultSessionDuration: d, Tasks: []string{".*"}, Extras: map[string]interface{}{"LoginRedirect": "http://localhost:3000"}}
diff -r /home/ubuntu/play-with-docker/config/config.go play-with-docker/config/config.go
58c58
<       flag.StringVar(&PlaygroundDomain, "playground-domain", "localhost", "Domain to use for the playground")
---
>       flag.StringVar(&PlaygroundDomain, "playground-domain", "lab.freecompilercamp.org:5010", "Domain to use for the playground")
diff -r /home/ubuntu/play-with-docker/docker-compose.yml play-with-docker/docker-compose.yml
7c7
<             - "80:8080"
---
>             - "5010:8080"

Start PWD services

cd $HOME/play-with-compiler
docker-compose up -d

Three serivces will be started

  • haproxy: frontend website, using port 80
  • l2: backend website, exposing three ports: 443 (https), 8022 (->22 ssh port) , 8053 (->53/tcp)
  • pwd: the PWD container, no exposed port

You can check their status:

docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                              NAMES
b7b2beb577c6        golang              "/bin/sh -c 'ssh-key…"   32 seconds ago      Up 29 seconds                                                                          pwd
7b8536f902e3        haproxy             "/docker-entrypoint.…"   42 seconds ago      Up 30 seconds       0.0.0.0:80->8080/tcp                                               haproxy
8f82793a350a        golang              "/bin/sh -c 'ssh-key…"   11 days ago         Up 41 seconds       0.0.0.0:443->443/tcp, 0.0.0.0:8022->22/tcp, 0.0.0.0:8053->53/tcp   l2

To test the server

you can access lab.yourdomain.com. The "Play with Docker" frontpage should show up.

  • If you click "Start" to start instances, it will go to the next webpage showing "No connection to server". This is expected since this installation method won't support this feature for now.

You can also check on the AWS server:

 docker container ls
CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS              PORTS                                           NAMES
f2c82b1a85b1        golang              "/bin/sh -c 'ssh-key…"   About an hour ago   Up About an hour                                                                       pwd
cb1d60dcee45        golang              "/bin/sh -c 'ssh-key…"   About an hour ago   Up About an hour    0.0.0.0:443->443/tcp, 0.0.0.0:8022->22/tcp, 0.0.0.0:8053->53/tcp   l2
004331c0ab3e        haproxy             "/docker-entrypoint.…"   About an hour ago   Up About an hour    0.0.0.0:80->8080/tcp                                               haproxy

As you can see, the HAPROXY container is running and listening at port 80.

If you want to stop or restart the PWD server, you can use one of the following command lines

cd $HOME/play-with-compiler
docker-compose restart

To take down the server

cd $HOME/play-with-compiler
docker-compose down --volumes

It will stop PWC completely and remove the created storage and networks used by docker.

4. Classroom Website Deployment

The classroom website is hosted using Github Pages. We recommend to use Github Pages instead maintaining your own web server to save time and resources. The classroom's website content is managed by a git repo, https://github.com/freeCompilerCamp/freecompilercamp.github.io .

In general, Github Pages uses a specially named git repo (e.g. https://github.com/username/username.github.io ).

  • Once you push content to the repo. Github will automatically convert the repo's content into website pages. The website's default URL will be http://username.github.io .
  • "username" can be a personal user account or organization account (preferred). You should create the account first before you can create username.github.io within that account.

Setup domain

Besides using the default free domain name (e.g. http://username.github.io) provided by github, you can use your own domain name for your classroom website.

Check the configuration file compiler-classroom\_config.yml and go to the line starting with url:```. The domain for the main website should be filled here.

url: "http://mydomain.com"

Check the line starting with pwdurl:. The domain for the PWC server should be added.

pwdurl: http://lab.mydomain.com

Testing

Go to mydomain.come in your browser. Your classroom website should show up.

5. Reference

Official guide of PWD deployment

Deploying PWD in your own infrastructure

Running Play with Docker on AWS

Deploying play-with-docker.com on my machine