mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-17 13:55:08 +00:00
feat: add nginx-proxy with acme companion as an alternative to traefik (#1800)
* refactor: move core nginx files into more recognizable folder structure * chore: include HTTPS_PUBLISH_PORT in example .env * feat: add nginx-proxy and acme-companion compose overrides * docs: add NGINX_PROXY_HOSTS to example.env * docs: add nginx-proxy overrides * docs: split docs, variables for usage of traefik or nginx-proxy * docs: update override notes for traefik proxy on separate stack * docs: split TLS/SSL overview and add own caddy guide * docs: add nginx-proxy + acme companion guide * docs: add nginx-proxy and acme single-server setup guide
This commit is contained in:
parent
3d46cb84e0
commit
99d9a1dc38
15 changed files with 470 additions and 51 deletions
|
|
@ -43,12 +43,14 @@ Then edit `.env` and set variables according to your needs.
|
|||
|
||||
---
|
||||
|
||||
## HTTPS & SSL Configuration
|
||||
## Reverse Proxy and SSL (HTTPS) Configuration
|
||||
|
||||
### Traefik (compose.proxy.yaml / compose.https.yaml)
|
||||
|
||||
| Variable | Purpose | Default | When to Set |
|
||||
| ------------------- | ------------------------------------------------------------- | ------- | ---------------------------------------- |
|
||||
| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | — | Required if using HTTPS override |
|
||||
| `SITES_RULE` | List of domains for SSL (Traefik rule for TLS domain routing) | — | Required if using reverse proxy override |
|
||||
| ------------------- | ------------------------------------------------ | ------- | -------------------------------------------- |
|
||||
| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate registration | - | Required for `compose.https.yaml` |
|
||||
| `SITES_RULE` | Domains for routing (Traefik rule expression) | - | Required for Traefik routing/HTTPS overrides |
|
||||
|
||||
**Format for `SITES_RULE`:**
|
||||
|
||||
|
|
@ -63,6 +65,28 @@ SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`)
|
|||
> Note: The Traefik v3 migration is complete. Use `SITES_RULE` as a full v3 rule expression; `SITES` is deprecated.
|
||||
> Rule syntax now defaults to v3, so no `core.defaultRuleSyntax` or per-router `ruleSyntax` settings are required.
|
||||
|
||||
### nginx-proxy + acme-companion (compose.nginxproxy\*.yaml)
|
||||
|
||||
| Variable | Purpose | Default | When to Set |
|
||||
| ------------------- | ----------------------------------------- | ------- | ------------------------------------------ |
|
||||
| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt certificate | - | Required for `compose.nginxproxy-ssl.yaml` |
|
||||
| `NGINX_PROXY_HOSTS` | Comma-separated hostnames for nginx-proxy | - | Required for `compose.nginxproxy*.yaml` |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
NGINX_PROXY_HOSTS=example.com,www.example.com
|
||||
```
|
||||
|
||||
> Note: Automatic certificates require port 80 to be reachable (HTTP-01).
|
||||
|
||||
### Published Ports (Traefik and nginx-proxy)
|
||||
|
||||
| Variable | Purpose | Default | When to Set |
|
||||
| -------------------- | -------------------- | ------------------------------- | ---------------------------- |
|
||||
| `HTTP_PUBLISH_PORT` | Published HTTP port | `80` (proxy) / `8080` (noproxy) | Change if port is in use |
|
||||
| `HTTPS_PUBLISH_PORT` | Published HTTPS port | `443` | Change if port 443 is in use |
|
||||
|
||||
---
|
||||
|
||||
## Site Configuration
|
||||
|
|
@ -94,13 +118,12 @@ If your site is named `example.com` and you access it via that domain, no need t
|
|||
|
||||
---
|
||||
|
||||
## Nginx Proxy Configuration
|
||||
## Frontend Nginx Configuration (inside the frontend container)
|
||||
|
||||
| Variable | Purpose | Default | Allowed Values |
|
||||
| ---------------------- | ---------------------------------- | -------------- | -------------------------------------------- |
|
||||
| `BACKEND` | Backend service address and port | `0.0.0.0:8000` | `{host}:{port}` |
|
||||
| `SOCKETIO` | Socket.IO service address and port | `0.0.0.0:9000` | `{host}:{port}` |
|
||||
| `HTTP_PUBLISH_PORT` | Published HTTP port | `8080` | Any available port |
|
||||
| `PROXY_READ_TIMEOUT` | Upstream request timeout | `120s` | Any nginx timeout value (e.g., `300s`, `5m`) |
|
||||
| `CLIENT_MAX_BODY_SIZE` | Maximum upload file size | `50m` | Any nginx size value (e.g., `100m`, `1g`) |
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co
|
|||
```
|
||||
|
||||
| Overrider | Purpose | Additional Info |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Database** | | |
|
||||
| compose.mariadb.yaml | Adds MariaDB database service | set `DB_PASSWORD` or default Password will be used |
|
||||
| compose.mariadb-secrets.yaml | Adds MariaDB with password from a secret file instead of environment variable | Set `DB_PASSWORD_SECRETS_FILE` to the path of your secret file |
|
||||
|
|
@ -15,6 +15,10 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co
|
|||
| compose.noproxy.yaml | Exposes the application directly on port `:8080` without a reverse proxy | |
|
||||
| compose.proxy.yaml | Uses Traefik as HTTP reverse proxy on port `:80` | You can change the published port by setting `HTTP_PUBLISH_PORT` |
|
||||
| compose.https.yaml | Uses Traefik as HTTPS reverse proxy on Port `:443` with automatic HTTP-to-HTTPS redirect | `SITES_RULE` and `LETSENCRYPT_EMAIL` must be set. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. |
|
||||
| compose.traefik.yaml | Runs a standalone Traefik proxy with dashboard (HTTP) on a shared `traefik-public` network | Use for multi-stack setups. Requires `TRAEFIK_DOMAIN` and `HASHED_PASSWORD`. |
|
||||
| compose.traefik-ssl.yaml | Adds HTTPS and Let's Encrypt for the Traefik dashboard | Use with `compose.traefik.yaml`. Requires `EMAIL` and `TRAEFIK_DOMAIN`. Publishes `HTTPS_PUBLISH_PORT`. |
|
||||
| compose.nginxproxy.yaml | Uses nginx-proxy as HTTP reverse proxy on port `:80` | Set `NGINX_PROXY_HOSTS`. Use with `compose.nginxproxy-ssl.yaml` for HTTPS. You can change the published port by setting `HTTP_PUBLISH_PORT` |
|
||||
| compose.nginxproxy-ssl.yaml | Adds acme-companion for HTTPS on port `:443` with automatic certificates | Requires `compose.nginxproxy.yaml`. Set `NGINX_PROXY_HOSTS` and `LETSENCRYPT_EMAIL`. `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` can be set. |
|
||||
| **Redis** | | |
|
||||
| compose.redis.yaml | Adds Redis service for caching and background job queuing |
|
||||
| **TBD** | **The following overrides are available but lack documentation. If you use them and understand their purpose, please consider contributing to this documentation.** |
|
||||
|
|
@ -23,5 +27,3 @@ docker compose -f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/co
|
|||
| compose.custom-domain.yaml | | |
|
||||
| compose.multi-bench-ssl.yaml | | |
|
||||
| compose.multi-bench.yaml | | |
|
||||
| compose.traefik-ssl.yaml | | |
|
||||
| compose.traefik.yaml | | |
|
||||
|
|
|
|||
177
docs/02-setup/08-single-server-nginxproxy-example.md
Normal file
177
docs/02-setup/08-single-server-nginxproxy-example.md
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
# Single Server Example (nginx-proxy + acme-companion)
|
||||
|
||||
This guide demonstrates a single-server setup using nginx-proxy and acme-companion for HTTPS. It is best for a small number of hostnames and a single bench. If you need multiple benches or advanced routing, use the Traefik-based example instead.
|
||||
|
||||
We will setup the following:
|
||||
|
||||
- Install Docker and Docker Compose v2 on a Linux server.
|
||||
- Use nginx-proxy + acme-companion for HTTPS (Let's Encrypt).
|
||||
- Install MariaDB and Redis via containers.
|
||||
- Setup one project called `erpnext` with sites `erp.your-domain.com` and `crm.your-domain.com`.
|
||||
|
||||
## Requirements
|
||||
|
||||
- A server that can run Docker (recommended: 2 vCPU, 4 GB RAM, 50 GB SSD).
|
||||
- A public domain with DNS control.
|
||||
- Two subdomains pointing to your server IP (A/AAAA records):
|
||||
- `erp.your-domain.com`
|
||||
- `crm.your-domain.com`
|
||||
- Ports 80 and 443 reachable from the internet (required for Let's Encrypt HTTP-01).
|
||||
|
||||
### Install Docker
|
||||
|
||||
Docker can be installed on a variety of systems. The easiest way to do this is with the convenience script.
|
||||
|
||||
| Platform | Convenience script | Using repository |
|
||||
| -------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| CentOS | [Link](https://docs.docker.com/engine/install/centos/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/centos/#install-using-the-repository) |
|
||||
| Debian | [Link](https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/debian/#install-using-the-repository) |
|
||||
| Ubuntu | [Link](https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) |
|
||||
| Fedora | [Link](https://docs.docker.com/engine/install/fedora/#install-using-the-convenience-script) | [Link](https://docs.docker.com/engine/install/fedora/#install-using-the-repository) |
|
||||
|
||||
Then do the post-installation steps. This will ensure that the permissions are easier to use and that Docker will start up with the System. [Post-Installation Steps](https://docs.docker.com/engine/install/linux-postinstall/)
|
||||
|
||||
### Prepare
|
||||
|
||||
Clone `frappe_docker` and change the current working directory to the repo.
|
||||
|
||||
```shell
|
||||
git clone https://github.com/frappe/frappe_docker
|
||||
cd frappe_docker
|
||||
```
|
||||
|
||||
Create a configuration directory:
|
||||
|
||||
```shell
|
||||
mkdir ~/gitops
|
||||
```
|
||||
|
||||
## Optional: Build a custom image
|
||||
|
||||
If you need extra apps (beyond Frappe/ERPNext), build a custom image. Otherwise, skip this section and use the default images.
|
||||
|
||||
Create `apps.json` (each entry is a Git repo + branch):
|
||||
|
||||
```shell
|
||||
cat > ~/gitops/apps.json <<'EOF'
|
||||
[
|
||||
{
|
||||
"url": "https://github.com/frappe/erpnext",
|
||||
"branch": "version-16"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/frappe/payments",
|
||||
"branch": "version-16"
|
||||
}
|
||||
]
|
||||
EOF
|
||||
```
|
||||
|
||||
Example for CRM only:
|
||||
|
||||
```shell
|
||||
cat > ~/gitops/apps.json <<'EOF'
|
||||
[
|
||||
{
|
||||
"url": "https://github.com/frappe/crm",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
EOF
|
||||
```
|
||||
|
||||
Generate the BASE64 value and build:
|
||||
|
||||
```shell
|
||||
export APPS_JSON_BASE64=$(base64 -w 0 ~/gitops/apps.json)
|
||||
|
||||
docker build \
|
||||
--build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \
|
||||
--build-arg=FRAPPE_BRANCH=version-16 \
|
||||
--build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \
|
||||
--tag=my-erpnext-prod-image:16.0.0 \
|
||||
--file=images/layered/Containerfile .
|
||||
```
|
||||
|
||||
If `base64 -w 0` is not available on your system, use:
|
||||
|
||||
```shell
|
||||
export APPS_JSON_BASE64=$(base64 ~/gitops/apps.json | tr -d '\n')
|
||||
```
|
||||
|
||||
### Configure environment
|
||||
|
||||
Create an environment file for the bench:
|
||||
|
||||
```shell
|
||||
cp example.env ~/gitops/erpnext.env
|
||||
sed -i 's/DB_PASSWORD=123/DB_PASSWORD=changeit/g' ~/gitops/erpnext.env
|
||||
echo 'NGINX_PROXY_HOSTS=erp.your-domain.com,crm.your-domain.com' >> ~/gitops/erpnext.env
|
||||
echo 'LETSENCRYPT_EMAIL=admin@your-domain.com' >> ~/gitops/erpnext.env
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Replace `changeit` with a strong password.
|
||||
- Replace domains and email with your production values.
|
||||
- `NGINX_PROXY_HOSTS` is a comma-separated list without spaces.
|
||||
- If you built a custom image, add:
|
||||
|
||||
```shell
|
||||
echo "CUSTOM_IMAGE=my-erpnext-prod-image" >> ~/gitops/erpnext.env
|
||||
echo "CUSTOM_TAG=16.0.0" >> ~/gitops/erpnext.env
|
||||
```
|
||||
|
||||
### Generate compose config
|
||||
|
||||
Create the rendered compose file:
|
||||
|
||||
```shell
|
||||
docker compose --project-name erpnext \
|
||||
--env-file ~/gitops/erpnext.env \
|
||||
-f compose.yaml \
|
||||
-f overrides/compose.mariadb.yaml \
|
||||
-f overrides/compose.redis.yaml \
|
||||
-f overrides/compose.nginxproxy.yaml \
|
||||
-f overrides/compose.nginxproxy-ssl.yaml config > ~/gitops/erpnext.yaml
|
||||
```
|
||||
|
||||
Start the stack:
|
||||
|
||||
```shell
|
||||
docker compose --project-name erpnext -f ~/gitops/erpnext.yaml up -d
|
||||
```
|
||||
|
||||
This starts MariaDB and Redis containers as part of the same stack.
|
||||
|
||||
### Create sites
|
||||
|
||||
```shell
|
||||
# erp.your-domain.com
|
||||
docker compose --project-name erpnext exec backend \
|
||||
bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app erpnext --admin-password changeit erp.your-domain.com
|
||||
|
||||
# crm.your-domain.com
|
||||
docker compose --project-name erpnext exec backend \
|
||||
bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app erpnext --admin-password changeit crm.your-domain.com
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- Let's Encrypt requires ports 80 and 443 to be reachable from the internet.
|
||||
- If you cannot expose these ports (LAN-only), omit `compose.nginxproxy-ssl.yaml` and use HTTP or a local TLS proxy like Caddy.
|
||||
- Replace `changeit` with a strong DB root password and set a strong admin password per site.
|
||||
|
||||
### Site operations
|
||||
|
||||
Refer: [site operations](../04-operations/01-site-operations.md)
|
||||
|
||||
### Troubleshooting (ACME / certificates)
|
||||
|
||||
- **No certificate issued:** Verify DNS points to the server IP and ports 80/443 are reachable from the internet.
|
||||
- **ACME errors in logs:** Check `acme-companion` logs for the exact challenge error.
|
||||
- **Wrong hostname:** Ensure the domain is included in `NGINX_PROXY_HOSTS` and that you restarted the stack after edits.
|
||||
|
||||
---
|
||||
|
||||
**Back:** [Single Server Example (Traefik)](07-single-server-example.md)
|
||||
|
|
@ -1,25 +1,53 @@
|
|||
# Accessing ERPNext through https on local deployment
|
||||
# TLS/SSL Setup Overview
|
||||
|
||||
- ERPNext container deployment can be accessed through https easily using Caddy web server, Caddy will be used as reverse proxy and forward traffics to the frontend container.
|
||||
Frappe Docker supports multiple TLS/SSL approaches. Choose the one that matches your routing needs and where you want the proxy to run.
|
||||
|
||||
### Prerequisites
|
||||
## Options
|
||||
|
||||
- Caddy
|
||||
- Adding a domain name to hosts file
|
||||
### Traefik (built-in HTTPS)
|
||||
|
||||
#### Installation of caddy webserver
|
||||
- Use `overrides/compose.https.yaml`
|
||||
- Best for multi-site setups and advanced routing rules
|
||||
- Requires `SITES_RULE` and `LETSENCRYPT_EMAIL`
|
||||
- See [Environment Variables](../02-setup/04-env-variables.md) and [Setup Examples](../02-setup/06-setup-examples.md#example-3-production-setup-with-https)
|
||||
|
||||
- Follow the official Caddy website for the installation guide https://caddyserver.com/docs/install
|
||||
After completing the installation open the configuration file of Caddy ( You find the config file in ` /etc/caddy/Caddyfile`), add the following configuration to forward traffics to the ERPNext frontend container
|
||||
#### Traefik deployment models
|
||||
|
||||
```js
|
||||
erp.localdev.net {
|
||||
tls internal
|
||||
- **Single stack (Traefik inside the stack):**
|
||||
- Use `compose.proxy.yaml` (HTTP) or `compose.https.yaml` (HTTPS)
|
||||
- Traefik runs as `proxy` in the same stack
|
||||
- **Central Traefik for multiple stacks:**
|
||||
- Run a dedicated Traefik stack with `compose.traefik.yaml` (and optional `compose.traefik-ssl.yaml` for the dashboard)
|
||||
- Each Frappe stack uses `compose.multi-bench.yaml` (and optional `compose.multi-bench-ssl.yaml`)
|
||||
- This connects stacks to the shared `traefik-public` network
|
||||
|
||||
reverse_proxy localhost:8085 {
|
||||
### nginx-proxy + acme-companion
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
- Use `overrides/compose.nginxproxy.yaml` plus `overrides/compose.nginxproxy-ssl.yaml`
|
||||
- Simple host-based routing for single-bench or small setups
|
||||
- Requires `NGINX_PROXY_HOSTS` and `LETSENCRYPT_EMAIL`
|
||||
- See [nginx-proxy + acme-companion](04-nginx-proxy-acme-companion.md)
|
||||
|
||||
- Caddy's root certificate must be added to other computers if computers from different networks access the ERPNext through https.
|
||||
## Traefik vs nginx-proxy + acme-companion
|
||||
|
||||
| Topic | Traefik (compose.https.yaml) | nginx-proxy + acme-companion |
|
||||
| ------------------- | --------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| Configuration | Labels with `SITES_RULE` expression | Environment variables (`NGINX_PROXY_HOSTS`) |
|
||||
| Routing | Flexible (rules, headers, paths) | Host-based only |
|
||||
| Multi-site | Strong | Works for simple host lists |
|
||||
| TLS/ACME | Built-in | Separate companion container |
|
||||
| Certificate storage | `cert-data` volume (`/letsencrypt/acme.json`) | `nginx-proxy-certs` + `acme-data` volumes (`/etc/nginx/certs`, `/etc/acme.sh`) |
|
||||
| Complexity | Moderate | Low |
|
||||
| Observability | Optional dashboard (not enabled here) | No built-in dashboard |
|
||||
|
||||
### Caddy (external reverse proxy)
|
||||
|
||||
- Run Caddy on the host and proxy to the frontend container
|
||||
- Useful for local HTTPS or when you already use Caddy
|
||||
- See [Caddy reverse proxy](05-caddy-https.md)
|
||||
|
||||
## Common requirements
|
||||
|
||||
- DNS must point to the server for public TLS certificates
|
||||
- Ports 80 and 443 must be reachable for HTTP-01 challenges
|
||||
- Use `HTTP_PUBLISH_PORT` and `HTTPS_PUBLISH_PORT` if you need non-default ports
|
||||
|
|
|
|||
82
docs/03-production/04-nginx-proxy-acme-companion.md
Normal file
82
docs/03-production/04-nginx-proxy-acme-companion.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# nginx-proxy + acme-companion (HTTPS)
|
||||
|
||||
This guide explains how to use nginx-proxy with acme-companion to provide HTTPS for a Frappe Docker stack.
|
||||
|
||||
## When to choose this
|
||||
|
||||
- You want a simple, host-based reverse proxy
|
||||
- You run a single bench or only a few hostnames
|
||||
- You prefer environment-variable based configuration
|
||||
|
||||
If you need advanced routing or complex multi-site setups, **Traefik** is usually the better choice.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Public DNS points your domain(s) to the server
|
||||
- Ports 80 and 443 are reachable (HTTP-01 challenge)
|
||||
- Docker and Docker Compose v2 installed
|
||||
|
||||
## Required environment variables
|
||||
|
||||
Set these in `.env`:
|
||||
|
||||
```bash
|
||||
NGINX_PROXY_HOSTS=erp.your-domain.com
|
||||
LETSENCRYPT_EMAIL=admin@your-domain.com
|
||||
```
|
||||
|
||||
Multiple hostnames (comma-separated, no spaces):
|
||||
|
||||
```bash
|
||||
NGINX_PROXY_HOSTS=erp.your-domain.com,erp2.your-domain.com
|
||||
LETSENCRYPT_EMAIL=admin@example.com
|
||||
```
|
||||
|
||||
Optional (non-default ports):
|
||||
|
||||
```bash
|
||||
HTTP_PUBLISH_PORT=80
|
||||
HTTPS_PUBLISH_PORT=443
|
||||
```
|
||||
|
||||
## Compose setup (HTTPS)
|
||||
|
||||
For HTTPS you must include both overrides:
|
||||
|
||||
- `overrides/compose.nginxproxy.yaml` (nginx-proxy, VIRTUAL_HOST)
|
||||
- `overrides/compose.nginxproxy-ssl.yaml` (acme-companion, LETSENCRYPT_HOST)
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
docker compose -f compose.yaml \
|
||||
-f overrides/compose.mariadb.yaml \
|
||||
-f overrides/compose.redis.yaml \
|
||||
-f overrides/compose.nginxproxy.yaml \
|
||||
-f overrides/compose.nginxproxy-ssl.yaml \
|
||||
config > ~/gitops/docker-compose.yml
|
||||
|
||||
docker compose --project-name <project-name> -f ~/gitops/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
> If you use external MariaDB/Redis, replace the database and Redis overrides accordingly.
|
||||
|
||||
## How hostnames are applied
|
||||
|
||||
`NGINX_PROXY_HOSTS` is a comma-separated list of hostnames. The overrides apply it as:
|
||||
|
||||
- `VIRTUAL_HOST` for nginx-proxy routing
|
||||
- `LETSENCRYPT_HOST` for certificate issuance
|
||||
|
||||
## Verify
|
||||
|
||||
Check logs for certificate issuance and proxy status:
|
||||
|
||||
```sh
|
||||
docker compose --project-name <project-name> -f ~/gitops/docker-compose.yml logs -f nginx-proxy
|
||||
docker compose --project-name <project-name> -f ~/gitops/docker-compose.yml logs -f acme-companion
|
||||
```
|
||||
|
||||
> Depending on the registrar, the assignment may take some time, whereby it must also be ensured that A and AAAA records are correctly directed to the server for the issuance of the certificate, if necessary.
|
||||
|
||||
See also: [Environment Variables](../02-setup/04-env-variables.md) and [TLS/SSL Setup Overview](01-tls-ssl-setup.md).
|
||||
44
docs/03-production/05-caddy-https.md
Normal file
44
docs/03-production/05-caddy-https.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Caddy reverse proxy (local HTTPS)
|
||||
|
||||
This guide shows how to use Caddy as an external reverse proxy in front of the frontend container. It is most useful for local HTTPS or internal networks.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Expose the frontend container on a host port (default 8080)
|
||||
- Add a local domain to your hosts file (or use internal DNS)
|
||||
- Install Caddy
|
||||
|
||||
## Step 1: Expose the frontend service
|
||||
|
||||
Include the no-proxy override so the frontend is reachable on the host:
|
||||
|
||||
```sh
|
||||
docker compose -f compose.yaml \
|
||||
-f overrides/compose.mariadb.yaml \
|
||||
-f overrides/compose.redis.yaml \
|
||||
-f overrides/compose.noproxy.yaml \
|
||||
config > ~/gitops/docker-compose.yml
|
||||
|
||||
docker compose --project-name <project-name> -f ~/gitops/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
If you changed the HTTP port, note the value of `HTTP_PUBLISH_PORT` for the next step.
|
||||
|
||||
## Step 2: Configure Caddy
|
||||
|
||||
Add a site block to your Caddyfile (usually `/etc/caddy/Caddyfile`):
|
||||
|
||||
```caddy
|
||||
erp.localdev.net {
|
||||
tls internal
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
```
|
||||
|
||||
Replace `8080` with your published frontend port if you changed it.
|
||||
|
||||
## Step 3: Trust the Caddy root certificate
|
||||
|
||||
When using `tls internal`, Caddy issues certificates from its internal CA. Import and trust the Caddy root certificate on any client that needs to access the site.
|
||||
|
||||
See also: [TLS/SSL Setup Overview](01-tls-ssl-setup.md).
|
||||
|
|
@ -8,5 +8,5 @@ On Windows, files often have `CRLF` line endings, while Linux systems expect `LF
|
|||
|
||||
- **Convert Line Endings using `dos2unix`:**
|
||||
```bash
|
||||
dos2unix resources/nginx-entrypoint.sh
|
||||
dos2unix resources/core/nginx/nginx-entrypoint.sh
|
||||
```
|
||||
|
|
|
|||
|
|
@ -93,8 +93,15 @@ Docker Compose "overrides" that extend the base compose.yaml for different scena
|
|||
|
||||
- **compose.mariadb.yaml** - Adds MariaDB database service
|
||||
- **compose.redis.yaml** - Adds Redis caching service
|
||||
- **compose.proxy.yaml** - Adds Traefik reverse proxy for multi-site hosting
|
||||
- **compose.https.yaml** - Adds SSL/TLS certificate management
|
||||
- **compose.proxy.yaml** - Adds Traefik reverse proxy for multi-site hosting (label-based routing)
|
||||
- **compose.https.yaml** - Adds Traefik HTTPS + automatic certs (uses `SITES_RULE`)
|
||||
- **compose.nginxproxy.yaml** - Adds nginx-proxy reverse proxy (HTTP, env-based `VIRTUAL_HOST`)
|
||||
- **compose.nginxproxy-ssl.yaml** - Adds nginx-proxy + acme-companion (HTTPS, env-based `LETSENCRYPT_HOST`)
|
||||
|
||||
**Proxy choice:**
|
||||
|
||||
- Traefik is more flexible for advanced routing and multi-bench setups
|
||||
- nginx-proxy is simpler for a single bench with host-based routing.
|
||||
|
||||
### 📁 development/ - Dev Environment
|
||||
|
||||
|
|
@ -103,8 +110,8 @@ Docker Compose "overrides" that extend the base compose.yaml for different scena
|
|||
|
||||
### 📁 resources/ - Runtime Templates
|
||||
|
||||
- **nginx-entrypoint.sh** - Dynamic Nginx configuration generator script
|
||||
- **nginx-template.conf** - Nginx configuration template with variable substitution
|
||||
- **core/nginx/nginx-entrypoint.sh** - Dynamic Nginx configuration generator script
|
||||
- **core/nginx/nginx-template.conf** - Nginx configuration template with variable substitution
|
||||
|
||||
## Custom Apps Explained
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ FRAPPE_SITE_NAME_HEADER=
|
|||
# Default value is `8080`.
|
||||
HTTP_PUBLISH_PORT=
|
||||
|
||||
# Default value is `443`.
|
||||
HTTPS_PUBLISH_PORT=
|
||||
|
||||
# Default value is `127.0.0.1`. Set IP address as our trusted upstream address.
|
||||
UPSTREAM_REAL_IP_ADDRESS=
|
||||
|
||||
|
|
@ -49,8 +52,14 @@ PROXY_READ_TIMEOUT=
|
|||
# Necessary if the upload limit in the frappe application is increased
|
||||
CLIENT_MAX_BODY_SIZE=
|
||||
|
||||
# Only with traefik overrides
|
||||
# Single site: SITES_RULE=Host(`erp.example.com`)
|
||||
# Multiple sites: SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`)
|
||||
# More https://doc.traefik.io/traefik/routing/routers/#rule
|
||||
# About acme https://doc.traefik.io/traefik/https/acme/#domain-definition
|
||||
SITES_RULE=Host(`erp.example.com`)
|
||||
|
||||
# Only with nginxproxy overrides
|
||||
# Single site: NGINX_PROXY_HOSTS=erp.example.com
|
||||
# Multiple sites: NGINX_PROXY_HOSTS=erp.example.com,www.erp.example.com
|
||||
NGINX_PROXY_HOSTS=erp.example.com
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ ARG PYTHON_VERSION=3.11.6
|
|||
ARG DEBIAN_BASE=bookworm
|
||||
FROM python:${PYTHON_VERSION}-slim-${DEBIAN_BASE} AS base
|
||||
|
||||
COPY resources/nginx-template.conf /templates/nginx/frappe.conf.template
|
||||
COPY resources/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh
|
||||
COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template
|
||||
COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh
|
||||
|
||||
ARG WKHTMLTOPDF_VERSION=0.12.6.1-3
|
||||
ARG WKHTMLTOPDF_DISTRO=bookworm
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ RUN useradd -ms /bin/bash frappe \
|
|||
&& chown -R frappe:frappe /var/lib/nginx \
|
||||
&& chown -R frappe:frappe /run/nginx.pid
|
||||
|
||||
COPY resources/nginx-template.conf /templates/nginx/frappe.conf.template
|
||||
COPY resources/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh
|
||||
COPY resources/core/nginx/nginx-template.conf /templates/nginx/frappe.conf.template
|
||||
COPY resources/core/nginx/nginx-entrypoint.sh /usr/local/bin/nginx-entrypoint.sh
|
||||
|
||||
FROM base AS build
|
||||
|
||||
|
|
|
|||
26
overrides/compose.nginxproxy-ssl.yaml
Normal file
26
overrides/compose.nginxproxy-ssl.yaml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
services:
|
||||
frontend:
|
||||
environment:
|
||||
LETSENCRYPT_HOST: ${NGINX_PROXY_HOSTS:?No NGINX_PROXY_HOSTS set}
|
||||
|
||||
nginx-proxy:
|
||||
ports:
|
||||
- ${HTTP_PUBLISH_PORT:-80}:80
|
||||
- ${HTTPS_PUBLISH_PORT:-443}:443
|
||||
|
||||
acme-companion:
|
||||
image: nginxproxy/acme-companion:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DEFAULT_EMAIL: ${LETSENCRYPT_EMAIL:?No LETSENCRYPT_EMAIL set}
|
||||
volumes:
|
||||
- nginx-proxy-certs:/etc/nginx/certs
|
||||
- nginx-proxy-html:/usr/share/nginx/html
|
||||
- nginx-proxy-vhost:/etc/nginx/vhost.d
|
||||
- acme-data:/etc/acme.sh
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
depends_on:
|
||||
- nginx-proxy
|
||||
|
||||
volumes:
|
||||
acme-data:
|
||||
21
overrides/compose.nginxproxy.yaml
Normal file
21
overrides/compose.nginxproxy.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
services:
|
||||
frontend:
|
||||
environment:
|
||||
VIRTUAL_HOST: ${NGINX_PROXY_HOSTS:?No NGINX_PROXY_HOSTS set}
|
||||
VIRTUAL_PORT: 8080
|
||||
|
||||
nginx-proxy:
|
||||
image: nginxproxy/nginx-proxy:alpine
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- ${HTTP_PUBLISH_PORT:-80}:80
|
||||
volumes:
|
||||
- nginx-proxy-certs:/etc/nginx/certs
|
||||
- nginx-proxy-html:/usr/share/nginx/html
|
||||
- nginx-proxy-vhost:/etc/nginx/vhost.d
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
|
||||
volumes:
|
||||
nginx-proxy-certs:
|
||||
nginx-proxy-html:
|
||||
nginx-proxy-vhost:
|
||||
Loading…
Reference in a new issue