Guide · Open source
How to use nginx-proxy: run several Docker apps behind one port 80
Updated · written with AI from the project's own documentation and checked against our catalogue data
nginx-proxy is a Docker container that runs nginx alongside docker-gen, so you can host several web apps behind one public port 80 entry point. This guide is for people who already run Docker on a host and point domains at it. By the end you will start the proxy, route a container with a VIRTUAL_HOST variable, and know which settings make a container reachable.
Quick start
- 1Pick a pinned image tag. Choose an explicit version such as nginxproxy/nginx-proxy:1.11 rather than latest, as the README advises for production.
- 2Start nginx-proxy. Run the docker run command with --publish 80:80 and the read-only Docker socket mount.
- 3Confirm DNS. Point your domain, for example foo.bar.com, at the host running nginx-proxy.
- 4Expose the app port. Make sure the app image uses EXPOSE or you pass --expose when starting it.
- 5Share a network. Attach the app and nginx-proxy to at least one common Docker network.
- 6Start the app with VIRTUAL_HOST. Run the app container with --env VIRTUAL_HOST set to its hostname.
- 7Test the request. Request http://your-hostname and check that the app responds.
What nginx-proxy does and how it works
nginx-proxy sets up a container running nginx and docker-gen. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
You never edit nginx config by hand for each app. When you start a container with a VIRTUAL_HOST variable, the proxy picks it up and routes requests for that hostname to the container.
Start the nginx-proxy container
Run the proxy with Docker. The README's example pins the image to the 1.11 tag and publishes port 80. It mounts the Docker socket read-only so the container can watch for container changes.
The README advises against using the latest tag for production, because those tags follow the main branch without a stability promise. Always pin an explicit version.
- --publish 80:80 exposes the proxy on host port 80.
- --volume /var/run/docker.sock:/tmp/docker.sock:ro gives the container read-only access to the Docker socket.
docker run --detach \
--name nginx-proxy \
--publish 80:80 \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
nginxproxy/nginx-proxy:1.11Route an app with VIRTUAL_HOST
Start any container you want proxied and set the VIRTUAL_HOST environment variable to the hostname it should answer to. The README example uses an nginx container with foo.bar.com.
If your DNS resolves foo.bar.com to the host running nginx-proxy, a request to http://foo.bar.com is routed to the container whose VIRTUAL_HOST matches.
docker run --detach \
--name your-proxied-app \
--env VIRTUAL_HOST=foo.bar.com \
nginxMake sure the proxied container is reachable
Two conditions must hold. First, the container must expose the port to be proxied, either with EXPOSE in its Dockerfile or with the --expose flag to docker run or docker create. Second, it must share at least one Docker network with the nginx-proxy container.
By default, if you do not pass --net when creating the nginx-proxy container, it attaches only to the default bridge network. It then cannot reach containers on other networks.
- Add EXPOSE in the Dockerfile or pass --expose to docker run.
- Put the app and nginx-proxy on a shared network, or the proxy will not connect to it.
- Do not put a port number in VIRTUAL_HOST; the README says this is not supported.
Choose an image variant
The images come in a Debian based version, an Alpine based version with the -alpine suffix, and a -dockergen version meant for separate containers alongside the official nginx image. Each variant is tagged with a version, such as 1.11, and the README shows each one.
- Debian: based on the nginx:mainline image, itself based on debian slim.
- Alpine: based on the nginx:alpine image, tagged with -alpine.
- Dockergen: for a separate-containers setup with the official nginx image, tagged with -dockergen.
docker pull nginxproxy/nginx-proxy:1.11
docker pull nginxproxy/nginx-proxy:1.11-alpine
docker pull nginxproxy/nginx-proxy:1.11-dockergenWhere to find more detail
The README points to a docs section in the repository for further topics, including virtual ports and custom external HTTP and HTTPS ports. Check those pages if your app listens on a non-standard port or you need a different external port.
What people use it for
- Hosting several web apps on one Docker host behind a single port 80 entry point.
- Letting new containers be picked up automatically without manual nginx edits.
- Routing different subdomains on one server to different containers.
- Running a self-hosted setup where Docker is already the standard way of deploying apps.
Frequently asked questions
Is nginx-proxy free to use?
The repository is licensed under the MIT licence, as listed on its page. The README also notes that ZeroSSL, which officially maintains the repository, offers free and paid SSL/TLS certificates, but using the proxy itself is governed by the MIT licence.
What do I need to run nginx-proxy?
The install method is Docker and the listed prerequisite is Docker. The proxy needs access to the Docker socket, which the README mounts read-only from /var/run/docker.sock.
Why is my container not reachable through nginx-proxy?
Check that the container exposes its port with EXPOSE or --expose, and that it shares at least one Docker network with nginx-proxy. By default the proxy joins only the bridge network if you do not pass --net.
Can I put a port number in VIRTUAL_HOST?
No. The README says providing a port number in VIRTUAL_HOST is not supported. It points to virtual ports and custom external HTTP/HTTPS ports in the docs for those cases.
Should I use the latest tag?
The README advises against it for production. The latest, alpine and dockergen tags point to the latest commit on main with no stability promise, so pin a specific version such as 1.11.
How does nginx-proxy compare to Traefik, Caddy or nginx Proxy Manager?
The comparable projects listed for this item are Traefik, Caddy, nginx Proxy Manager and jwilder/nginx-proxy. This guide does not benchmark them, so compare them on the features you need, such as how each routes traffic and how much config you write by hand.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
nginx-proxy suits people running several web apps on one Docker host who want new containers routed automatically through one port 80 entry point. It is a poor fit if you do not use Docker, or if you need a fully hand-tuned nginx configuration, since configs are generated for you.
Install options & downloads