To host multiple domains on Docker containers with HTTPS, route incoming web traffic through one reverse proxy that selects the right container by hostname and obtains TLS certificates for each domain. You will need a server with Docker and Docker Compose, domain names you control, and DNS records pointing to the server’s public IP address.
What You’ll Need
- A Linux server or other Docker-capable host with a stable public IP address.
- Docker Engine and the Docker Compose plugin.
- At least two domains or subdomains, such as example.com and app.example.net.
- DNS access to create A records, and AAAA records only if the server is reachable over IPv6.
- Inbound TCP ports 80 and 443 allowed through the server firewall and any cloud network firewall.
Step-by-Step
- Point each domain to the server. In the DNS control panel for each domain, create an A record for the root name (often shown as
@) with the server’s IPv4 address. Add a record forwwwor other subdomains if you intend to serve them. If using IPv6, add an AAAA record only when IPv6 routing and firewall access are configured correctly. DNS changes may take time to reach resolvers; verify them withdig example.com Aanddig example.net A. - Prepare a project directory. On the server, create a directory such as
/opt/web-stackand move into it. Create a Docker network for the proxy and applications:docker network create proxy. The proxy and every web container it serves must join this network. Do not publish application ports to the public internet unless you specifically need direct access. - Create a Compose file for the proxy. A common setup uses Traefik or Caddy as the reverse proxy, with automatic certificate management. For example, a Traefik service can use a current official image, publish ports 80 and 443, mount the Docker socket read-only, and persist its ACME data in a named volume. Configure an HTTP entry point on port 80, an HTTPS entry point on 443, and an ACME certificate resolver using the HTTP-01 challenge. Set a valid email address for certificate notices. Keep the resolver’s storage file persistent and restrict its permissions as required by the proxy documentation.
- Start the reverse proxy and check it. Run
docker compose up -dfrom the directory containing its Compose file. Usedocker compose psanddocker compose logsto confirm it started without errors. The proxy must be able to bind ports 80 and 443; stop any existing web server already using them, or deliberately reconfigure the setup. Follow the chosen proxy’s current documentation for exact configuration syntax and secure Docker socket access. - Define each website as a separate service. Add each application to a Compose file and attach it to the
proxynetwork. For a sample app, the labels or proxy configuration should specify its hostname, the HTTPS entry point, the certificate resolver, and the application’s internal listening port. For example, routeexample.comto an app listening on port 8080 andexample.netto another app listening on port 3000. These are container ports, not necessarily ports exposed on the host. Use the application’s actual listening port, and ensure it listens on an interface reachable from the proxy, typically0.0.0.0. - Connect the services to the same network. In Compose, declare the existing network as external, with the name
proxy, for both proxy and application projects. If the proxy and apps are in a single Compose project, define a shared network there instead. Avoid relying on container IP addresses, which can change; the proxy should discover containers by service or Docker metadata. - Launch the applications and confirm routing. Run
docker compose up -dfor each app. Check that containers are running and inspect proxy logs for routing or network errors. Test each hostname in a browser usinghttps://. Also test plain HTTP and confirm it redirects to HTTPS if that behavior is configured. The certificate should match the hostname shown in the address bar. - Set up renewals and maintenance. Automatic certificate clients renew certificates before expiry, provided the proxy remains running, its certificate data persists, and domain validation can still reach the server. Back up persistent configuration and certificate data securely. Update containers deliberately, check release notes, and verify all domains after changes. Never publish private keys or certificate storage in a public repository.
Common Mistakes
A frequent cause of failed certificates is incorrect DNS: a stale A or AAAA record can send validation requests to the wrong machine. An AAAA record is especially problematic when IPv6 is advertised but not actually routed to the server. Check both address families and remove records you cannot serve.
Another mistake is publishing the same host port from multiple application containers. Usually only the reverse proxy should publish 80 and 443; applications communicate with it over Docker networking. Also confirm that the proxy target port is the container’s listening port, not a host-mapped port.
Do not assume a running container is reachable. The app and proxy may be on different networks, or the app may listen only on localhost inside its container. Finally, a certificate for one hostname does not automatically cover other domains. Configure every required hostname explicitly.
Tips
- Start with one domain and one application; add the next only after DNS, routing, and HTTPS work.
- Use separate, clear host rules for every domain, including
wwwif it should work. - Keep application ports private and expose only the proxy’s necessary public ports.
- Use persistent volumes for proxy configuration and certificate state so container recreation does not erase them.
- Use a staging certificate authority while testing repeated certificate issuance, then switch to production. Certificate authorities limit issuance, so avoid repeatedly deleting certificate state to troubleshoot.
Troubleshooting
The domain does not load: Check DNS resolution, server IP, firewall rules, and whether the proxy is listening on ports 80 and 443. Check for another process occupying either port with tools such as ss -lntp.
The wrong site appears: Confirm the requested hostname matches the proxy’s router rule exactly and that the correct application joined the proxy network. Check proxy logs and container labels or configuration for spelling errors and duplicate rules.
HTTPS fails or shows an invalid certificate: Verify the domain resolves to this server, port 80 is reachable for HTTP-01 validation, and the proxy can write its persistent certificate store. Check the certificate’s listed names and the client’s exact URL. If using DNS validation instead, confirm the DNS provider credentials and challenge configuration.
The proxy returns a gateway error: Confirm the application is healthy, listens on the configured internal port, and shares a network with the proxy. Use docker compose logs for both services; test connectivity from inside the proxy container if necessary.
Renewal fails: Keep the proxy running and its certificate data intact. Recheck DNS and inbound validation access, then read the ACME error in the logs. Avoid repeatedly requesting production certificates while experimenting.
Frequently Asked Questions
Can one server IP host several domains?
Yes. DNS can point multiple domains to one IP. The reverse proxy uses each request’s hostname to select the corresponding container.
Do I need a separate IP address for every domain?
No. For ordinary HTTP and HTTPS hosting, one public IP can serve many hostnames through a reverse proxy.
Can each domain use a different application container?
Yes. Configure a hostname rule for each application and route it to that container’s internal port.
Do I need to expose application ports publicly?
Usually not. Keep those ports on a Docker network shared with the proxy, and publish only the proxy’s web ports.
Can I use wildcard certificates?
Yes, if your proxy and certificate authority setup support DNS-01 validation. It requires suitable DNS-provider access and does not remove the need to configure routing for each hostname.
Will HTTPS renew if the container restarts?
It should if the proxy is configured for automatic renewal and its certificate state is stored persistently. Test the configuration and monitor logs rather than assuming renewal succeeded.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Skype Messaging Updates: What Changed
- Filter Values Within Tolerance: How It Works
- Why Chromecast Still Good Purchase
- Programming Skills for Job: What You Need120 hours
- Asus ProArt P16 Laptops: Specs, Pros, Cons & Buying Tips
- Analytical Database Engine: What It Does & When to Use