From f8accc344628555488e8003f49bfc58aa8f54ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D0=B0=D0=BA=20=D0=90=D1=80=D1=82=D0=B5?= =?UTF-8?q?=D0=BC?= Date: Wed, 15 Jul 2026 10:18:11 +0300 Subject: [PATCH 1/4] docs: angie-docker-proxy deployment guide --- src/cookbook/angie-docker-proxy.md | 472 +++++++++++++++++++++++++++++ 1 file changed, 472 insertions(+) create mode 100644 src/cookbook/angie-docker-proxy.md diff --git a/src/cookbook/angie-docker-proxy.md b/src/cookbook/angie-docker-proxy.md new file mode 100644 index 00000000..0476efee --- /dev/null +++ b/src/cookbook/angie-docker-proxy.md @@ -0,0 +1,472 @@ +# Deploying Yii applications with Angie Docker Proxy + +Angie Docker Proxy is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the +applications, reads the Docker API through the Docker socket, discovers containers using the `VIRTUAL_HOST` and +`VIRTUAL_PORT` environment variables, generates the Angie configuration, and automatically obtains TLS certificates +using ACME. + +This approach is useful when you need to run several web applications on one server and enable HTTPS for them without +manually editing the reverse proxy configuration for each domain. + +In this example, we'll deploy a minimal Yii application with Angie Docker Proxy. The example is small and clearly +demonstrates how the proxy, ACME, and the addition of new services work. + +```mermaid +graph LR + A[Internet] --> B[Reverse Proxy: Angie] + B --> C[app1.example.com] + B --> D[app2.example.com] + + subgraph Docker Compose Project + B + C + D + end +``` + +## Prerequisites + +- A server with a fresh Linux distribution. +- A domain name pointing to your server's IP address. +- Docker and Docker Compose. +- Open TCP ports `80` and `443`. +- SSH access to your server. +- Basic knowledge of Docker and command-line tools. + +## `yii-app` project structure + +The prepared `yii-app` project uses the following project structure: + +```text +yii-angie-demo/ +├── docker-compose.yml +└── proxy +| ├── Dockerfile +| ├── entrypoint.sh +| └── templates +| └── angie.tmpl +└── yii-app + ├── Dockerfile + └── public + └── index.php +``` + +`yii-app/Dockerfile`: + +```dockerfile +FROM php:8.3-apache +COPY public/ /var/www/html/ +EXPOSE 80 +``` + +`yii-app/public/index.php`: + +```php + + + + + + <?= htmlspecialchars($appName, ENT_QUOTES) ?> + + +
+

+

This is a demo Yii3 application with Angie Docker Proxy.

+

Host:

+

Forwarded protocol:

+

Forwarded for:

+
+ + +``` + +#### Detailed description of Angie Docker Proxy + +`Dockerfile`: + +```dockerfile +FROM ubuntu:24.04 + +ARG DOCKER_GEN_VERSION=0.16.0 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates curl tar gnupg \ + && install -d -m 0755 /etc/apt/keyrings \ + && curl --retry 8 --retry-all-errors --retry-delay 3 --connect-timeout 20 -fsSL https://angie.software/keys/angie-signing.gpg -o /etc/apt/keyrings/angie.gpg \ + && chmod 0644 /etc/apt/keyrings/angie.gpg \ + && . /etc/os-release \ + && echo "deb [signed-by=/etc/apt/keyrings/angie.gpg] https://download.angie.software/angie/ubuntu/24.04 ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/angie.list \ + && apt-get update \ + && apt-get install -y --no-install-recommends angie \ + && curl --retry 8 --retry-all-errors --retry-delay 3 --connect-timeout 20 -fsSL "https://github.com/nginx-proxy/docker-gen/releases/download/${DOCKER_GEN_VERSION}/docker-gen-linux-amd64-${DOCKER_GEN_VERSION}.tar.gz" \ + | tar -xz -C /usr/local/bin docker-gen \ + && chmod +x /usr/local/bin/docker-gen \ + && rm -rf /var/lib/apt/lists/* + +COPY templates/angie.tmpl /etc/docker-gen/templates/angie.tmpl +COPY entrypoint.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +EXPOSE 80 443 + +ENTRYPOINT ["/entrypoint.sh"] +``` + +- Installing Angie OSS. +- Installing `docker-gen`. +- Copying the `entrypoint.sh` script and `angie.tmpl` template. +- Exposing ports `80` and `443` for proxying. +- Starting the `entrypoint.sh` script. + +`entrypoint.sh`: + +```sh +#!/bin/sh +set -e + +export DOCKER_HOST=unix:///tmp/docker.sock + +mkdir -p /etc/angie /etc/angie/conf.d +mkdir -p /var/lib/angie/acme + +docker-gen -watch=false /etc/docker-gen/templates/angie.tmpl /etc/angie/angie.conf + +angie -t -c /etc/angie/angie.conf +angie -c /etc/angie/angie.conf + +exec docker-gen -watch -notify "angie -s reload" /etc/docker-gen/templates/angie.tmpl /etc/angie/angie.conf +``` + +Inside the container, `entrypoint.sh` specifies where the Docker API is located: + +```sh +export DOCKER_HOST=unix:///tmp/docker.sock +``` + +Creating directories for `angie.conf` and ACME. + +Starting `docker-gen` in `-watch` mode. + +`templates/angie.tmpl`: + +```text +events {} + +http { +{{ $acmeURL := or (index .Env "ANGIE_ACME_URL") "https://acme-v02.api.letsencrypt.org/directory" }} +{{ $acmeEmail := or (index .Env "ANGIE_ACME_EMAIL") "admin@example.com" }} +{{ $resolver := or (index .Env "ANGIE_RESOLVER") "1.1.1.1 8.8.8.8" }} +{{ $resolverValid := or (index .Env "ANGIE_RESOLVER_VALID") "300s" }} +{{ $proxyNetwork := or (index .Env "ANGIE_PROXY_NETWORK") "proxy" }} + + resolver {{ $resolver }} valid={{ $resolverValid }}; + +{{ range $host, $containers := groupByMulti . "Env.VIRTUAL_HOST" "," }} +{{ $slug := replace (replace (toLower $host) "." "_" -1) "-" "_" -1 }} + acme_client {{ $slug }} {{ $acmeURL }} + email={{ $acmeEmail }} + challenge=http; +{{ end }} + + access_log /dev/stdout; + error_log /dev/stderr notice; + + server { + listen 80 default_server; + server_name _; + return 404; + } + +{{ range $host, $containers := groupByMulti . "Env.VIRTUAL_HOST" "," }} +{{ $container := index $containers 0 }} +{{ $port := or (index $container.Env "VIRTUAL_PORT") "80" }} +{{ $slug := replace (replace (toLower $host) "." "_" -1) "-" "_" -1 }} +{{ range $network := $container.Networks }} +{{ if eq $network.Name $proxyNetwork }} + server { + listen 80; + server_name {{ $host }}; + + location / { + return 301 https://$host$request_uri; + } + } + + server { + listen 443 ssl; + server_name {{ $host }}; + + acme {{ $slug }}; + + ssl_certificate $acme_cert_{{ $slug }}; + ssl_certificate_key $acme_cert_key_{{ $slug }}; + + location / { + proxy_pass http://{{ $network.IP }}:{{ $port }}; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + } + } +{{ end }} +{{ end }} +{{ end }} +} +``` + +`templates/angie.tmpl` is a Go template for `docker-gen`. It is used to generate the final Angie configuration at +`/etc/angie/angie.conf`. + +The template reads container metadata from Docker and selects services that have `VIRTUAL_HOST` and `VIRTUAL_PORT` +configured. + +For every domain it finds, the template: + +- Generates a separate `acme_client`. +- Converts the domain into a slug for the ACME client name, for example, + `example-demo.example.com -> example_demo_example_com`. +- Creates an HTTPS `server` block on port `443`. +- Configures the Angie ACME certificate using `$acme_cert_` and `$acme_cert_key_`. +- Selects the container IP only from the shared `proxy` network. +- Generates `proxy_pass` for the container's internal port specified by `VIRTUAL_PORT`. + +The template also uses the following settings from the proxy container: + +- `ANGIE_ACME_EMAIL`. +- `ANGIE_ACME_URL`. +- `ANGIE_RESOLVER`. +- `ANGIE_RESOLVER_VALID`. +- `ANGIE_PROXY_NETWORK`. + +When a new container with `VIRTUAL_HOST` and `VIRTUAL_PORT` appears, `docker-gen` regenerates `angie.conf`, after which +Angie reloads the configuration with `angie -s reload`. + +## `docker-compose.yml` structure + +The following `docker-compose.yml` configuration uses Angie Docker Proxy: + +```yaml +services: + angie-proxy: + build: + context: ./proxy + environment: + - ANGIE_ACME_EMAIL=admin@example.com + - ANGIE_ACME_URL=https://acme-v02.api.letsencrypt.org/directory + - ANGIE_RESOLVER=1.1.1.1 8.8.8.8 + - ANGIE_RESOLVER_VALID=300s + - ANGIE_PROXY_NETWORK=proxy + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - angie_acme:/var/lib/angie/acme + networks: + - proxy + + yii-app: + build: + context: ./yii-app + environment: + - VIRTUAL_HOST=angie-demo.example.ru + - VIRTUAL_PORT=80 + - APP_NAME=Yii demo behind Angie HTTPS + networks: + - proxy + +networks: + proxy: + name: proxy + +volumes: + angie_acme: +``` + +## Starting the application + +To start the application, run the Docker Compose build: + +```bash +docker compose up -d --build +``` + +For Angie Docker Proxy to discover a service, the application must be attached to the same `proxy` network and have +two environment variables: + +```yaml +environment: + - VIRTUAL_HOST=example-demo.example.com + - VIRTUAL_PORT=80 +``` + +`VIRTUAL_HOST` is the application's public domain. + +`VIRTUAL_PORT` is the container's internal port to which Angie should proxy requests. + +Angie Docker Proxy automatically discovers `VIRTUAL_HOST` and `VIRTUAL_PORT` from the environment variables and issues +certificates using the Angie ACME module and Let's Encrypt. + +Adding a new application or service to `docker-compose.yml`: + +```yaml +second_app: + image: traefik/whoami + environment: + - VIRTUAL_HOST=example-demo2.example.com + - VIRTUAL_PORT=80 +networks: + - proxy +``` + +After adding the new service block, apply the changes: + +```bash +docker compose up -d +``` + +## How it works + +Angie Docker Proxy runs in a separate container alongside the applications. The container includes Angie, `docker-gen`, +the `angie.tmpl` configuration template, and the entrypoint script. When `docker compose up -d` runs, the `angie-proxy` +container starts and the Docker socket is mounted into it in read-only mode. + +The Angie Docker Proxy image contains: + +- Angie OSS. +- `docker-gen`. +- The `angie.tmpl` template. +- `entrypoint.sh`, which starts configuration generation and Angie itself. + +Workflow: + +After `docker compose up -d --build` runs, the following sequence takes place: + +```text +Docker API +-> docker-gen +-> /etc/angie/angie.conf +-> angie -t +-> Angie startup +-> ACME certificate issuance +-> reverse proxy to yii-app +``` + +`docker-gen` monitors the Docker socket: + +```yaml +volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro +``` + +Inside the container, `entrypoint.sh` specifies where the Docker API is located: + +```sh +export DOCKER_HOST=unix:///tmp/docker.sock +``` + +After startup, `docker-gen` remains in watch mode. When a new container with `VIRTUAL_HOST` appears, it regenerates +`/etc/angie/angie.conf` and runs: + +```sh +angie -s reload +``` + +For each domain, the template generates a separate `acme_client`. The client name is built from the domain by replacing +dots and hyphens with underscores. + +Example: + +`example-demo.example.com -> example_demo_example_com` + +Certificates are stored separately for each server. + +When generating an upstream, the container IP is selected only from the shared `proxy` network. This is important +because a container can be connected to multiple Docker networks, but the reverse proxy needs an address from the +network shared with `angie-proxy`. + +## Verification + +Check the containers: + +```bash +docker compose ps +``` + +Check the HTTP redirect: + +```bash +curl -I http://example-demo.example.com/ +``` + +Expected result: + +```text +HTTP/1.1 301 Moved Permanently +Location: https://example-demo.example.com/ +``` + +Check HTTPS: + +```bash +curl -I https://example-demo.example.com/ +``` + +Expected result: + +```text +HTTP/1.1 200 OK +Server: Angie/... +``` + +Check the certificate: + +```bash +echo | openssl s_client \ + -connect example-demo.example.com:443 \ + -servername example-demo.example.com 2>/dev/null \ + | openssl x509 -noout -issuer -subject -dates +``` + +Expected issuer: + +```text +Let's Encrypt +``` + +## Logs + +Proxy logs: + +```bash +docker compose logs -f angie-proxy +``` + +## Stopping the services + +Stop the services: + +```bash +docker compose down +``` + +Stop the services and remove the certificates: + +```bash +docker compose down -v +``` From c831752697c3c0bacd5bf70af5a0367380d22752 Mon Sep 17 00:00:00 2001 From: Artem Novak <97213086+artnovak@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:08:33 +0300 Subject: [PATCH 2/4] Update angie-docker-proxy.md --- src/cookbook/angie-docker-proxy.md | 58 +++++++++--------------------- 1 file changed, 16 insertions(+), 42 deletions(-) diff --git a/src/cookbook/angie-docker-proxy.md b/src/cookbook/angie-docker-proxy.md index 0476efee..eb8d5d86 100644 --- a/src/cookbook/angie-docker-proxy.md +++ b/src/cookbook/angie-docker-proxy.md @@ -44,52 +44,22 @@ yii-angie-demo/ | ├── Dockerfile | ├── entrypoint.sh | └── templates -| └── angie.tmpl +| └── angie.tmpl └── yii-app - ├── Dockerfile - └── public - └── index.php + ├── ... + ├── ... + └── ``` -`yii-app/Dockerfile`: +Create `yii-app` from the official Yii application template: -```dockerfile -FROM php:8.3-apache -COPY public/ /var/www/html/ -EXPOSE 80 +```bash +composer create-project yiisoft/app yii-app ``` -`yii-app/public/index.php`: - -```php - - - - - - <?= htmlspecialchars($appName, ENT_QUOTES) ?> - - -
-

-

This is a demo Yii3 application with Angie Docker Proxy.

-

Host:

-

Forwarded protocol:

-

Forwarded for:

-
- - -``` + +This article focuses on Angie Docker Proxy, so the internal Yii application configuration is not covered here. The +application container uses its production Docker target and exposes HTTP on port `80`. #### Detailed description of Angie Docker Proxy @@ -263,8 +233,7 @@ The following `docker-compose.yml` configuration uses Angie Docker Proxy: ```yaml services: angie-proxy: - build: - context: ./proxy + image: angiesoftware/proxy:latest environment: - ANGIE_ACME_EMAIL=admin@example.com - ANGIE_ACME_URL=https://acme-v02.api.letsencrypt.org/directory @@ -470,3 +439,8 @@ Stop the services and remove the certificates: ```bash docker compose down -v ``` + +## For more information + +- [Yii Application Template](https://github.com/yiisoft/app) +- [Docker Compose documentation]( From 7d30155bf0561339887c253187d7dececc4456ec Mon Sep 17 00:00:00 2001 From: Artem Novak <97213086+artnovak@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:41:26 +0300 Subject: [PATCH 3/4] Update angie-docker-proxy.md --- src/cookbook/angie-docker-proxy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cookbook/angie-docker-proxy.md b/src/cookbook/angie-docker-proxy.md index eb8d5d86..22655212 100644 --- a/src/cookbook/angie-docker-proxy.md +++ b/src/cookbook/angie-docker-proxy.md @@ -1,6 +1,6 @@ # Deploying Yii applications with Angie Docker Proxy -Angie Docker Proxy is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the +[Angie Docker Proxy ](https://hub.docker.com/r/angiesoftware/proxy)is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the applications, reads the Docker API through the Docker socket, discovers containers using the `VIRTUAL_HOST` and `VIRTUAL_PORT` environment variables, generates the Angie configuration, and automatically obtains TLS certificates using ACME. From 4da2d3a6e404f0cd7b28493a57fa56a32135a21c Mon Sep 17 00:00:00 2001 From: Artem Novak <97213086+artnovak@users.noreply.github.com> Date: Wed, 22 Jul 2026 13:09:57 +0300 Subject: [PATCH 4/4] Update angie-docker-proxy.md --- src/cookbook/angie-docker-proxy.md | 324 +++++------------------------ 1 file changed, 49 insertions(+), 275 deletions(-) diff --git a/src/cookbook/angie-docker-proxy.md b/src/cookbook/angie-docker-proxy.md index 22655212..7d7035e5 100644 --- a/src/cookbook/angie-docker-proxy.md +++ b/src/cookbook/angie-docker-proxy.md @@ -1,6 +1,6 @@ # Deploying Yii applications with Angie Docker Proxy -[Angie Docker Proxy ](https://hub.docker.com/r/angiesoftware/proxy)is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the +[Angie Docker Proxy](https://hub.docker.com/r/angiesoftware/proxy) is a small reverse proxy for Docker Compose projects. It runs in a separate container alongside the applications, reads the Docker API through the Docker socket, discovers containers using the `VIRTUAL_HOST` and `VIRTUAL_PORT` environment variables, generates the Angie configuration, and automatically obtains TLS certificates using ACME. @@ -8,14 +8,15 @@ using ACME. This approach is useful when you need to run several web applications on one server and enable HTTPS for them without manually editing the reverse proxy configuration for each domain. -In this example, we'll deploy a minimal Yii application with Angie Docker Proxy. The example is small and clearly -demonstrates how the proxy, ACME, and the addition of new services work. +In this example, we'll connect a containerized Yii application to Angie Docker Proxy and configure automatic HTTPS. + +This guide assumes that your Yii application is already packaged as a Docker image and accepts HTTP requests on port 80. Building and configuring the application image is outside the scope of this guide. ```mermaid graph LR A[Internet] --> B[Reverse Proxy: Angie] - B --> C[app1.example.com] - B --> D[app2.example.com] + B --> C[Yii application] + B --> D[Another application] subgraph Docker Compose Project B @@ -33,202 +34,22 @@ graph LR - SSH access to your server. - Basic knowledge of Docker and command-line tools. -## `yii-app` project structure +## Project structure -The prepared `yii-app` project uses the following project structure: +The example requires a single Docker Compose configuration: ```text yii-angie-demo/ -├── docker-compose.yml -└── proxy -| ├── Dockerfile -| ├── entrypoint.sh -| └── templates -| └── angie.tmpl -└── yii-app - ├── ... - ├── ... - └── -``` - -Create `yii-app` from the official Yii application template: - -```bash -composer create-project yiisoft/app yii-app -``` - - -This article focuses on Angie Docker Proxy, so the internal Yii application configuration is not covered here. The -application container uses its production Docker target and exposes HTTP on port `80`. - -#### Detailed description of Angie Docker Proxy - -`Dockerfile`: - -```dockerfile -FROM ubuntu:24.04 - -ARG DOCKER_GEN_VERSION=0.16.0 - -RUN apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates curl tar gnupg \ - && install -d -m 0755 /etc/apt/keyrings \ - && curl --retry 8 --retry-all-errors --retry-delay 3 --connect-timeout 20 -fsSL https://angie.software/keys/angie-signing.gpg -o /etc/apt/keyrings/angie.gpg \ - && chmod 0644 /etc/apt/keyrings/angie.gpg \ - && . /etc/os-release \ - && echo "deb [signed-by=/etc/apt/keyrings/angie.gpg] https://download.angie.software/angie/ubuntu/24.04 ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/angie.list \ - && apt-get update \ - && apt-get install -y --no-install-recommends angie \ - && curl --retry 8 --retry-all-errors --retry-delay 3 --connect-timeout 20 -fsSL "https://github.com/nginx-proxy/docker-gen/releases/download/${DOCKER_GEN_VERSION}/docker-gen-linux-amd64-${DOCKER_GEN_VERSION}.tar.gz" \ - | tar -xz -C /usr/local/bin docker-gen \ - && chmod +x /usr/local/bin/docker-gen \ - && rm -rf /var/lib/apt/lists/* - -COPY templates/angie.tmpl /etc/docker-gen/templates/angie.tmpl -COPY entrypoint.sh /entrypoint.sh - -RUN chmod +x /entrypoint.sh - -EXPOSE 80 443 - -ENTRYPOINT ["/entrypoint.sh"] -``` - -- Installing Angie OSS. -- Installing `docker-gen`. -- Copying the `entrypoint.sh` script and `angie.tmpl` template. -- Exposing ports `80` and `443` for proxying. -- Starting the `entrypoint.sh` script. - -`entrypoint.sh`: - -```sh -#!/bin/sh -set -e - -export DOCKER_HOST=unix:///tmp/docker.sock - -mkdir -p /etc/angie /etc/angie/conf.d -mkdir -p /var/lib/angie/acme - -docker-gen -watch=false /etc/docker-gen/templates/angie.tmpl /etc/angie/angie.conf - -angie -t -c /etc/angie/angie.conf -angie -c /etc/angie/angie.conf - -exec docker-gen -watch -notify "angie -s reload" /etc/docker-gen/templates/angie.tmpl /etc/angie/angie.conf -``` - -Inside the container, `entrypoint.sh` specifies where the Docker API is located: - -```sh -export DOCKER_HOST=unix:///tmp/docker.sock -``` - -Creating directories for `angie.conf` and ACME. - -Starting `docker-gen` in `-watch` mode. - -`templates/angie.tmpl`: - -```text -events {} - -http { -{{ $acmeURL := or (index .Env "ANGIE_ACME_URL") "https://acme-v02.api.letsencrypt.org/directory" }} -{{ $acmeEmail := or (index .Env "ANGIE_ACME_EMAIL") "admin@example.com" }} -{{ $resolver := or (index .Env "ANGIE_RESOLVER") "1.1.1.1 8.8.8.8" }} -{{ $resolverValid := or (index .Env "ANGIE_RESOLVER_VALID") "300s" }} -{{ $proxyNetwork := or (index .Env "ANGIE_PROXY_NETWORK") "proxy" }} - - resolver {{ $resolver }} valid={{ $resolverValid }}; - -{{ range $host, $containers := groupByMulti . "Env.VIRTUAL_HOST" "," }} -{{ $slug := replace (replace (toLower $host) "." "_" -1) "-" "_" -1 }} - acme_client {{ $slug }} {{ $acmeURL }} - email={{ $acmeEmail }} - challenge=http; -{{ end }} - - access_log /dev/stdout; - error_log /dev/stderr notice; - - server { - listen 80 default_server; - server_name _; - return 404; - } - -{{ range $host, $containers := groupByMulti . "Env.VIRTUAL_HOST" "," }} -{{ $container := index $containers 0 }} -{{ $port := or (index $container.Env "VIRTUAL_PORT") "80" }} -{{ $slug := replace (replace (toLower $host) "." "_" -1) "-" "_" -1 }} -{{ range $network := $container.Networks }} -{{ if eq $network.Name $proxyNetwork }} - server { - listen 80; - server_name {{ $host }}; - - location / { - return 301 https://$host$request_uri; - } - } - - server { - listen 443 ssl; - server_name {{ $host }}; - - acme {{ $slug }}; - - ssl_certificate $acme_cert_{{ $slug }}; - ssl_certificate_key $acme_cert_key_{{ $slug }}; - - location / { - proxy_pass http://{{ $network.IP }}:{{ $port }}; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Host $host; - } - } -{{ end }} -{{ end }} -{{ end }} -} +└── docker-compose.yml ``` -`templates/angie.tmpl` is a Go template for `docker-gen`. It is used to generate the final Angie configuration at -`/etc/angie/angie.conf`. - -The template reads container metadata from Docker and selects services that have `VIRTUAL_HOST` and `VIRTUAL_PORT` -configured. - -For every domain it finds, the template: - -- Generates a separate `acme_client`. -- Converts the domain into a slug for the ACME client name, for example, - `example-demo.example.com -> example_demo_example_com`. -- Creates an HTTPS `server` block on port `443`. -- Configures the Angie ACME certificate using `$acme_cert_` and `$acme_cert_key_`. -- Selects the container IP only from the shared `proxy` network. -- Generates `proxy_pass` for the container's internal port specified by `VIRTUAL_PORT`. - -The template also uses the following settings from the proxy container: - -- `ANGIE_ACME_EMAIL`. -- `ANGIE_ACME_URL`. -- `ANGIE_RESOLVER`. -- `ANGIE_RESOLVER_VALID`. -- `ANGIE_PROXY_NETWORK`. +## Configuring Docker Compose -When a new container with `VIRTUAL_HOST` and `VIRTUAL_PORT` appears, `docker-gen` regenerates `angie.conf`, after which -Angie reloads the configuration with `angie -s reload`. +Create `docker-compose.yml` with the following configuration. Replace: -## `docker-compose.yml` structure - -The following `docker-compose.yml` configuration uses Angie Docker Proxy: +- `admin@example.com` with your email address; +- `registry.example.com/yii-app:1.0.0` with your application image; +- `example-demo.example.com` with the domain pointing to your server. ```yaml services: @@ -250,12 +71,10 @@ services: - proxy yii-app: - build: - context: ./yii-app + image: registry.example.com/yii-app:1.0.0 environment: - - VIRTUAL_HOST=angie-demo.example.ru + - VIRTUAL_HOST=example-demo.example.com - VIRTUAL_PORT=80 - - APP_NAME=Yii demo behind Angie HTTPS networks: - proxy @@ -267,23 +86,6 @@ volumes: angie_acme: ``` -## Starting the application - -To start the application, run the Docker Compose build: - -```bash -docker compose up -d --build -``` - -For Angie Docker Proxy to discover a service, the application must be attached to the same `proxy` network and have -two environment variables: - -```yaml -environment: - - VIRTUAL_HOST=example-demo.example.com - - VIRTUAL_PORT=80 -``` - `VIRTUAL_HOST` is the application's public domain. `VIRTUAL_PORT` is the container's internal port to which Angie should proxy requests. @@ -291,83 +93,46 @@ environment: Angie Docker Proxy automatically discovers `VIRTUAL_HOST` and `VIRTUAL_PORT` from the environment variables and issues certificates using the Angie ACME module and Let's Encrypt. -Adding a new application or service to `docker-compose.yml`: +## Starting the services -```yaml -second_app: - image: traefik/whoami - environment: - - VIRTUAL_HOST=example-demo2.example.com - - VIRTUAL_PORT=80 -networks: - - proxy -``` - -After adding the new service block, apply the changes: +Start the proxy and application containers: ```bash docker compose up -d ``` -## How it works - -Angie Docker Proxy runs in a separate container alongside the applications. The container includes Angie, `docker-gen`, -the `angie.tmpl` configuration template, and the entrypoint script. When `docker compose up -d` runs, the `angie-proxy` -container starts and the Docker socket is mounted into it in read-only mode. - -The Angie Docker Proxy image contains: - -- Angie OSS. -- `docker-gen`. -- The `angie.tmpl` template. -- `entrypoint.sh`, which starts configuration generation and Angie itself. +## Adding another application -Workflow: - -After `docker compose up -d --build` runs, the following sequence takes place: - -```text -Docker API --> docker-gen --> /etc/angie/angie.conf --> angie -t --> Angie startup --> ACME certificate issuance --> reverse proxy to yii-app -``` - -`docker-gen` monitors the Docker socket: +To expose another application, add it to `services` in `docker-compose.yml` and attach it to the `proxy` network: ```yaml -volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro -``` - -Inside the container, `entrypoint.sh` specifies where the Docker API is located: - -```sh -export DOCKER_HOST=unix:///tmp/docker.sock +services: + second-app: + image: traefik/whoami + environment: + - VIRTUAL_HOST=example-demo2.example.com + - VIRTUAL_PORT=80 + networks: + - proxy ``` -After startup, `docker-gen` remains in watch mode. When a new container with `VIRTUAL_HOST` appears, it regenerates -`/etc/angie/angie.conf` and runs: +Apply the changes: -```sh -angie -s reload +```bash +docker compose up -d ``` -For each domain, the template generates a separate `acme_client`. The client name is built from the domain by replacing -dots and hyphens with underscores. - -Example: +## How it works -`example-demo.example.com -> example_demo_example_com` +Angie Docker Proxy monitors the Docker API and discovers containers configured with `VIRTUAL_HOST` and `VIRTUAL_PORT`. +It generates the Angie configuration, obtains TLS certificates using ACME, and forwards incoming requests to the +corresponding containers through the shared Docker network. -Certificates are stored separately for each server. +When containers are added, removed, or updated, the proxy regenerates its configuration and performs a graceful reload. +Existing connections continue to be handled while the updated configuration is applied. -When generating an upstream, the container IP is selected only from the shared `proxy` network. This is important -because a container can be connected to multiple Docker networks, but the reverse proxy needs an address from the -network shared with `angie-proxy`. +For configuration options and implementation details, see the +[Angie Docker Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy). ## Verification @@ -418,6 +183,7 @@ Expected issuer: Let's Encrypt ``` + ## Logs Proxy logs: @@ -440,7 +206,15 @@ Stop the services and remove the certificates: docker compose down -v ``` +## Limitations + +This setup is intended for Docker Compose. Kubernetes doesn't expose workloads through the Docker API and requires an +Ingress or Gateway API controller. Docker Swarm also uses the Docker API, but Swarm deployment isn't covered in this +guide. + ## For more information +- [Angie Docker Proxy documentation](https://hub.docker.com/r/angiesoftware/proxy) - [Yii Application Template](https://github.com/yiisoft/app) -- [Docker Compose documentation]( +- [Docker in Yii Application Templates](https://yiisoft.github.io/docs/guide/tutorial/docker.html) +- [Docker Compose documentation](https://docs.docker.com/compose/)