Documentation

Last updated: 2026-06-21

Public hosting: DNS vhosts and ACME

This page covers reaching an OCI registry from the public internet: how a DNS hostname routes to a registry instance, and how Everlock issues and renews its TLS certificate automatically. It builds on the multi-instance model — the same vhost mechanism, pointed at a real domain.

For registries this matters more than for most services, because docker and podman expect a registry to speak HTTPS with a trusted certificate. A public vhost with an Everlock-issued Let's Encrypt certificate gives clients exactly that, so docker login, push, and pull work straight away.

The model in one paragraph

You map a public hostname to a registry as a vhost and point that hostname at your server in DNS. When the HTTP frontend has an HTTPS listener configured, it recognises the public name and obtains a Let's Encrypt certificate for it over the http-01 challenge. OCI vhosts are first-class HTTP vhosts, so this is the same machinery documented for publishing a site over HTTPS.

Prerequisites

  • an Everlock instance reachable from the internet on ports 80 and 443;
  • a domain name with a DNS A (and optionally AAAA) record pointing at the server's public IP;
  • the registry instance already created, with the public hostname as one of its vhosts.

The hostname must resolve to your server before the first request, because ACME validation hits http://<host>/.well-known/acme-challenge/... on port 80.

Step 1 — Configure the HTTP frontend for HTTPS

The HTTP frontend reads config/frontend-http.toml. An HTTPS listener plus an ACME contact email turn on certificate issuance:

listen_http  = "0.0.0.0:80"
listen_https = "0.0.0.0:443"
acme_email   = "ops@example.com"
redirect_http_to_https = true

This config is shared across every HTTP backend — sites, images, and registries all obtain certificates through it.

Step 2 — Give the registry a public vhost

Add the public hostname to the registry, either in config/oci-http.toml:

[registries.main]
store = "everlock-oci-main"
vhosts = ["registry.example.com"]

or from the admin console:

/oci set main vhost=registry.example.com

Then create the matching DNS record so the name resolves to your server's public IP. If Everlock is also your authoritative DNS server, the vhost is published as a synthesised A/AAAA record automatically; otherwise add the record at your DNS provider.

Step 3 — Restart to apply listener changes

Editing frontend-http.toml requires a process restart to bind the new listeners. On startup Everlock will:

  1. bind the HTTP listener on port 80;
  2. bind the HTTPS listener on port 443;
  3. recognise which vhosts are public hostnames;
  4. obtain a certificate for each public hostname;
  5. serve the registry over HTTPS as soon as the certificate is issued.
frontend-http: issuing or renewing certificate for registry.example.com
frontend-http: certificate persisted for registry.example.com
HTTPS server listening on https://0.0.0.0:443

Step 4 — Log in and push

Once HTTPS is live, point any OCI client at the host:

docker login registry.example.com
docker tag alpine:latest registry.example.com/library/alpine:latest
docker push registry.example.com/library/alpine:latest

Credentials are Everlock users, and the action is checked against the http/oci/<instance> grant — Reader for pull, Writer for push, Owner for delete. Grant push to a user with:

/users grant alice http/oci/main writer

How ACME works here

Everlock uses the http-01 challenge: Let's Encrypt requests http://<host>/.well-known/acme-challenge/<token> and Everlock answers it on the HTTP listener. Certificates and keys are stored in the system store under config/<host>/fullchain.pem and config/<host>/privkey.pem, and renew automatically. For staging tests against Let's Encrypt's rate-limited CA, point acme_directory at the staging endpoint as described in the HTTPS guide.

Public pull

A public hostname controls transport, while read access is still a grant. To make a registry world-readable, grant Reader to the built-in anon user:

/users grant anon http/oci/main reader

Pushes and deletes continue to require an authenticated user with the matching grant. See the registry model and auth reference for the full action mapping.

Multiple registries and domains

Each public vhost gets its own certificate, issued and renewed independently, so two patterns compose:

  • Several names for one registry — a registry can carry multiple public vhosts, each with its own certificate.
  • Several registries on different domains — run distinct registries (e.g. registry.example.com and registry-staging.example.com) from one process; routing by Host keeps them isolated.

Hosting from a home / NAT line

A residential line can serve a public registry. Because the server sees only a private address on its interface, point the DNS backend at your real public IPv4 with address_mode = discover, which probes public resolvers hourly. See DNS address modes and the NAT root-domain walkthrough. Forward ports 80 and 443 from the router to Everlock so ACME validation and HTTPS pulls reach it.

If a registry only ever serves the local network, you can skip public DNS and use mDNS on the LAN instead.

oci registry dns acme tls https vhost