The Metanorma Docker container provides all dependencies necessary for using Metanorma.
This is the cross-platform solution for Metanorma that works across operating systems where supported by Docker (including Windows).
If you want Metanorma to affect your local machine’s environment as little as possible, using Docker may be the best choice — although not without some performance tradeoff.
For those who need better performance, or wish to avoid a Docker setup (e.g. administrative rights, memory usage), please refer to alternative Metanorma installation methods at https://metanorma.com/author/topics/install/.
Note
|
This repository contains source code that is used to build the Metanorma Docker images. It is only intended for image development. |
Please refer to the metanorma/actions-mn
workflows for using Metanorma in your GitHub Actions workflows.
Under the hood, the Metanorma toolchain depends on a couple of software/packages.
To ease installation, the Docker image is already fully set up so you don’t have to worry about anything.
At a high level, the image includes the following:
To see the full list of packages/software included, check out the Dockerfiles.
All you need is to install Docker as shown below.
macOS:
Windows:
Linux:
This container is published at the
Docker Registry as
docker.io/metanorma/metanorma
or metanorma/metanorma
,
and can be pulled with the following command:
docker pull metanorma/metanorma
In a directory containing the Metanorma document, run this:
Syntax:
docker run -v "$PWD":/metanorma/ metanorma/metanorma metanorma compile [compile-options] {my-document-file}
Anatomy of syntax:
docker run \ (1)
-v "$PWD":/metanorma/ \ (2)
metanorma/metanorma \ (3)
metanorma \ (4)
compile \ (5)
-t {flavor} \ (6)
-x {extensions} \ (7)
{my-document-file} (8)
-
The
docker run
command to run a container -
The
-v
option "bind mounts" the current working directory ($PWD
) to/metanorma/
in the container -
The name of the Metanorma Docker image
-
The first argument after the Docker image tag is the command to run inside the container (
metanorma
invokes the Metanorma CLI) -
The
metanorma
CLI accepts thecompile
command with additional arguments -
The
-t
option specifies the Metanorma flavoriso
,itu
, etc. -
The
-x
option specifies a comma-delimited list of the desired output formatsxml,html,doc
means to generate Presentation XML, HTML, and DOC formats -
The name of the Metanorma document file to compile
# Minimal (the `compile` command is assumed)
docker run -v "$PWD":/metanorma metanorma/metanorma metanorma iso-8601-2-en.adoc
# Alternatively, if you want to specify the flavor and extensions
docker run -v "$PWD":/metanorma metanorma/metanorma metanorma compile -t iso -x xml,html,doc,pdf iso-8601-2-en.adoc
The above command uses a couple assumptions set in the built container itself, including:
-
the
/metanorma
path is set within the container’sWORKDIR
-
the
metanorma
command is set in the container’sENTRYPOINT
The full command is actually this:
docker run -v "$PWD":/metanorma/ -w /metanorma metanorma/metanorma metanorma compile -t {flavor} -x {extensions} {my-document-file}
The :local-cache-only:
document attribute should be set in your
document in order to take advantage of local caching of
bibliographic items fetched from the Internet.
Note
|
Normally, the Metanorma toolchain assumes that you have a global
bibliographic cache located in ~/.relaton/cache and
~/.iev/cache . However, when run in a docker container,
the global cache is not shared between the host and the container.
|
By setting :local-cache-only:
, Metanorma will not generate a global
bibliographic cache, and will store a cache instance for each document
in the local working directory, which is shared between the host
and the container, as in:
-
./relaton/cache
; and -
./iev/cache
.
The document attribute is to be set in the document header, like this:
= ISO 8601-2
:docnumber: 8601
:partnumber: 2
:copyright-year: 2019
:title-intro-en: Date and time
:title-main-en: Representations for information interchange
:title-part-en: Extensions
// ...
:local-cache-only: (1)
-
This attribute is useful for compiling in Docker with a shared bind mount for caching auto-fetched data across Docker runs.
These files can also be checked-in into version control.
Metanorma provides two sets of Docker images:
metanorma/*
-
Official release images using released gems at rigorously tested release intervals (via
metanorma-cli
tagged versions) mn/*
-
Development release images using released gems at shorter intervals, only intended for testing and development purposes
Warning
|
The mn/* images are not intended for production use and may
contain unstable or untested features.
|
The Metanorma Docker images are available in multiple flavors based on different base containers (OS containers), each optimized for different use cases.
Each image set produces the following image types:
Image Type | Base | Tag | Size | Description |
---|---|---|---|---|
Debian |
|
|
~500MB |
Default. Based on the official Ruby image on Debian. Developer-friendly and extensible. |
Ubuntu |
|
|
~450MB |
Developer-friendly and extensible. |
Alpine |
|
|
~400MB |
Smallest image size. Based on the official Ruby image on Alpine. Extensions may
be limited due to usage of |
Windows |
|
|
~5GB |
Native Windows container based on Windows Server Core, using Windows Server 2019 with .NET Framework 4.8 (required for Chocolatey). Enables native Windows workflows in GitHub Actions. Uses Chocolatey for package management. Larger image size due to Windows base image. |
Windows |
|
|
~5GB |
Native Windows container based on Windows Server Core, using Windows Server 2022. Enables native Windows workflows in GitHub Actions. Uses Chocolatey for package management. Larger image size due to Windows base image. |
Windows |
|
|
~5GB |
Native Windows container based on Windows Server Core, using Windows Server 2025. Enables native Windows workflows in GitHub Actions. Uses Chocolatey for package management. Larger image size due to Windows base image. |
By default, the Debian-based image is tagged as metanorma/metanorma:latest
.
Native Windows containers are available with the following tags:
- metanorma/metanorma:windows-latest
(Windows Server 2022)
- metanorma/metanorma:windows-2019-latest
(Windows Server 2019)
- metanorma/metanorma:windows-2025-latest
(Windows Server 2025)
When using native Windows containers, the path format changes:
docker run -v "%cd%:c:/metanorma" metanorma/metanorma:windows-latest metanorma compile -t iso document.adoc
For PowerShell:
docker run -v "${PWD}:c:/metanorma" metanorma/metanorma:windows-latest metanorma compile -t iso document.adoc
Note
|
For Windows containers, the hostq and container OS versions must match. For example, to use windows-2022-latest the host must be running Windows 10/11 with matching kernel version. Alternatively, you can use Hyper-V isolation with the --isolation=hyperv flag.
|
docker run --isolation=hyperv -v "%cd%:c:/metanorma" metanorma/metanorma:windows-latest metanorma compile -t iso document.adoc
When using Docker on Windows with Linux containers, you may encounter path mapping issues:
-
Use proper path conversion when mounting volumes:
docker run -v "%cd%":/metanorma metanorma/metanorma metanorma compile -t iso document.adoc
-
For PowerShell:
docker run -v "${PWD}:/metanorma" metanorma/metanorma metanorma compile -t iso document.adoc
-
If you encounter permission issues, ensure your Docker Desktop has the necessary permissions to access your files.
-
Volume mounting works similarly to Linux:
docker run -v "$PWD":/metanorma metanorma/metanorma metanorma compile -t iso document.adoc
-
If you experience performance issues with mounted volumes, consider using Docker Desktop’s file sharing optimization settings.
Metanorma Docker images are designed to be extensible. You can create your own custom images by extending the base Metanorma images to add your own dependencies, fonts, or configuration.
Create a Dockerfile
like this:
FROM metanorma/metanorma:latest
# Install additional dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
your-package-name \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Add custom fonts
COPY ./custom-fonts/ /config/fonts/
# Add custom scripts
COPY ./scripts/ /usr/local/bin/
RUN chmod +x /usr/local/bin/*.sh
Build your custom image:
docker build -t my-organization/metanorma:custom .
Use your custom image the same way as the base image:
docker run -v "$PWD":/metanorma my-organization/metanorma:custom metanorma compile -t iso document.adoc
Warning
|
If you override the default Metanorma ENTRYPOINT or CMD in your
custom image, you will need to adjust the command accordingly.
|
The Makefile
makes developing the container much simpler.
To start the metanorma
container and enter it with bash
, all you need is:
make run-metanorma
To kill the container:
make kill-metanorma
The Makefile
supports the following commands related to running:
make {run,kill,rm,rmf}-metanorma
This Makefile
allows you to build the Metanorma container yourself.
All you have to set is a couple environment variables.
For example, if you use AWS' ECR, you can set this:
export NS_REMOTE=${account-id}.dkr.ecr.${region}.amazonaws.com/${account-name}
export DOCKER_LOGIN_CMD='aws ecr get-login --no-include-email \
--region=${region} --registry-ids=${ecr-registry-id}'
If you want to build other containers you can add these:
export ITEMS="1 2"
export IMAGE_TYPES="metanorma metanorma-ubuntu-21.10"
export VERSIONS="1.0 1.0"
export ROOT_IMAGES="ubuntu:20.04 ubuntu:21.10"
The environment variables are used for:
NS_REMOTE
-
the namespace for your remote repository (to separate from builds intended for local consumption)
DOCKER_LOGIN_CMD
-
how you authenticate against your repository
ITEMS
-
a sequential number list for iterating
IMAGE_TYPES
, its numbers are indexes to the content inIMAGE_TYPES
IMAGE_TYPES
-
the different containers you support.
VERSIONS
-
how resulting images are tagged. Currently we apply the same version across all images, which is defined in
VERSION.mak
ROOT_IMAGES
-
the container your new image should be based on
The Makefile
supports the following commands for building:
make {build,push,tag,clean-remote,clean-local}-{container-flavor}
All files relating to building a certain container flavor is located in the
{container-flavor}
directory.
For the metanorma
and mn
flavors, we update using this procedure:
pushd metanorma
bundle update
popd
# Gemfile.lock is updated
Then, we build and push the container:
make btp-metanorma
Lastly, we tag and push the built container as latest.
make latest-tp-metanorma
If you feel tired typing out this:
make build-metanorma tag-metanorma push-metanorma
We have a list of shortcut targets to save you from repeating fingers. For example:
# equivalent to make {build,push}-{container-flavor} latest-{tag,push}-{container-flavor}
make btp-metanorma latest-tp-metanorma
The shortcut targets are:
btp-{target}
-
build + tag + push
bt-{target}
-
build + tag
tp-{target}
-
tag + push
Currently our GitHub Actions workflow performs the push
step only for tags on main
branch.
To trigger a build, you need to create a tag on main
and push it.
The following example creates a tag v1.2.3
and pushes it to the Git repository:
git tag v1.2.3
git push origin main --tags
Important
|
The tag version must correlate with the versioning of metanorma-cli. |
Git tags allow you to quickly switch between different versions.
You can list available tags with:
git tag --list
The Metanorma Docker images are available as open source under the terms of the MIT License.
Copyright 2018-2025 Ribose Inc.