Files
n8n-install/ADDING_NEW_SERVICE.md
Yury Kossakovsky e1a18241cd Add guide for adding new services to n8n-installer
- Introduced a comprehensive guide in ADDING_NEW_SERVICE.md detailing the steps to add a new optional service, including modifications to docker-compose.yml, Caddyfile, .env.example, and relevant scripts.
- Included instructions for handling Basic Auth, secret generation, and service selection during installation.
- Updated README.md to include a description for the new service.
2025-08-27 15:39:10 -06:00

165 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Guide: Adding a New Service to n8n-installer
This document shows how to add a new optional service (behind Docker Compose profiles) and wire it into the installer, Caddy, and final report.
Use a short lowercase slug for your service, e.g., `myservice`.
## 1) docker-compose.yml
- Add a service block under `services:` with a Compose profile:
- `profiles: ["myservice"]`
- `restart: unless-stopped`
- image/build/command/healthcheck as needed
- IMPORTANT: do not publish ports and do not expose ports. Let Caddy do external HTTPS.
- Avoid `ports:` and avoid `expose:` entries unless strictly required for internal discovery.
- If you intend to proxy it via Caddy, ensure you define a hostname env in `.env.example` (e.g., `MYSERVICE_HOSTNAME`) and pass it to the `caddy` container via the `environment:` section if needed for the Caddyfile.
Minimal example:
```yaml
myservice:
image: yourorg/myservice:latest
container_name: myservice
profiles: ["myservice"]
restart: unless-stopped
# command: ...
# healthcheck: { test: ["CMD-SHELL", "curl -fsS http://localhost:8080/health || exit 1"], interval: 30s, timeout: 10s, retries: 5 }
```
If adding Caddy env passthrough (only if used in Caddyfile):
```yaml
caddy:
# ...
environment:
- MYSERVICE_HOSTNAME=${MYSERVICE_HOSTNAME}
# If using basic auth:
- MYSERVICE_USERNAME=${MYSERVICE_USERNAME}
- MYSERVICE_PASSWORD_HASH=${MYSERVICE_PASSWORD_HASH}
```
## 2) Caddyfile
- Add a site block for the service hostname if it should be reachable externally:
- Ask users whether the service needs Basic Auth via Caddy; if yes, add `basic_auth` with env-based credentials.
Example:
```caddyfile
{$MYSERVICE_HOSTNAME} {
# Optional. Ask the user if we should protect this endpoint via Basic Auth
basic_auth {
{$MYSERVICE_USERNAME} {$MYSERVICE_PASSWORD_HASH}
}
reverse_proxy myservice:8080
}
```
Notes:
- Keep using env placeholders (e.g., `{$MYSERVICE_HOSTNAME}`), supplied by the `caddy` service environment in `docker-compose.yml`.
## 3) .env.example
- Add the service hostname under the Caddy config section:
```dotenv
MYSERVICE_HOSTNAME=myservice.yourdomain.com
```
- If Basic Auth is desired, add credentials (username, password, and password hash):
```dotenv
############
# [required]
# MyService credentials (for Caddy basic auth)
############
MYSERVICE_USERNAME=
MYSERVICE_PASSWORD=
MYSERVICE_PASSWORD_HASH=
```
## 4) scripts/03_generate_secrets.sh
- Generate secrets/hashes and preserve user-provided values:
- Add any password variables to `VARS_TO_GENERATE` (e.g., 32-char random password)
- Add username to `found_vars` if you want an auto default (commonly set to the installer email)
- Create a bcrypt hash using Caddy and write `MYSERVICE_PASSWORD_HASH` into `.env`
Example edits:
- Add to `VARS_TO_GENERATE` map:
```bash
["MYSERVICE_PASSWORD"]="password:32"
```
- Default username (optional) and mark as found var:
```bash
found_vars["MYSERVICE_USERNAME"]=0
# ... later where usernames are defaulted
generated_values["MYSERVICE_USERNAME"]="$USER_EMAIL"
```
- Generate hash (following the established pattern used by other services):
```bash
MYSERVICE_PLAIN_PASS="${generated_values["MYSERVICE_PASSWORD"]}"
FINAL_MYSERVICE_HASH="${generated_values[MYSERVICE_PASSWORD_HASH]}"
if [[ -z "$FINAL_MYSERVICE_HASH" && -n "$MYSERVICE_PLAIN_PASS" ]]; then
NEW_HASH=$(_generate_and_get_hash "$MYSERVICE_PLAIN_PASS")
if [[ -n "$NEW_HASH" ]]; then
FINAL_MYSERVICE_HASH="$NEW_HASH"
generated_values["MYSERVICE_PASSWORD_HASH"]="$NEW_HASH"
fi
fi
_update_or_add_env_var "MYSERVICE_PASSWORD_HASH" "$FINAL_MYSERVICE_HASH"
```
## 5) scripts/04_wizard.sh
- Add the service to the selectable profiles list so users can opt-in during installation:
```bash
# base_services_data+=
"myservice" "MyService (Short description)"
```
## 6) scripts/06_final_report.sh
- Add a block that prints discovered URLs/credentials:
```bash
if is_profile_active "myservice"; then
echo
echo "================================= MyService ==========================="
echo
echo "Host: ${MYSERVICE_HOSTNAME:-<hostname_not_set>}"
# Only print credentials if Caddy basic auth is enabled for this service
echo "User: ${MYSERVICE_USERNAME:-<not_set_in_env>}"
echo "Password: ${MYSERVICE_PASSWORD:-<not_set_in_env>}"
echo "API (external via Caddy): https://${MYSERVICE_HOSTNAME:-<hostname_not_set>}"
echo "API (internal): http://myservice:8080"
echo "Docs: <link_to_docs>"
fi
```
## 7) README.md
- Add a short, one-line description under “Whats Included”, linking to your service docs/homepage.
```md
✅ [**MyService**](https://example.com) - One-line description of what it provides.
```
## 8) Ask about Basic Auth (important)
When adding any new public-facing service, explicitly ask the user whether they want to protect the service with Basic Auth via Caddy. If yes, add:
- Credentials section to `.env.example`
- Secret generation in `scripts/03_generate_secrets.sh`
- `basic_auth` in `Caddyfile`
- Pass the username/hash through `docker-compose.yml` `caddy.environment`
## 9) Verify and apply
- Regenerate secrets to populate new variables:
```bash
bash scripts/03_generate_secrets.sh
```
- Start (or recreate) only the affected services:
```bash
docker compose -p localai up -d --no-deps --force-recreate caddy
# If your service was added/changed
docker compose -p localai up -d --no-deps --force-recreate myservice
```
- Check logs:
```bash
docker compose -p localai logs -f --tail=200 myservice | cat
docker compose -p localai logs -f --tail=200 caddy | cat
```
## 10) Quick checklist
- [ ] Service added to `docker-compose.yml` with a profile (no external ports exposed)
- [ ] Hostname and (optional) credentials added to `.env.example`
- [ ] Secret + hash generation added to `scripts/03_generate_secrets.sh`
- [ ] Exposed via `Caddyfile` with `reverse_proxy` (+ `basic_auth` if desired)
- [ ] Service selectable in `scripts/04_wizard.sh`
- [ ] Listed with URLs/credentials in `scripts/06_final_report.sh`
- [ ] One-line description added to `README.md`