Skip to main content
If your environment can’t pull from ghcr.io — registry policy, a source-audit requirement, or a build network that only reaches your own Artifactory or Nexus — build the same image CI builds. The entire build runs inside Docker: code generation, the frontend, the docs, the Go binary, and the full test suite, so a build that succeeds is a tested build. Git and Docker (with BuildKit) are the only host requirements.
Build from a release tag, and pass that tag as VERSION — it becomes the version the instance reports (in the app footer, logs, and telemetry), which upgrade tooling and support will ask for.

Every image the repository builds

The command above builds the product image, the Dockerfile’s default target and the only image published to ghcr.io. The same checkout builds two more for the load-testing harness described in Load Tests. Those are not published: building them here and pushing them to your own registry is how you get them. To build and push the load-test images next to the product image:
Build them from the same tag as the product image you are measuring.

What the build downloads

Every host the build downloads from, and the build arg that points it at your own registry instead: The mock upstream’s Dockerfile honors the same GOLANG_IMAGE, ALPINE_IMAGE and GOPROXY args; it installs no npm or apk packages, so the others don’t apply to it. The docs build makes a few more requests that no build arg repoints: Because the assets are copied into the image, the docs a running instance serves load nothing from these hosts or any other external host. The Mintlify CLI’s usage telemetry is turned off in the build (DO_NOT_TRACK=1), so the build doesn’t contact Mintlify’s analytics service. Nothing else is contacted. Code generation runs locally inside the build, and dependency integrity comes from the hashes committed in go.sum and the npm lockfiles — no external checksum service is consulted, and a mirror can’t substitute a package unnoticed. npm re-points lockfile URLs from the default registry to the one you configure. The Mintlify client archive from MINT_RELEASES_BASE is checked against the SHA-256 the repository pins (scripts/mint/client-sha256). A fully repointed build looks like:
Match the base image versions to the ones in the repository’s Dockerfile for the tag you’re building — they’re part of the tested build. If your network uses a forward proxy rather than registry mirrors, Docker’s predefined http_proxy / https_proxy / no_proxy build args cover the Go, npm and Alpine package downloads with no per-ecosystem configuration. The docs build’s downloads and the Mintlify CLI’s requests go directly, not through the proxy: mirror the client and icons (below), or allow their hosts through your firewall.

Mirror the docs downloads

Create a generic remote repository in your registry for each of the two Mintlify hosts, over https, with default settings, and pass each remote’s URL as its build arg. The build appends the host’s own path to the base: Both hosts are public S3 buckets behind CloudFront: anonymous GET, immutable paths. A path that doesn’t exist answers 403, not 404 — that’s how a public S3 bucket reports a missing key, not an authentication problem. The mirrors must:
  • Be named by hostname, not an IP address (DOCS_ICONS_BASE). The icon download reaches a private address only for a named host.
  • Serve the icons directly (DOCS_ICONS_BASE). The icon download doesn’t follow redirects, so a repository that redirects to cloud storage (in Artifactory, direct cloud storage download) can’t serve them. The client download follows redirects.
A build using the mirrors logs seed-client: installed client <version>, and for each docs edition a line naming the client it rendered with. A mirror that refuses the build’s credentials, redirects, or can’t be reached fails the build with its error. An icon the mirror doesn’t have is a warning that lists it; the build continues, and that icon shows blank.

If your registry needs credentials

Don’t put credentials in MINT_RELEASES_BASE or DOCS_ICONS_BASE: build args are recorded in the image’s history, so the build refuses a base URL that carries them. Put them in a netrc file instead, and pass it as a BuildKit secret, which is mounted only for the two steps that download from the mirrors and never written to a layer or the build cache:
artifactory.netrc
Only machine entries are read, and each is sent only to the host it names, only over https, and not along a redirect to another host; a default entry is ignored, so credentials never reach Mintlify’s public hosts. A mirror that answers 401 means the credentials are missing or refused. In Artifactory, a 403 can also mean credentials without read access to the repository. make docs reads the same file from the NETRC environment variable.

Running your build

Point your deployment at the pushed image: image.repository / image.tag with the Helm chart (see Private registries), the image: line in raw manifests, or the image in your docker run command. Upgrades are the same loop — check out the new tag, build, push, roll — reading the changelog’s Upgrade notes first, as with any upgrade. The load-test images go wherever Load Tests says to deploy them, by the names you pushed them under. What the running instance downloads is a separate, deliberately short list — see Network Access.