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
Requirements
- 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
Step 1: Create the Dockerfile
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:
mkdir node_apps
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
2. Install Node.js and global dependencies
There are two options when it comes to installing Node.js and the global dependencies that you'll need for this project.
Option 1: Install Node.js directly from NodeSource
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]
Option 2: Use nvm
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 configure
script.
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 yarn@v1.22.5
# Copy configure script (we need this to add nvm to our path)
COPY configure /coder/configure
The 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.
Step 3: Clone projects automatically
In the 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.
In your 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.
Step 4: Add environment variables
There are two ways to add environment variables so that they're available to anyone who uses the image.
Option 1: Specify environment variables in the Dockerfile
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
Option 2: Add a secrets manager to the Coder image
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:
Step 5: Build and push your image
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:
docker login
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.
Step 6: Import the image to Coder and create the workspace
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.