This guide will show you how to create a Coder image for a sample blog project that's written in Node.js.
The Coder workspace that you'll create using this image and be using for your project includes:
- The source code for the project, which is automatically cloned from GitHub
- The Node.js version that's compatible with this project, as well as several global dependencies obtained via npm
- Environment variables containing the developer API keys
- A Code deployment (you can request a trial license; afterward, see our installation guide)
- Docker (you can have this installed locally or on an existing Coder workspace)
- A Docker Hub account or access to another Docker registry
- VS Coder or the text editor of your choice
In Coder, developer workspaces are defined by a Dockerfile that contains the apps, tools, and dependencies that you need to work on the project.
See Docker’s guide to writing Dockerfiles for more information.
To create your Dockerfile, as well as the configure script that Coder runs automatically once it has started your workspace:
Create a folder for the image you're creating:
We strongly recommend that you version control your Dockerfiles:
cd node_apps git init
Create a file named
configure that runs when your workspace starts:
touch node_apps/configure chmod +x node_apps/configure
At this point, you can open your text editor and begin the Dockerfile for your image. Coder maintains base images that contain the recommended software for a Coder workspace. For this guide, we recommend that you use the Ubuntu one:
# Dockerfile FROM codercom/enterprise-base:ubuntu # Copy the configure script to /coder/configure where Coder can find it COPY configure /coder/configure
There are two options when it comes to installing Node.js and the global dependencies that you'll need for this project.
To include instructions for installing Node.js directly from NodeSource:
# Dockerfile ... # Install Node.js 15 RUN curl -fsSL https://deb.nodesource.com/setup_15.x | sudo -E bash - RUN sudo apt-get install -y nodejs # Install global packages RUN npm install --global [email protected]
If you'd like to use nvm instead of supporting multiple versions of Node.js in a
single workspace, you can do so using the
In the following example, you're not installing
nvm in the user's home
directory. As such, the image is the deciding factor for the Node.js version
that's installed and any global packages.
# Dockerfile FROM codercom/enterprise-base:ubuntu USER root # Set NVM_DIR outside of the home directory so it doesn't persist across rebuilds ENV NVM_DIR=/usr/bin/nvm RUN mkdir -p $NVM_DIR RUN chown coder:coder $NVM_DIR # Install nvm as the "coder" user USER coder RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash \ && . $NVM_DIR/nvm.sh \ # Install any Node versions we need && nvm install 12.21.0 \ && nvm install 15.12.0 \ && nvm alias default 15.12.0 \ && nvm use default \ # Install global packages on the default version of node && npm install --global email@example.com # Copy configure script (we need this to add nvm to our path) COPY configure /coder/configure
configure script is as follows:
# configure #!/bin/bash # if nvm command fails, try to add it to our profile and PATH if ! command -v nvm &> /dev/null then echo "nvm command not found... attempting to add to your profile via the install script" # Create a .bash_profile file if it doesn't exist if [ ! -f ~/.bash_profile ]; then touch ~/.bash_profile echo "#/bin/sh" > ~/.bash_profile echo "source ~/.bashrc" >> ~/.bash_profile fi # Create a .bashrc if it doesn't exist if [ ! -f ~/.bashrc ]; then touch ~/.bashrc echo "#/bin/sh" > ~/.bashrc fi # run the install script to add to profile $NVM_DIR/install.sh export NVM_DIR="/usr/bin/nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion fi
We have recently released configure steps in workspace templates. See https://github.com/bpmct/company-blog to see how you can implement this new functionality.
configure script, you can set
git clone to run on your behalf
(assuming that you've
linked your Git account).
We recommend using the SSH option.
configure script, include:
# configure # 1. Ensure that you've added GitHub's host key to known_hosts if ! grep github.com ~/.ssh/known_hosts > /dev/null; then ssh-keyscan github.com >> ~/.ssh/known_hosts 2> /dev/null fi # 2. Clone your project GIT_REMOTE="[email protected]:bpmct/company-blog.git" CLONE_TO="$HOME/company-blog" if [ ! -d $CLONE_TO ]; then echo "$CLONE_TO is empty... Cloning" git clone $GIT_REMOTE $CLONE_TO/. else echo "$CLONE_TO exists ✅" fi
If you have multiple repositories, you can clone each one by replicating and including the cloning instructions shown above.
There are two ways to add environment variables so that they're available to anyone who uses the image.
Note: If you have secret credentials, make sure you make the image private in the Docker Hub, or use a private registry!
# Dockerfile ... ENV PORT=3000 ENV API_KEY=asdfjkl
You can install a secrets manager in Coder just as you would with a local machine. This approach is more secure than the option mentioned previously, since it doesn't require you to commit sensitive information. However, you'll still need to create an account with a secrets manager provider or host the service of your choice.
Some options that you can consider include:
Once you've created your image, you can build and push it to your registry so that it can be accessed by Coder and used to build your workspace. For this guide, we'll show you how to do this with Docker Registry using the console, but you can use the registry of your choice:
Log in to Docker Hub:
Build the image (from the current directory) and tag it:
docker build . -t [username]/gatsby-blog
Push the image:
Note: if you want this image to be private, make sure that you create the private image in hub.docker.com or use a private registry docker push [username]/gatsby-blog
We recommend adding CI-related steps to your git repository so that you can build images automatically and source control images. You can do this with GitHub Actions, GitLab, CircleCI, or even Docker Hub.
At this point, you can import your image and use it to create a new workspace. When you've completed these steps, you can launch your workspace, which contains all of the required tools and dependencies.
See our sample repo for the example project and image configured for Coder.