Containerizing your project’s documentation might be one of the easiest ways you can remove friction from iterating. Your docs are also probably one of the easiest things you can containerize. Here’s how you can get your docs up and running with Docker Compose in just a few minutes.
Why should I containerize my docs?
Simply put, containerizing your docs lets you hit the ground running when writing documentation.
Here are a few QoL improvements that come with doing this:
- No need to install/update/manage dependencies
- Work with the same development environment across machines
- Start developing with just a single command
In short, it’s just easier. You don’t have to think about building and running the dev server, you can just open your terminal and your IDE, then start writing. When writing docs, you’re likely iterating often and adding small chunks at a time, so it makes sense to optimize your local dev environment to spin up as efficiently as possible.
Containerizing your Docusaurus build
At Shipyard, we’re big fans of Docusaurus. We’ve been using it to write our public documentation for three years. We’ve also been using Docker Compose for local docs development just as long. A lesson we’ve learned is that sometimes the best tools are the ones we’re already using. We were using Docker Compose for everything else, why not extend it to our docs?
Writing the Dockerfile
Since Docusaurus is Node-based, the Dockerfile is pretty standard. You might need to swap in your docs’ custom run commands.
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
This Dockerfile Explained
If you’re newer to Docker, here’s a line-by-line rundown of what this Dockerfile is doing:
- Start with a Node base image
- Create and set the working directory within the container
- Copy the Node dependencies to the working directory
- Install dependencies within container
- Copy the rest of the repo’s contents to the working directory
- Run the Node project’s start command
Setting the host
In order to make the application accessible from outside the container (e.g. from your web browser), you’ll want to set the --host
option to 0.0.0.0
.
This can be done from your package.json
:
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start --host 0.0.0.0",
Or in your Dockerfile as an argument to your project’s start command:
CMD ["npm", "start", “--host”, “0.0.0.0”]
Writing the Docker Compose file
Now that we have the Dockerfile, we can write a single-service Compose file to leverage it. Here, we’ll specify any Docker config options (so we don’t need to remember them for complex docker build
and docker run
commands).
version: '3'
services:
docusaurus:
build:
context: .
ports:
- '3000:3000'
volumes:
- './docs:/app/docs'
- './src:/app/src'
- './static:/app/static'
- './docusaurus.config.js:/app/docusaurus.config.js'
- './sidebars.js:/app/sidebars.js'
Because we’re optimizing this Compose file for local development, we’ll want to define bind mounts from any files and directories that we plan to edit. This way, any local changes will be reflected in the Docker container.
In this example, I have a few bind mounts defined under the volumes option. The syntax for this involves specifying the local path (relative to the build context), followed by a colon, then followed by the corresponding location in the container.
Bonus: Writing the .dockerignore
Docker images tend to run pretty large, so writing a .dockerignore
can help slim them down by weeding out any files irrelevant to your Docker build.
To exclude any Markdown files in the root directory (e.g. your README.md
and LICENSE.md
, but not your actual Markdown doc pages), you can use this glob pattern in the .dockerignore
:
/*.md
Your Docker build also doesn’t need to include the Dockerfile or the Compose file. These glob patterns will match most naming conventions for those:
*compose*
*Dockerfile*
You can also exclude node_modules
(likely the biggest bloat culprit):
node_modules
Docs that work right out of the box
Now that you’ve containerized your Docusaurus docs, you can spin them up locally with docker compose up
and start editing.
Thanks for reading!
If you enjoyed this Docker Compose tutorial, check out this post I made a few months ago on how to write a Compose file for a Wordle clone.