Running a live server

The most important use of docker on the Educative platform is to run an app with a live server connected to it. This live virtual machine will stay persistently active throughout your course for a fixed period of time. It gives users the ability to interact with an app/webpage and use a server terminal to see how the backend of the app works.

If you wish to include a running server in your Answer, you must use the SPA widget.

This guide will take you through all the steps required to set up a live server. We will create a Dockerfile, set up our Docker job, and run the code.

Example: Setting up a Node.js server

Objective

To run a Node.js server on Educative. We’re assuming that you have a server set up locally and you wish to port it to our platform. Here’s what the server file looks like:

Press + to interact
'use strict';
const express = require('express');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(PORT, HOST);

Step 1: create a dockerfile

As always, the first step is to create a Dockerfile. In the same directory, we will have a folder containing all the files for our application. In this case, there is a package.json file and a server.js file.

Press + to interact
# Base image
FROM node:10
# Copying the project files into the container
COPY . .
# Moving into the project directory and installing dependencies
RUN cd server && npm install -g nodemon && npm install
  • FROM node:10: We are using Node version 10 as our base image. The OS is Debian.

  • COPY . .: This copies all the source files (which includes server.js) to the current working directory. Keep in mind that these files are not automatically present in the container. Hence, it is essential to use COPY to bring them into the container.

  • cd server: Moving into the server folder where our project files are present.

  • npm install -g nodemon: This installs Nodemon, a Node watcher. A watcher checks for any changes in the project files and reflects those changes in your application without you having to rebuild or restart the project. This is useful when you want users to experiment with the code. With the help of a watcher, the users will be able to make their own changes to the project code without worrying about the steps to rebuild and restart the project.

  • npm install: This downloads the package and all its dependencies. Since it requires a package.json file, we have to move into the server folder where the file is present.

Step 2: create a tarball and upload it

Previously, we only had to include the Dockerfile in the tarball. But now, since we have a project folder as well, that must also be compressed in the tarball along with the Dockerfile. If the name of the folder is server, the tarball command will look something like this:

tar -czvf node.tar.gz Dockerfile server

Sometimes, the project repository may be very large in size. The resulting tarball will not be supported on the Educative platform, causing the image build to fail. In such a case, make a GitHub repository of your project and simply clone it in the Dockerfile.

RUN git clone https://github.com/my-project &&\
    cd my-project

This way, the tarball remains manageable and all your code can still be imported into the container. You will not have to use the COPY command to import the project folder - git clone works directly in the container.

Step 3: create a docker job

All the fields in this job are similar to those of a job for a regular Docker environment until you change the job type from Default to Live. On selecting the live option, you’ll see a few more fields appear. We’ll discuss these fields in detail later on in this lesson.

This is where the actual set up of your container takes place. So, let’s discuss each component one by one.

Select docker job type

This field will be used to select your docker job type.

Job name

This name will be used to select the job in a SPA widget.

Input file name

This field is not applicable when working with LiveVMs. The files in the SPA widget are not linked to your container. Hence, there is no input file for the backend to work with. Instead, we can copy the files from the SPA into our container (more on this shortly).

Application port

This is the port where your server will be listening. Port 3000 is open by default and you can listen on one more port. In our case, it’s 8080.

HTTPS strict mode

If your server is HTTPS, tick this field.

Force relaunch on widget switch

With this option enabled, If you use the same job on different widgets, a container will be started on each switch. However, on the same widget, the session won’t restart. Check this box if you want the widget to restart on every switch.

Start script

This script runs the first time you click the ‘RUN’ button in a SPA. It runs only once. Typically, this script would be used to ‘start’ the server.

The code present in the SPA widget’s editor is not actually part of our project. This code lives in a directory called /usercode which is present in your container’s root directory by default.

So if the user makes any changes to server.js (which is in /usercode), they will not be reflected in your project’s server.js (which is in your project folder).

That’s why you also need to copy the code from the /usercode to your relevant folder (i.e., server.js in this case). Here, we simply copy the code and use npm to start the server.

Your container is persistently active for 15 minutes. Hence, the Start Script is executed once the container times out.

Run script

The Run script is something you have seen before, but its behaviour is slightly different when working with a live terminal. It runs every time you click the ‘RUN’ button. On the first run, the Run Script is executed before the start script and after the first run, every subsequent run will only execute the commands written in this field (not the Start Script).

If you start the server using the start script, then the only thing you need to worry about is updating the code in the relevant files/folder as the updated code would lie in the file present in the /usercode as we discussed earlier in the run script section. That’s why it is typically used to update your project’s code in the container.

cp /usercode/* /server

Here is the general data flow of a run script cycle:

Step 4: select the docker job

Finally, create a new Single Page App widget and select your job from the docker (beta) dropdown menu.

widget

Put all your project code in the SPA editor files so that users can see it.

Before we get to running the server, there are a few extra options in the SPA control panel which you can use to fine-tune how your live server looks. Let’s discuss a few important ones.

  • Hide code: Hides the code completely on the front end.

  • Hide output: Hides the output window. Only the terminal will be displayed.

  • Output height: Can be used to define the height of the output window.

  • Provide GitHub token: Provide a personal token if you are using a private repository.

  • Import code from GitHub: Enter the link to a repository to import it. This is useful for importing large projects automatically. The project size should not exceed 750 kb. If the project is larger, the usercode directory will become empty.

  • Override app entrypoint: You can change the server’s landing page with this option. Clicking on it will allow you to modify the link that is generated for the server.

URL key

If you want to refer to the URL link generated by the SPA widget, you can use the key {{EDUCATIVE_LIVE_VM_URL}} in code playgrounds (code widget, SPA, and code tabs) and it will be replaced by the application URL.

Hence, instead of having users manually copy the URL of their application, you can write {{EDUCATIVE_LIVE_VM_URL}} in the code playground and it will automatically be replaced for each user with their SPA widget’s application URL.

Note: The key must be added in edit mode. Once you switch to preview mode, you will see the key replaced by your app’s URL.

Editor view

widget

User view

print("https://vv3gd8xe98k42.educative.run") # Convert to string to make it printable

URL key in a docker job

You may want to use your SPA’s URL in a docker job. For example, you have the following command in your start script and want to replace url with your app’s URL:

 curl -H "Accept: text/event-stream" "url/quotes-reactive-paged?page=0&size=50"

This url is stored in the API key: EDUCATIVE_LIVE_VM_URL which can only be accessed inside a code file in the SPA widget. Hence, we can’t do the following directly inside the start script of the docker job:

curl -H "Accept: text/event-stream" "{{EDUCATIVE_LIVE_VM_URL}}/quotes-reactive-paged?page=0&size=50"

In order to use this API key, we can shift the whole start script of the Docker job to a .sh file inside the SPA widget.

  • Make a .sh file in the SPA widget and select the “Hide File” option.
widget
  • When you switch to preview mode and click on the “Run” button of the SPA widget, this API key will be replaced with the EDUCATIVE_LIVE_VM_URL.

Note: This may not work in edit mode.

  • In the start script of your docker job, change the directory to /usercode where your .sh file resides and run it.
widget

Your app’s URL is now available in your docker job!