CLI, Docker, Cache and Private Repositories

This content was generated with the assistance of AI and should be verified against the official documentation of each tool before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

This page was written against Antora 3.2.1 and checked on 2026-10-26. The command line is the only way to run Antora that the project documents, so everything the playbook does can be adjusted from it, and everything that matters in continuous integration (fail on warnings, keep a cache, read credentials) is a CLI option or an environment variable. The examples use the Pocket Units playbook described in Playbook.

The antora command

Antora is started with antora (or npx antora when it is installed in the project and not on the PATH). Its usage line is antora [options] [[command] [args]]. The base call has four options and the only command that does work is generate, which is the default, so these two lines are equivalent:

npx antora generate antora-playbook.yml
npx antora antora-playbook.yml

The playbook path is resolved from the current working directory. The extension may be left out: Antora then looks for a YAML file, then JSON, then TOML.

Base option Purpose

-v, --version

Prints the version of the CLI and of the default site generator.

-r, --require <library>

Loads a Node.js module or script before the command runs. Used to register a custom generator or a credential manager.

--stacktrace

Shows the stack trace when the application fails. Added in 3.2 as a CLI flag for runtime.stacktrace.

-h, --help

Prints the usage. antora help generate and antora generate -h print the options of the command.

Running npx antora --version in the scratch project printed:

@antora/cli: 3.2.1
@antora/site-generator: 3.2.1

Options of generate

Every option of generate overrides the matching playbook key. Only -h, -r and -v have a short form. A boolean option is switched on by naming it, and the documentation gives no CLI syntax to switch off a boolean that the playbook file turned on. A value is passed as --option value or --option=value; an empty value needs --option=.

Option Overrides or does Environment variable

--attribute <name=value>

An AsciiDoc attribute set on every page. Repeatable.

none documented

--cache-dir <dir>

runtime.cache_dir.

ANTORA_CACHE_DIR

--clean

Removes the output directory before publishing (file system provider only).

none documented

--extension <extension>

Registers an extension. Repeatable. Negating an extension disables it (new in 3.2).

none documented

--fetch

runtime.fetch: update remote repositories and snapshot UI bundles.

none documented

--generator <name>

The generator package or script. Default @antora/site-generator.

none documented

--git-credentials-path <path>

git.credentials.path.

GIT_CREDENTIALS_PATH

--html-url-extension-style <choice>

urls.html_extension_style: default, drop or indexify.

none documented

--http-proxy, --https-proxy, --noproxy

The network keys.

http_proxy, https_proxy, no_proxy

--key <name=value>

An API key passed to the UI model. Repeatable.

none documented

--log-failure-level <choice>

runtime.log.failure_level: warn, error, fatal or none.

ANTORA_LOG_FAILURE_LEVEL

--log-file <file>

runtime.log.destination.file.

ANTORA_LOG_FILE

--log-format <choice>

json or pretty; pretty when CI=true or stdout is a terminal, json otherwise.

ANTORA_LOG_FORMAT

--log-level <choice>

The minimum level logged: all, trace, debug, info, warn (default), error, fatal, silent.

ANTORA_LOG_LEVEL

--log-level-format <choice>

label or number.

ANTORA_LOG_LEVEL_FORMAT

--quiet, --silent

--quiet suppresses stdout messages; --silent suppresses all messages.

none documented

--redirect-facility <choice>

urls.redirect_facility. See Publishing.

none documented

--start-page <page>

site.start_page.

none documented

--title <title>

site.title.

none documented

--to-dir <dir>

output.dir; default build/site.

none documented

--ui-bundle-url <url>

ui.bundle.url, a URL or a local path. The only value a playbook must provide.

none documented

--url <url>

site.url, without trailing slash.

URL

--asciidoc-sourcemap

Adds file and line information to AsciiDoc blocks.

none documented

The environment variable names in the table were also read from the schema of @antora/playbook-builder 3.2.1. The precedence is: CLI option, then environment variable, then the playbook file, then the default.

Fetching updates

By default Antora reads remote repositories and UI bundles from its cache and never touches the network after the first run. The --fetch option (or runtime.fetch: true) changes that: remote repositories already cloned are updated, repositories not yet cloned are cloned, and a UI bundle declared with snapshot: true is downloaded again. A bundle without snapshot is downloaded once and then served from the cache. Antora never runs git fetch on a local repository (a content source whose url is a path), because that would interfere with work in progress.

npx antora --fetch antora-playbook.yml

A continuous integration job that builds a site from release branches and keeps its cache between runs should pass --fetch, otherwise it publishes whatever the cache held when it started. A job on a fresh runner, such as this site’s nightly workflow, starts with an empty cache, so it clones every source anyway. This site’s local build uses npx antora --fetch antora-playbook.yml for the same reason. The scratch project of this page uses only local repositories, so the option had nothing to update there.

Logging, the failure level and exit code 2

Antora logs warnings and errors while it converts pages (a missing xref target, an unresolved include, a missing attribute). By default a build that logged only warnings and errors still exits with code 0, because the failure level is fatal. The failure level is the severity at which the process exit code becomes non-zero:

Value Exit code is 2 when the build logged

fatal (default)

a fatal message

error

an error or fatal message

warn

a warning, error or fatal message

none

never; the exit code is 0 even after an unhandled error

Exit code 2 for an exceeded failure level was introduced in Antora 3.2. The failure level does not stop the build: Antora still writes the whole site and then exits with the non-zero code. Other failures that stop the run, such as an unreadable playbook or a cache directory that cannot be created, are unhandled errors and end with code 1.

The Pocket Units scratch repository contains a page with a deliberately broken cross-reference. Antora logs it as an error. The same build with different failure levels gave:

npx antora antora-playbook.yml                                    # exit code 0
npx antora --log-failure-level warn antora-playbook.yml           # exit code 2
ANTORA_LOG_FAILURE_LEVEL=error npx antora antora-playbook.yml     # exit code 2
npx antora --log-failure-level none antora-playbook.yml           # exit code 0

In a terminal or with CI=true the log is human readable; otherwise it is one JSON object per line:

[10:04:15.869] ERROR (asciidoctor): target of xref not found: missing-page.adoc
    file: /antora/src/pocket-units/modules/ROOT/pages/broken.adoc
    source: /antora/src/pocket-units (branch: v2.0 <worktree>)
Site generation completed with errors.

For a documentation repository the sensible CI setting is --log-failure-level warn (or runtime.log.failure_level: warn in the playbook), so a broken link fails the pipeline. This is the setting to use together with the checks in Resource IDs and xrefs. The CLI option beats the playbook, so a pipeline can be stricter than a developer’s local build.

The cache directory

Antora keeps bare clones of remote content repositories and downloaded UI bundles in a cache directory. After one run the site can be generated offline. The default location depends on the system:

System Default cache directory

Linux

$XDG_CACHE_HOME/antora, or $HOME/.cache/antora when the variable is not set

macOS

$HOME/Library/Caches/antora

Windows

$APPDATA/antora/Caches

The directory is changed with runtime.cache_dir, --cache-dir or ANTORA_CACHE_DIR. A relative path starting with ~ resolves from the home directory, one starting with . resolves from the directory of the playbook file, and any other relative path (or ~+) resolves from the working directory. To clear the cache delete the directory; to refresh it use --fetch.

npx antora --cache-dir ./.cache --quiet antora-playbook.yml

Running this in the scratch project created .cache/content next to the playbook. The official documentation does not describe how to cache in a CI system; the usual approach, used by the GitLab example in Publishing, is to point the cache directory inside the workspace and tell the CI system to persist that directory between runs.

The antora/antora Docker image

The project publishes the image antora/antora for Docker and Podman. It is built only for linux/amd64, so on an Apple Silicon machine Docker runs it under emulation (the examples below pass --platform linux/amd64 and ran that way). Each Antora release, including prereleases, has one image tag; latest is the greatest stable release and testing the greatest prerelease. Pin the tag (antora/antora:3.2.1) in CI.

docker run -u $(id -u):$(id -g) -v $PWD:/antora --rm -t antora/antora:3.2.1 --cache-dir=./.cache --stacktrace antora-playbook.yml

The container’s working directory is /antora, so the playbook and the content are mounted there; the arguments after the image name are the arguments of the antora command. The -t flag is needed to see the progress bars of Git. -u makes the container write the site as the host user instead of root. On SELinux systems (Fedora) add :Z to the volume. Podman runs rootless and does not need -u.

The EACCES error when the UID is not 1000

The user inside the image has the home directory /, so the default cache path is /.cache/antora. A process running with another user ID cannot create it. This is the real output of the scratch project run as user 501 without --cache-dir:

[10:04:04.414] FATAL (antora): Failed to create content cache directory: /.cache/antora/content; EACCES: permission denied, mkdir '/.cache'

The exit code was 1. The documented fix is --cache-dir=./.cache, which places the cache under the mounted directory (relative to the playbook). The same run with the option, and with --log-failure-level warn to show the exit code, generated the site and exited with 2 because of the broken link:

Site generation completed with errors.
Open file:///antora/build/site/index.html in a browser to view your site.

Setting the HOME variable is sometimes suggested; the image documentation does not describe it, so prefer --cache-dir or ANTORA_CACHE_DIR. Add .cache to .gitignore and to .dockerignore.

Extensions in a derived image

The image contains Antora and its Node.js runtime only. An extension is added by building a derived image:

FROM antora/antora:3.2.1
RUN yarn global add @sntke/antora-mermaid-extension@0.0.6
docker build --pull --platform linux/amd64 -t local/antora:custom -f Dockerfile.custom .

The derived image was built successfully. The extension is then listed in the playbook (antora.extensions) as for a local install; the build with it was not executed. The image does not include the git binary: it ships the isogit command, a CLI for the JavaScript Git client Antora uses.

Private repositories

Antora reads Git repositories with a JavaScript client over HTTP(S). Authentication is therefore Basic authentication with a username and password, or more commonly an access token.

  • Deploy keys and SSH agents are not supported. A content source URL of the form git@host:org/repo.git is converted to HTTPS, and if the conversion fails the playbook must be changed to the right HTTPS URL.

  • A personal access token reaches every repository its owner can read, so use it only on a developer machine. A deploy token is bound to one project and suits a CI server.

  • Some hosts refuse passwords, and an account with two-factor authentication cannot use one: use a token.

The credential store

The default credential manager reads a file in the format of the Git credential store, one entry per line: https://<credentials>@<host>;. The credentials are username:password or token: (note the trailing colon). Usernames and passwords containing characters such as /, # or : are percent-encoded. The file is $HOME/.git-credentials, or $XDG_CONFIG_HOME/git/credentials when the first does not exist; it must be a file, and should be readable only by its owner.

https://<YOUR_GITHUB_TOKEN>:@github.com
https://oauth2:<YOUR_GITLAB_TOKEN>@gitlab.com
https://gitlab+deploy-token-<TOKEN_ID>:<YOUR_DEPLOY_TOKEN>@gitlab.com

The three lines are the formats for a GitHub token (a fine-grained token needs the Contents permission), a GitLab token and a GitLab deploy token. A path may be appended to a line (https://<credentials>@github.com/org/project-docs) to restrict the entry to one repository. All values above are placeholders.

Other ways to provide credentials

CLI option Environment variable and playbook key Purpose

--git-credentials-path <path>

GIT_CREDENTIALS_PATH, git.credentials.path

Reads the credential store from another file.

none

GIT_CREDENTIALS, git.credentials.contents

The credentials themselves, one entry per line or separated by commas. Best for CI where the variable is a secret.

GIT_CREDENTIALS='https://<YOUR_GITHUB_TOKEN>:@github.com' npx antora --fetch antora-playbook.yml
npx antora --git-credentials-path ./.git-credentials --fetch antora-playbook.yml

Credentials can also be written inside the url of a content source, but anyone who can read the playbook then sees them; if that is unavoidable, put a variable name in the playbook and substitute it in CI before the build. A custom credential manager (exporting fill, approved and rejected) can be registered under git.plugins.credential_manager or with --require, for example to delegate to git credential fill.

In Docker, pass the secret as an environment variable (-e GIT_CREDENTIALS), or mount a credentials file and give its path with --git-credentials-path. The private-repository examples on this page were not executed: they need a real remote repository and token. The mechanism is the one documented by the Antora project.

Pitfalls

  • The default failure level is fatal, so a CI build with broken links is green until --log-failure-level warn (or error) is set.

  • Without --fetch a CI job reuses the cache; with a persisted cache and no --fetch it never sees new commits.

  • In Docker, a UID other than 1000 needs --cache-dir; without -u the container writes the site as root.

  • --silent suppresses all messages, including the reason a build failed. Read the exit code.

  • Percent-encode special characters in the credential store and keep it out of the repository.