I won’t be going over what Stencil CLI, Docker, or containers are in this post — I’ll assume you’re already familiar with the basic concepts. However, if this is something you’re approaching for the first time, I’ve included some primers to get you started in the Wrapping Up section section at the end.
Also included towards the bottom is a TL;DR with just the commands necessary to build and run the image if you’d prefer to skip my ramblings.
Stencil CLI is a pretty sweet tool; however, like many other npm packages, the smallest misconfiguration in your node environment can make it a PITA to install. I know. I’ve been there.
I recently experienced package hell attempting to install Stencil CLI on a personal machine. I could have cleaned up my node environment (it was messed up like a soup sandwich) and resolved the issue; however I just wanted to tinker around a bit, and I was ready to show npm who’s boss once and for all. That’s when I remembered step one of the Efficiency Algorithm I mentioned in Tips for Optimizing Your Workflow: there’s a solution to your annoyance.
Luckily, in this case, I already knew the solution: containers. This is exactly the type of problem containers are meant to solve. So, why containerize Stencil CLI? I’ll get to the point:
- It’s fun and easy to setup
- It’s cross-platform
- It makes Stencil CLI easier to install
- It makes Stencil CLI easier to install
Okay, now that you’re convinced, let’s dockerize this bad boy.
Creating the Dockerfile
Docker runs images. In order to run an image, the image must be built. A convenient way to build images is using a dockerfile. According to docs.docker.com:
Dockerfileis a text document that contains all the commands a user could call on the command line to assemble an image. Using
docker buildusers can create an automated build that executes several command-line instructions in succession.
Here’s the dockerfile I use to build a basic Node.js and Stencil CLI image:
# use official node parent image
FROM node:10# set container working directory
WORKDIR /theme# install the cli
RUN npm -g config set user root
RUN npm install -g @bigcommerce/stencil-cli# publish cli default port
I’ve pushed this dockerfile to a repo on my GitHub — feel free to clone, fork, or copy/paste to customize to your taste.
Building the Docker Image
docker build accepts URLs to dockerfiles. So, the image can be built on any machine with docker and access to the internet:
# build docker image
docker build -t docker-stencil https://github.com/aglensmith/docker-stencil-cli.git
-t: name and optionally a tag in the ‘name:tag’ format
Running the Image Interactively
The basic command for running a docker image is as follows:
docker run [<IMAGE>][<COMMAND>]
However, if you execute
docker run docker-stencil stencil start not much will happen. This is because, by default, docker runs the command passed in and immediately exits. To interact with Stencil, we’ll need to do a few things:
- Run the image interactively and start a shell session so that we can run
stencil initand other CLI commands.
- Mount the current working directory to the
/themedir in the container’s file system so that stencil can access the theme files on the host machine.
- Expose the default port used by
stencil startand attach it to a port on the host machine so that we can browse to the theme preview.
Here’s the complete command:
user@host$: docker run -it -v $(pwd):/theme -p3000:3000 docker-stencil /bin/bash
Or, for bash on Windows:
user@host$: docker run -it -v /$(PWD):/theme -p3000:3000 docker-stencil //bin/bash
Run it to start a containerized bash shell:
root@54a89154e06c:/theme# ls -all
drwxrwxrwx 2 root root 12288 Mar 10 23:28 .
drwxr-xr-x 1 root root 4096 Apr 23 15:07 ..
-rwxr-xr-x 1 root root 66 Mar 5 19:52 .eslintignore
exit to go back to the host machine’s CLI:
-it: keep STDIN open and allocate a pseudo-TTY.
-v $(pwd):/theme: mount host’s current working directory (your theme dir) to container’s working directory (/theme — specified in dockerfile).
-p3000:3000: expose stencil’s default port to localhost.
If there’s not a
.stencil configuration file in your theme directory, you’ll need to generate one. Also, don’t forget to install theme dependencies.
To do so, run the following commands:
# move into theme dir
user@host$: cd ~/path/to/theme/dir# install theme dependencies
user@host$: npm install# Run container and start bash
user@host$: sudo docker run -it -v $(pwd):/theme -p3000:3000 docker-stencil /bin/bash# initialize stencil config
root@54a89154e06c:/theme#: stencil init
# exit back to host CLI
Once everything is configured, use
docker run to start stencil:
user@host$: cd ~/path/to/theme/diruser@host$: docker run -it -v $(pwd):/theme -p3000:3000 docker-stencil stencil start
- Add an alias for the above command to your
# build image
user@host$: docker build -t docker-stencil https://github.com/aglensmith/docker-stencil-cli.git# move into theme dir
user@host$: cd ~/path/to/theme/dir# install dependencies
user@host$: npm install# run interactively
user@host$: sudo docker run -it -v $(pwd):/theme -p3000:3000 docker-stencil /bin/bash# init stencil
root@54a89154e06c:/theme#: stencil init# exit
root@54a89154e06c:/theme#: exit# start stencil
user@host$:docker run -it -v $(pwd):/theme -p3000:3000 docker-stencil stencil start
What is this, a Christmas present? I’ve got nothing. Go dockerize Stencil CLI already. Oh yeah, below are the resources I promised.
- Orientation and Setup (docs.docker.com)
- A Docker Tutorial for Beginners (docker-curriculum.com)
- Docker: a Primer (medium.com)
- Best Practices for Writing Dockerfiles (docs.docker.com).
- Dockerfile Reference (docs.docker.com)
- docker build (docs.docker.com)
- docker start (docs.docker.com)