Straightforward, minimal Docker Compose setup for Eleventy
Typical Docker use-case scenario: I was throwing together a blog with Eleventy, and the others did not have the required Node.js version for all functionality.
Eleventy doesn't require any fancy setup; I assume that's why there's no "official" or popular Docker image. The ones I quickly found looked half-backed or abandoned.
For this particular project, the CLI command for serving the site was:
npx @11ty/eleventy --input=*.njk --serve
Without any configuration file, as a one-line command, this for Docker would be:
docker run --rm -v ${PWD}:/app -w=/app node:16.15.0-alpine npx @11ty/eleventy --input=*.njk --serve
Eleventy when serving a website exposes a local and external URL:
[11ty] Watching…
[Browsersync] Access URLs:
--------------------------------
Local: http://localhost:8080
External: http://172.17.0.2:8080
--------------------------------
[Browsersync] Serving files from: _site
Because the process is running inside the container, use the external URL. There's no real need for doing a port mapping.
Now that macOS uses zsh
by default, this chokes with the zsh: no matches found: --input=*.njk
error; but works well with bash
.
We can get around this entire error by adding the 11ty command in package.json
, which we would do it anyway:
{
"scripts": {
"build": "npx @11ty/eleventy --input=*.njk",
"serve": "npx @11ty/eleventy --input=*.njk --serve"
}
}
This works well on Unbutu (bash
) and macOS (zsh
):
docker run --rm -v ${PWD}:/app -w=/app node:16.15.0-alpine npm run serve
I prefer having a Docker config file, not just because it shortens the commands, but IDEs pick up on the usage and provide support for it.
The docker-compose.yml
can be as simple as:
version: '3'
services:
site:
image: node:16.15.0-alpine
working_dir: /app
volumes:
- ./:/app
With this file in place, the command is now:
docker-compose run --rm site npm run serve
This is still too much typing for my taste, so I usually add a helper script, so I can run my command like:
./bin/docker npm run serve
The script (bin/docker
) does nothing more than forward the arguments passed to it:
#!/bin/bash
CMD=$*
if [[ -z $CMD ]]; then
echo "What command should we run inside the container? None provided."
exit 1
fi
eval docker-compose run --rm site "$CMD"