Docker Profiles with Nginx

Docker Profiles

The default Docker Compose configuration will start all containers defined in the Compose YAML file. Compose has a Profiles feature that allows for selectively starting containers. We can add a reverse proxy by adding a Nginx container in our Compose configuration. Nginx can intercept all requests and forward them to backend applications and services.


  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ 
|                                                                   |
|                             nginx-proxy                           |
|                            192.168.96.1                           |
|                          +-------------+                          |
|                          | Nginx Proxy |                          |
|                          |  container  |                          |
|                          +-------------+                          |
|                                 |                                 |
|                                 |                                 |
|            __ __ __ __ __ __ __ | __ __ __ __ __ __ __            |
|           |                     |                     |           |
|           |                     |                     |           |
|           v                     v                     v           |
|    +-------------+       +-------------+       +-------------+    |
|    |   Web Go    |       |   Web Py    |       |   Web App   |    |
|    |  container  |       |  container  |       |  container  |    |
|    +-------------+       +-------------+       +-------------+    |
|     192.168.96.2           192.168.96.3          192.168.96.4     |
|        web-go                web-py                 web-app       |
| __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |


services:
  nginx-proxy:
    container_name: nginx-proxy
    image: nginx:latest
    ...
  web-go:
    container_name: web-go
    profiles:
      - all
      - go
    ...
  web-py:
    container_name: web-py
    Profiles:
      - all
      - python
    ...
  web-app:
    container_name: web-app
    ...
        

Nginx Configuration

To make Profiles seamlessly work with Nginx, the configuration will need to handle unavailable endpoints. Otherwise the Nginx container will fail to start due to "host not found in upstream" error.

nginx   | Starting Nginx
nginx   | 2022/10/29 20:36:15 [emerg] 16#16: host not found in upstream "web-go" in /etc/nginx/conf.d/default.conf:12
nginx   | nginx: [emerg] host not found in upstream "web-go" in /etc/nginx/conf.d/default.conf:12

My initial workaround dynamically created the Nginx configuration during container initialization. I changed the configuration to use the internal Docker DNS Resolver along with setting the resolver directive per location in Nginx. Both options worked well. The latter option relies on DNS discovery to allow Nginx to start even if a upstream endpoint is down.

Conclusion

The COMPOSE_PROFILES environment variable is one of the key pieces. With this setup, Nginx will still start even if one of the containers is not running. We can start some or all services by starting with one of the commands below.

The nginx-docker-profiles GitHub repo has a working sample.