How to bootstrap your NodeSchool event
Tags: nodeschool, education, learning
Published: 2019-06-13 16:25:47

---
title: How to bootstrap your NodeSchool event
published: true
description: Steps to get a NodeSchool workshop running a web-based VS Code
tags: nodeschool, education, learning
cover_image: https://i.imgur.com/X75gr6p.jpg
---


For years the team at NodeSchool Buenos Aires has been experimenting with different setups trying out tools like [C9](c9.io), [runnable](http://runnable.com/) or [glitch](https://glitch.com/). On all those attempts we intended to minimize the setup time for the participant and avoid any kind of  installations from their part. We were looking for an alternative that supported all Operating Systems, that doesn't requires a GitHub account and ideally that requires no sign-in/registration. 

This is a tutorial on how to configure a modified Docker image of [code-server](https://github.com/codercom/code-server) to use a web-based VSCode editor with every workshop pre-installed on a self-hosted instance. To get a better idea I tried to put together the components in the following diagram:

![](https://thepracticaldev.s3.amazonaws.com/i/d38xxiawfugyle250ge7.png)


# 1. Configure your instance
Use the cloud provider of your choice and any OS of your preference as long it's *NIX based (I haven't tried running it on Windows' WSL but should work too). It cal also run locally on a computer.
Requirements: [docker](http://docker.com/), [Node](http://nodejs.org/), a [Zeit](https://zeit.co/signup) account and [now](https://zeit.co/now) installed.
# 2. Create your containers
SSH into your instance and define a few environment variables that will be used for the next steps, make sure you modify the environment variable `CONTAINERS_COUNT` to have the value you need:
```
export PUBLIC_IP=`curl https://ipinfo.io/ip`
export CONTAINERS_COUNT=thenumberyouwant
```

Create a template folder for your containers. In my case I created an `introduction.js` file so that the project is not empty:

```
$ mkdir -p nodeschool/template
$ echo "console.log('hello');" > nodeschool/template/introduction.js
$ ls nodeschool/template/
introduction.js

```

Each container should have a unique directory so that participants are able to save and edit files within their projects without affecting other running projects. Create the directories from your template running: 

```
$ for i in $(seq 1 $CONTAINERS_COUNT); do cp -a nodeschool/template. nodeschool/$i; done
```

After that you can create the containers with the command: 

```
for i in $(seq 1 2 $(($CONTAINERS_COUNT*2))); do docker run -e "SERVE_PORT=$((8442+$i+1))" -e "URL=$PUBLIC_IP" -d -p 0.0.0.0:$((8442+$i)):8443 -p 0.0.0.0:$((8442+$i+1)):5000 --entrypoint "/bin/bash" -v "${PWD}/nodeschool-servers/$i:/root/project" a0viedo/code-server initialize; done
```

Once all the containers are up you will need to extract the configuration from them running the following commands:

```
docker ps -q | xargs -n1 -I{} sh -c 'docker logs {} | tail -10' | grep Password | cut -d' ' -f4 | START_PORT=8443 npx https://gist.github.com/a0viedo/6707a836b16621263a31e7bd149bb6d8
```

The generated `config.json` should look like the following:
```json
{
  "list": [
    {
      "port": 8443,
      "password": "arandompassword"
    },
    {
      "port": 8444,
      "password": "anotherrandompassword"
    }
  ]
}
```

# 3. Setup your event landing page
On this step we will configure a website that will assign each participant a unique URL and a password. You will need a [Zeit](https://zeit.co/signup) account and have [now](https://zeit.co/now) installed (`npm i now -g`).

First, clone the [minimal-nodeschool](https://github.com/a0viedo/minimal-nodeschool) repository:
```
git clone https://github.com/a0viedo/minimal-nodeschool
```
Grab the `config.json` file that was generated for step 2 and copy it into the directory for "minimal-nodeschool". Finally run `now` in the directory and you should see something like the following:

```
$ now
> Deploying ~/Documents/dev/minimal-nodeschool under a0viedo
> Using project nodejs
> Synced 6 files (4.28KB) [2s]
> https://yourdeployment-hash.now.sh [v2] [2s]
┌ index.js           Ready               [17s]
└── λ index.js (2.86KB) [gru1]
┌ index.html         Ready               [1s]
└── index.html
┌ config.json        Ready               [1s]
└── config.json
> Ready! Aliased to https://yourdeployment.a0viedo.now.sh [in clipboard] [23s]

```

You can go a step further and alias your deployment URL to be something like `nodeschoolcity.now.sh` so that's easier for participants to type. Check [their docs](https://zeit.co/docs/v2/domains-and-aliases/aliasing-a-deployment) for more info.


# 4. Configure access to your server
Arguably one of the harder steps to automate since each cloud provider will provide different ways to enable ports on your instance (or enable those in your firewall in case you're using a local computer).
In case you're using AWS's EC2, you could open the ports on a security group with this command (you can either define `CONTAINERS_COUNT` or replace it manually with your value):
```
for i in $(seq 1 $((CONTAINERS_COUNT*2))); do aws ec2 authorize-security-group-ingress --group-name your-security-group-name --protocol tcp --port $((8442+$i)) --cidr 0.0.0.0/0; done
```


You are good to go! Participants can download their current projects by running `download` in the terminal, opening the URL that's displayed and clicking the `project.zip` file.

# Final thoughts
Running 30 containers consumed around 17gb of memory but with a very low CPU consumption (which is not that bad!).
![](https://imgur.com/qJRaxPV.png)