nginx-proxy
                                
                                 nginx-proxy copied to clipboard
                                
                                    nginx-proxy copied to clipboard
                            
                            
                            
                        Docker container for automatically creating nginx configuration based on active services in docker host.
Nginx-Proxy
Docker container for automatically creating nginx configuration based on active containers in docker host.
- Easy server configuration with environment variables
- Map multiple containers to different locations on same server
- Automatic Let's Encrypt ssl certificate registration
- Basic Authorization
Quick Setup
Setup nginx-proxy
docker pull mesudip/nginx-proxy
docker network create frontend;    # create a network for nginx proxy 
docker run  --network frontend \
            --name nginx-proxy \
            -v /var/run/docker.sock:/var/run/docker.sock:ro \
            -v /etc/ssl:/etc/ssl \
            -v /etc/nginx/dhparam:/etc/nginx/dhparam \
            -p 80:80 \
            -p 443:443 \
            -d --restart always mesudip/nginx-proxy
Setup your container
The only thing that matters is that the container shares at least one common network to the nginx container and VIRTUAL_HOST
environment variable is set.
Examples:
- WordPress
docker run --network frontend \
          --name wordpress-server \
          -e VIRTUAL_HOST="wordpress.example.com" \
          wordpress
- Docker Registry
docker run --network frontend \
         --name docker-registry \
         -e VIRTUAL_HOST='https://registry.example.com/v2 -> /v2; client_max_body_size 2g' \
         -e PROXY_BASIC_AUTH="registry.example.com -> user1:password,user2:password2,user3:password3" \
         registry:2
Details of Using nginx-proxy
- Configure nginx-proxy
- Configure enrironment VIRTUAL_HOST in your containers
- WebSockets
- Multiple hosts in same container
 
- Redirection
- Https and SSL
- Basic Authorization
- Default Server
Configure nginx-proxy
Following directries can be made into volumes to persist configurations
- /etc/nginx/conf.dnginx configuration directory. You can add your own server configurations here
- /etc/nginx/dhparamthe directory for storing DH parameter for ssl connections
- /etc/ssldirectory for storing ssl certificates, ssl private key and Let's Encrypt account key.
- /var/log/nginxdirectory nginx logs
- /tmp/acme-challengesdirectory for storing challenge content when registering Let's Encrypt certificate
Some of the default behaviour of nginx-proxy can be changed with environment variables.
- DHPARAM_SIZEDefault -- 2048: Set size of dhparam usd for ssl certificates
- CLIENT_MAX_BODY_SIZEDefault -- 1m: Set default max body size for all the servers.
Configure environment VIRTUAL_HOST in your containers
When you want a container's to be hosted on a domain set VIRTUAL_HOST environment variable to desired server_name entry.
For virtual host to work it requires
- nginx-proxy container to be on the same network as that of the container.
- port to be exposed in Docker file or while creating the container. When missing or if it has multiple exposed ports, port 80 is used by default.
- when hosting on port other than 80, make sure that your nginx-proxy container's port is bind-mounted to host port.
Some configurations possible through VIRTUAL_HOST
| VIRTUAL_HOST | release address | container path | container port | 
|---|---|---|---|
| example.com | http://example.com | / | exposed port | 
| example.com:8080 | http://example.com:8080 | / | exposed port | 
| example.com -> :8080 | http://example.com | / | 8080 | 
| https://example.com | https://example.com | / | exposed port | 
| example.com/api | http://example.com/api | / | exposed port | 
| example.com/api -> :8080/api | http://example.com/api | /api | 8080 | 
| https://example.com/api/v1:5001 -> :8080/api | https://example.com/api/v1:5001 | /api | 8080 | 
| wss://example.com/websocket | wss://example.com/websocket | / | exposed port | 
With VIRTUAL_HOST you can inject nginx directives into location each configuration must be separed with a ;
. You can see the possible directives in nginx documentation.
Example : VIRTUAL_HOST=somesite.example.com -> :8080 ;proxy_read_timeout  900;client_max_body_size 2g; will generate configuration as follows
server{
    server_name somesite.example.com;
    listen 80;
    location /{
        proxy_read_timeout 900;
        client_max_body_size 2g;
        proxy_pass http://127.2.3.4; // your container ip here
    }
}
Support for websocket
Exposing websocket requires the websocket endpoint to be explicitly configured via virtual host. The websocket endpoint can be ws:// or wss://.
If you want to use both websocket and non-websocket endpoints you will have to use multiple hosts
-e "VIRTUAL_HOST=wss://ws.example.com -> :8080/websocket"
Multiple Virtual Hosts on same container
To have multiple virtual hosts out of single container, you can use VIRTUAL_HOST1, VIRTUAL_HOST2, VIRTUAL_HOST3 and so on. In fact the only thing it matters is that the environment variable starts with VIRTUAL_HOST.
Example: setting up a go-ethereum node.
    docker run -d  --network frontend \
    -e "VIRTUAL_HOST1=https://ethereum.example.com -> :8545" \
    -e "VIRTUAL_HOST2=wss://ethereum.example.com/ws -> :8546" \
    ethereum/client-go \
    --rpc --rpcaddr "0.0.0.0"  --ws --wsaddr 0.0.0.0
Redirection
Let's say you want to serve a website on example.uk. You might want users visiting www.example.uk,example.com,www.example.com
to redirect to  example.uk.  You can simply use PROXY_FULL_REDIRECT environment variable.
 -e 'VIRTUAL_HOST=https://example.uk -> :7000' \
 -e 'PROXY_FULL_REDIRECT=example.com,www.example.com,www.example.uk->example.uk'
SSL Support
Issuing of SSL certificate is done using acme-nginx library for Let's Encrypt. If a precheck determines that the domain we are trying to issue certificate is not owned by current machine, a self-signed certificate is generated instead.
Using SSL for exposing endpoint
Certificate is automatically requested by the nginx-proxy container.
It requests for a challenge and verifies the challenge to obtain the certificate.
It is saved under directory /etc/ssl/certs and the private key is located inside
directoy /etc/ssl/private
Using your Own SSL certificate
If you already have a ssl certificate that you want to use, copy it under the /etc/ssl/certs directory and it's key under the directory /etc/ssl/private file should be named domain.crt and domain.key.
Wildcard certificates can be used. For example to use *.example.com wildcard, you should create files
/etc/ssl/certs/*.example.com.crt and /etc/ssl/private/*.example.com.key in the container's filesystem.
Note that *.com or * is not a valid wildcard. Wild card must have at least 2 dots.
/etc/ssl/certs/*.example.com.crt certificate will :
- be used for host1.example.com
- be used for www.example.com
- not be used for xyz.host1.example.com
- not be used for example.com
DHPARAM_SIZE :
Default size of DH key used for https connection is 2048bits. The key size can be changed by changing DHPARAM_SIZE environment variable
Manually obtaining certificate.
You can manually obtain Let's encrypt certificate using the nginx-proxy container. Note that you must set ip in DNS entry to point the correct server.
To issue a certificate for a domain you can simply use this command.
- 
docker exec nginx-proxy getssl www.example.comObtained certificate is saved on /etc/ssl/certs/www.example.comand private is saved on/etc/ssl/private/www.example.com
To issue certificates for multiple domain you can simply add more parameters to the above command
- 
docker exec nginx-proxy getssl www.example.com example.com ww.example.comAll the domains are registered on the same certificate and the filename is set from the first parameter passed to the command. so /etc/ssl/certs/www.example.comand/etc/ssl/private/www.example.comare generated
Use  docker exec nginx-proxy getssl --help   for getting help with the command
Basic Authorization
Basic Auth can be enabled on the container with environment variable PROXY_BASIC_AUTH.
- PROXY_BASIC_AUTH=user1:password1,user2:password2,user3:password3adds basic auth feature to your configured- VIRTUAL_HOSTserver root.
- PROXY_BASIC_AUTH=example.com/api/v1/admin -> admin1:password1,admin2:password2adds basic auth only to the location starting from- api/v1/admin
Note: Basic authorization will be ignored if the container's host doesn't use https
Default Server
When request comes for a server name that is not registered in nginx-proxy, It responds with 503 by default.
If you want the requested to be passed to a container instead, when setting up the container you can add PROXY_DEFAULT_SERVER=true environment along with VIRTUAL_HOST.
This much is sufficient for http connections, but for https connections, you might want to setup wildcard certificates so that your users dont get invalid ssl certificate errors.