web application to provide students with an instant development and deployment environment (vscode in the web browser).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
forest 659e609ec3 readme 2 years ago
caddy/config styles for home page 2 years ago
dockerbuild got multi-user code-server working !! 2 years ago
frontend fixing bugs with workshop chat 2 years ago
readme Add screencast, how-to-set-up instructions on readme, etc 2 years ago
synapse-data update deployment code 2 years ago
.gitignore Add screencast, how-to-set-up instructions on readme, etc 2 years ago
Dockerfile got multi-user code-server working !! 2 years ago
Dockerfile.code-server Add screencast, how-to-set-up instructions on readme, etc 2 years ago
Dockerfile.code-server.entrypoint.sh Add screencast, how-to-set-up instructions on readme, etc 2 years ago
ReadMe.md readme 2 years ago
build-docker.sh got multi-user code-server working !! 2 years ago
config.json fixing bugs with workshop chat 2 years ago
db.go add become-user functionality 2 years ago
docker-compose.yml update deployment code 2 years ago
docker_manager.go fix fatal error: concurrent map writes in docker mgr 2 years ago
frontend.go fixing bugs with workshop chat 2 years ago
frontend_auth.go add become-user functionality 2 years ago
frontend_chat.go adding in chat support 2 years ago
frontend_publish.go got the publish feature working! 2 years ago
frontend_vscode.go update readme 2 years ago
go.mod tabs -> spaces 2 years ago
go.sum tabs -> spaces 2 years ago
main.go adding in chat support 2 years ago
oauth.go grab app skeleton from greenhouse 2 years ago




animated gif screencast showing login process, creation of a new project, editing html with live updating preview, and publishing a site


  • Login is required to access code-server
    • Users log in with thier Gitea account, separate workspaces for each user
  • The code-server runs inside a dedicated debian linux environment for each user.
    • The shell works just fine, with apt, sudo, etc
    • Sandboxed by docker
  • Live updating html/css for development
  • Live group chat for classes and workshops
  • Ability to publish under a separate path for your username so that anyone can view your site
  • Special /api/* route will be reverse-proxied to whatever HTTP server is listening on port 5000
    • This makes it easy for users to play around with "full stack" web apps with a server application, not just static HTML.

Quick tips for operation / admin

You can set the scrollback history of the live chat to a specific point in time using the DefaultRoomIterator configuration setting.

Get the sync iterator value by opening the live chat and going into the network tab of the web browser development tools. You should see http requests for URLs similar to


Grab the from value, something similar to s43_319_58_25_21_1_1_18_0, and then put it in the docker compose as an environment variable like so:

    image: sequentialread/workspace-on-demand:0.0.0-d8eca9c-fa1d
      - WOD_DEFAULTROOMITERATOR=s43_319_58_25_21_1_1_18_0

Finally, update the config and restart the app with docker compose up -d

NOTE: in order to test this properly, you can't just press refresh on the chat window. You have to close the chat window and re-open it from the main landing page of the app. This is because the chat iterator is part of the URL of the chat window.

How to set it up and run it:

1. build a customized image for code-server

First, build the special code-server image that contains https://github.com/ForestJohnson/live-server/ listening on port 2000.

(This is a fork of https://www.npmjs.com/package/@compodoc/live-server with a couple small bug fixes)

sudo docker build -f Dockerfile.code-server -t code-server-configured:v7 .

NOTE! the rest of this step is OPTIONAL if you wish you may now proceed to step 2.

If you want to further customize the code-server instance or do other manual customization outside of the docker build:

mkdir testconfig
mkdir testproject
docker run -d -v ./testconfig:/home/coder/.config \
           -v ./testproject:/home/coder/project \
           -p 8080:8080 \
           --user coder:coder \

Then grab the password with

cat ./testconfig/code-server/config.yaml

And log into the code-server instance at http://localhost:8080, do any customizations to vscode or install any desired packages or SDKs, and then save your image with:

sudo docker ps

To record the container ID of the container you just created, and then

sudo docker commit <containerid> code-server-configured:v8

to save a new version of your custom image with whatever manual changes you did.

2. Update the config for your deployment

You will need to change configuration settings in docker-compose.yml for your deployment.

You will need to set the configuration of the wod service via environment variables, and also set some docker labels on wod and caddy-config as well.

Here are the environment variables you need to set on wod:


Default value: code-server-configured:v7 You may want to change this if you have your own image that you want to use which has a different image name.






These default to the helloworld.cyberia.club domains, you will need to provide your own domain name for yours.


Default value: /home/cyberian/wod/workspaces

This value controls where wod will save your users' workspace folders on the docker host. This folder has to exist and it has to be readable by user 1000.


Default value: cyberia-gitea

This is a human readable admin-facing name that represents the OAuth provider.

NOTE: This string gets placed into the Redirect URL you need to enter into the OAuth settings within your OAuth provider as you will see later.


Default value: https://git.cyberia.club

Set this to the home page of your OAuth provider.


Currently only gitea is supported but adding other OAuth backend types shouldn't be that hard.



These come from your OAuth provider when you create the OAuth application, see the image below.



In the docker-compose.yml. This is so that the client secret can live in a separate .env file and be automatically injected by docker-compose when run. This way I can safely commit my docker-compose file to source control and gitignore .env so it does not get committed by accident.

Also note how cyberia-gitea, the value of WOD_OAUTHPROVIDERS_0_INTERNALID, is included in the redirect url:

screenshot of gitea &quot;Edit OAuth2 Application&quot; UI showing 4 fields: Client ID, CLient Secret, Application Name, and Redirect URI


Default value: !kjpZCYKhylkmHWXIQs:cyberia.club

This should be the id of a matrix room which you want to use for the live chat feature. The matrix room has to have guest access enabled and the history visibility setting should be set to "history is visible to everyone".

Also, if that room is on a separate server, the embedded matrix server used for creating guest accounts has to "know about" the room already. It has to have a local user account which has joined the room.


Default value: s31_222_14_19_15_1_1_18_0

Set the scrollback limit to a specific point in time in the matrix room. See the "Quick tips for operation / admin" section.

Here are the docker container labels you need to set on wod:


This needs to be a comma separated list of all the values you set for, WOD_SELFDOMAIN, WOD_VSCODEDOMAIN, WOD_LIVESERVERDOMAIN, and WOD_PUBLISHDOMAIN.

Here are the environment variables you need to set on caddy-config:


Same as above, set this to a comma separated list of all the values you set for, WOD_SELFDOMAIN, WOD_VSCODEDOMAIN, WOD_LIVESERVERDOMAIN, and WOD_PUBLISHDOMAIN.


Put your email address here to recieve notifications / security advisories from Let's Encrypt should there be any problems related to your TLS certificates.

See synapse-data/homeserver.yaml for more information on how to configure the builtin matrix server used by the chat feature

3. Ensure that your DNS and TCP ingress is set up correctly

Make sure that when you look up the domain names you set for WOD_SELFDOMAIN, WOD_VSCODEDOMAIN, WOD_LIVESERVERDOMAIN, and WOD_PUBLISHDOMAIN, they all resolve to the correct IP address for your server.

Run nc -l 80 (leave it hanging in your terminal while you do the next part)

And then from another machine preferrably somewhere else on the internet or via a VPN or on your phone's mobile data connection, try connecting to http://<your-ip-here>:80 with curl or with the web browser. The HTTP request should show up in your terminal where you ran nc -l 80. If it does you are good to go!

4. Run docker compose to start it up!

sudo docker compose up -d


sudo docker-compose up -d

Depending on how it was installed.

If everything worked, the site should now be live and you can see it at https://<my-app-domain>!


Then you should be able to see all the containers like this:

root@debian:/home/cyberian# docker ps
CONTAINER ID   IMAGE                            COMMAND                  CREATED      STATUS      PORTS                     NAMES
c16ecc914949   sequentialread/workspace-on-...  "/app/wod"               3 days ago   Up 3 days                             cyberian-wod-1
2a6a19a877c9   sequentialread/caddy-config:...  "/app/sequentialread…"   3 days ago   Up 3 days                             cyberian-caddy-config-1
eddb369bf095   caddy:2.3.0                      "/bin/sh -c 'rm -f /…"   5 days ago   Up 5 days>80/tcp, ...   cyberian-caddy-1

If the page doesn't load want to check the logs to make sure that caddy was sent a good config:

docker logs -n 100 -f cyberian-caddy-config-1

And check to make sure that caddy was able to aquire your TLS certificates correctly:

docker logs -n 100 -f cyberian-caddy-1

If you are having trouble accessing the code-server, try checking the wod logs in case it had trouble creating or starting a container:

docker logs -n 100 -f cyberian-wod-1