Docker in the SPA widget
We'll cover the following
- Running a live server
- Example: Setting up a Node.js server
- Objective
- Step 1: create a dockerfile
- Step 2: create a tarball and upload it
- Step 3: create a docker job
- Select docker job type
- Job name
- Input file name
- Application port
- HTTPS strict mode
- Force relaunch on widget switch
- Start script
- Run script
- Step 4: select the docker job
- URL key
- Editor view
- User view
- URL key in a docker job
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:
'use strict';const express = require('express');// Constantsconst PORT = 8080;const HOST = '0.0.0.0';// Appconst 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.
# Base imageFROM node:10# Copying the project files into the containerCOPY . .# Moving into the project directory and installing dependenciesRUN 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.
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.
-
By default, SPA searches for the Master branch. If that is not found, it tries to search for a Main branch. In case neither of these branches exist, you will see a warning ⚠️ sign.
-
You can clone a specific branch of a repo as well. You can simply copy the URL when you’re on the branch you need. eg. https://github.com/Zuwayr/Hash-collision-demo/tree/demo. Notice the tree/demo part of the URL. If you know the branch name, you can simply add tree/
to your GitHub link and it should work as expected. -
In case your branch name has a / in it, you’ll have to replace it with %2F. For example, if your URL was https://github.com/webtutsplus/ecommerce/tree/nmadhab/security-config, change it to https://github.com/webtutsplus/ecommerce/tree/nmadhab%2Fsecurity-config
-
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
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.
- 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.
Your app’s URL is now available in your docker job!