mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
move server into apps/ignis-server
This commit is contained in:
139
apps/ignis-server/examples/INSTRUCTIONS.md
Normal file
139
apps/ignis-server/examples/INSTRUCTIONS.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Deploying Ignis with Authentication
|
||||
|
||||
Ignis has no built-in authentication. These examples provide ready-to-use Docker Compose setups that put an authentication layer in front of Ignis using [Caddy](https://caddyserver.com/) as a reverse proxy.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker and Docker Compose installed
|
||||
- A domain name pointing to your server (or a local DNS setup)
|
||||
- Ports 80 and 443 available
|
||||
|
||||
## Choose Your Setup
|
||||
|
||||
| Setup | Complexity | Features |
|
||||
| ----- | ---------- | -------- |
|
||||
| [Caddy + Basic Auth](#caddy--basic-auth) | Minimal | Username/password prompt on every new browser session |
|
||||
| [Caddy + Authelia](#caddy--authelia) | Low | Login page, sessions, optional 2FA, multi-user support |
|
||||
|
||||
Basic auth is fine if you just need a password gate for yourself. Authelia is better if you want a proper login page, persistent sessions, or might add more users later.
|
||||
|
||||
---
|
||||
|
||||
## Caddy + Basic Auth
|
||||
|
||||
The simplest option. Caddy prompts for a username and password before allowing access.
|
||||
|
||||
### Setup
|
||||
|
||||
1. Copy the `caddy-basic-auth/` folder to wherever you want to run Ignis.
|
||||
|
||||
2. Generate a password hash:
|
||||
```bash
|
||||
docker run --rm caddy:2 caddy hash-password --plaintext YOUR_PASSWORD
|
||||
```
|
||||
|
||||
3. Edit `Caddyfile`:
|
||||
- Replace `ignis.example.com` with your domain.
|
||||
- Replace `$2a$14$REPLACE_THIS_WITH_YOUR_BCRYPT_HASH` with the hash from step 2.
|
||||
- Optionally change the username `admin` to something else.
|
||||
|
||||
4. Start it:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Caddy will automatically obtain a TLS certificate from Let's Encrypt for your domain.
|
||||
|
||||
---
|
||||
|
||||
## Caddy + Authelia
|
||||
|
||||
A more robust setup with a dedicated login page, session cookies, and optional two-factor authentication.
|
||||
|
||||
### Setup
|
||||
|
||||
1. Copy the `caddy-authelia/` folder to wherever you want to run Ignis.
|
||||
|
||||
2. Generate two random secrets (used for signing tokens and encrypting the database):
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
Run this twice. You need two different values.
|
||||
|
||||
3. Edit `authelia/configuration.yml`:
|
||||
- Replace both `REPLACE_WITH_A_RANDOM_SECRET` and `REPLACE_WITH_ANOTHER_RANDOM_SECRET` with the secrets from step 2.
|
||||
- Replace `example.com` with your root domain (e.g. `mydomain.com`).
|
||||
- Replace `auth.example.com` with your auth subdomain (e.g. `auth.mydomain.com`).
|
||||
|
||||
4. Generate a password hash for your user:
|
||||
```bash
|
||||
docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password YOUR_PASSWORD
|
||||
```
|
||||
|
||||
5. Edit `authelia/users_database.yml`:
|
||||
- Replace the placeholder hash with the output from step 4.
|
||||
- Optionally change the username, display name, and email.
|
||||
|
||||
6. Edit `Caddyfile`:
|
||||
- Replace `auth.example.com` with your auth subdomain.
|
||||
- Replace `ignis.example.com` with your Ignis domain.
|
||||
|
||||
7. Start it:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Adding more users
|
||||
|
||||
Add entries to `authelia/users_database.yml` following the same format as the existing user. Each user needs a unique username, email, and password hash. Restart Authelia after editing:
|
||||
```bash
|
||||
docker compose restart authelia
|
||||
```
|
||||
|
||||
### Enabling two-factor authentication
|
||||
|
||||
Authelia supports TOTP (authenticator apps like Google Authenticator, Authy, etc.) out of the box. To require 2FA, change the access control policy in `authelia/configuration.yml`:
|
||||
|
||||
```yaml
|
||||
access_control:
|
||||
default_policy: two_factor
|
||||
```
|
||||
|
||||
After restarting, users will be prompted to register a TOTP device on their next login.
|
||||
|
||||
### Password reset
|
||||
|
||||
The default configuration uses a filesystem notifier, which writes password reset links to a file inside the container instead of emailing them. To check for reset links:
|
||||
```bash
|
||||
docker compose exec authelia cat /data/notification.txt
|
||||
```
|
||||
|
||||
For production use, replace the `notifier` section in `configuration.yml` with your SMTP server details. See the [Authelia notifier docs](https://www.authelia.com/configuration/notifications/smtp/).
|
||||
|
||||
---
|
||||
|
||||
## Common Notes
|
||||
|
||||
### DNS
|
||||
|
||||
Both examples require DNS records pointing to your server:
|
||||
- For basic auth: one A/CNAME record for your Ignis domain.
|
||||
- For Authelia: two A/CNAME records, one for Ignis and one for the auth subdomain.
|
||||
|
||||
### HTTPS
|
||||
|
||||
Caddy handles TLS automatically via Let's Encrypt. For this to work, your domain must be publicly resolvable and ports 80/443 must be reachable from the internet (Let's Encrypt needs to verify domain ownership).
|
||||
|
||||
If you're running on a local network without public DNS, you can use Caddy's [internal TLS](https://caddyserver.com/docs/caddyfile/directives/tls#internal) to generate self-signed certificates. Add `tls internal` inside each site block in the Caddyfile.
|
||||
|
||||
### Vault data
|
||||
|
||||
Both examples store vault data in a `vaults/` directory and Ignis state in a `data/` directory next to the compose file. These are bind mounts, so your data lives on the host filesystem and persists across container restarts.
|
||||
|
||||
### Building from source
|
||||
|
||||
If you're building Ignis from source instead of using the published image, edit `docker-compose.yml` and swap `image: nobbe/ignis:latest` for `build: ../../` (assuming you're running from the cloned repo's `examples/` folder).
|
||||
|
||||
### Alternative: Cloudflare Tunnel
|
||||
|
||||
If you don't want to expose ports 80/443, [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) can route traffic to your server without opening any inbound ports. Cloudflare Access can also provide authentication. This is a different approach entirely and not covered by these examples, but it's worth considering if you already use Cloudflare.
|
||||
14
apps/ignis-server/examples/caddy-authelia/Caddyfile
Normal file
14
apps/ignis-server/examples/caddy-authelia/Caddyfile
Normal file
@@ -0,0 +1,14 @@
|
||||
# Authelia portal. Replace auth.example.com with your auth subdomain.
|
||||
auth.example.com {
|
||||
reverse_proxy authelia:9091
|
||||
}
|
||||
|
||||
# Ignis. Replace ignis.example.com with your domain.
|
||||
ignis.example.com {
|
||||
forward_auth authelia:9091 {
|
||||
uri /api/authz/forward-auth
|
||||
copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
||||
}
|
||||
|
||||
reverse_proxy ignis:8080
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Authelia minimal configuration for Ignis.
|
||||
# See https://www.authelia.com/configuration/prologue/introduction/ for full docs.
|
||||
|
||||
# -- Replace these with random strings (e.g. openssl rand -hex 32) --
|
||||
identity_validation:
|
||||
reset_password:
|
||||
jwt_secret: REPLACE_WITH_A_RANDOM_SECRET
|
||||
|
||||
server:
|
||||
address: tcp://0.0.0.0:9091
|
||||
|
||||
log:
|
||||
level: info
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
|
||||
session:
|
||||
cookies:
|
||||
- domain: example.com # Replace with your root domain
|
||||
authelia_url: https://auth.example.com
|
||||
|
||||
storage:
|
||||
encryption_key: REPLACE_WITH_ANOTHER_RANDOM_SECRET
|
||||
local:
|
||||
path: /data/db.sqlite3
|
||||
|
||||
notifier:
|
||||
# For production, replace this with an SMTP block.
|
||||
# The filesystem notifier writes password reset links to a file instead of emailing them.
|
||||
filesystem:
|
||||
filename: /data/notification.txt
|
||||
|
||||
access_control:
|
||||
default_policy: one_factor
|
||||
@@ -0,0 +1,13 @@
|
||||
# Authelia user database.
|
||||
#
|
||||
# To generate a password hash, run:
|
||||
# docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password YOUR_PASSWORD
|
||||
#
|
||||
# Then paste the output as the `password` value below.
|
||||
|
||||
users:
|
||||
admin:
|
||||
disabled: false
|
||||
displayname: Admin
|
||||
email: admin@example.com
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=4$REPLACE_THIS_WITH_YOUR_HASH"
|
||||
45
apps/ignis-server/examples/caddy-authelia/docker-compose.yml
Normal file
45
apps/ignis-server/examples/caddy-authelia/docker-compose.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
- ignis
|
||||
restart: unless-stopped
|
||||
|
||||
authelia:
|
||||
image: authelia/authelia:latest
|
||||
volumes:
|
||||
- ./authelia:/config:ro
|
||||
- authelia_data:/data
|
||||
networks:
|
||||
- ignis
|
||||
restart: unless-stopped
|
||||
|
||||
ignis:
|
||||
image: nobbe/ignis:latest
|
||||
# To build from source instead, comment out `image` and uncomment:
|
||||
# build: ../../
|
||||
environment:
|
||||
- OBSIDIAN_VERSION=1.12.7
|
||||
volumes:
|
||||
- ./vaults:/vaults
|
||||
- ./data:/app/data
|
||||
- obsidian-app:/app/obsidian-app
|
||||
networks:
|
||||
- ignis
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
ignis:
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
authelia_data:
|
||||
obsidian-app:
|
||||
11
apps/ignis-server/examples/caddy-basic-auth/Caddyfile
Normal file
11
apps/ignis-server/examples/caddy-basic-auth/Caddyfile
Normal file
@@ -0,0 +1,11 @@
|
||||
# Replace with your domain, or use :443 for local access with a self-signed cert.
|
||||
ignis.example.com {
|
||||
basicauth {
|
||||
# Username: admin
|
||||
# Replace the hash below with your own. Generate one with:
|
||||
# docker run --rm caddy:2 caddy hash-password --plaintext YOUR_PASSWORD
|
||||
admin $2a$14$REPLACE_THIS_WITH_YOUR_BCRYPT_HASH
|
||||
}
|
||||
|
||||
reverse_proxy ignis:8080
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
- ignis
|
||||
restart: unless-stopped
|
||||
|
||||
ignis:
|
||||
image: nobbe/ignis:latest
|
||||
# To build from source instead, comment out `image` and uncomment:
|
||||
# build: ../../
|
||||
environment:
|
||||
- OBSIDIAN_VERSION=1.12.7
|
||||
volumes:
|
||||
- ./vaults:/vaults
|
||||
- ./data:/app/data
|
||||
- obsidian-app:/app/obsidian-app
|
||||
networks:
|
||||
- ignis
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
ignis:
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
obsidian-app:
|
||||
37
apps/ignis-server/examples/demo/README.md
Normal file
37
apps/ignis-server/examples/demo/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Public demo deployment
|
||||
|
||||
This example runs Ignis as a public, no-auth demo where anyone with the URL can spin up a transient vault and try the editor. The live demo at <https://ignis-demo.thiefling.com> uses this configuration.
|
||||
|
||||
Demo mode changes the security and lifecycle model:
|
||||
|
||||
- **Per-session vaults.** Each visitor gets their own isolated set of vaults, tracked by a session cookie. Sessions don't share storage.
|
||||
- **Transient files.** Vaults live on tmpfs in the example compose file, so everything is wiped on container restart and on session expiry.
|
||||
- **Auto-cleanup.** Sessions expire after a period of inactivity; their vaults are removed in-process.
|
||||
- **Capacity caps.** Concurrent sessions, vaults per session, and bytes per session are bounded, so a single visitor can't fill the disk and the host can't be flooded with sessions.
|
||||
- **Proxy allowlist.** The CORS proxy is restricted to a known-safe domain list so the public demo can't be used as an open relay.
|
||||
- **Login blocked.** Obsidian account login is blocked at both the proxy and the UI, so visitors can't accidentally enter credentials into a server they don't control.
|
||||
|
||||
## Running it
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The bundled [`docker-compose.yml`](docker-compose.yml) builds Ignis from the parent directory, mounts a 20 MB tmpfs at `/vaults`, and configures the demo limits. Adjust the env vars below for your own deployment.
|
||||
|
||||
## Demo environment variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
| -------- | ----------- | ------- |
|
||||
| `DEMO_MODE` | Enable demo mode (per-session vaults, auto-cleanup, proxy allowlist, login blocking). | `false` |
|
||||
| `DEMO_MAX_SESSIONS` | Concurrent demo session cap. New visitors get a 503 capacity page when full. | `20` |
|
||||
| `DEMO_VAULTS_PER_SESSION` | Max vaults per session (vault create returns 507 past this). | `3` |
|
||||
| `DEMO_SESSION_QUOTA_BYTES` | Cumulative byte budget per session across all session vaults. | `716800` |
|
||||
| `DEMO_TIMEOUT_MS` | Inactivity timeout before a demo session and its vaults are cleaned up. | `1800000` |
|
||||
| `DEMO_TEMPLATE_DIR` | Directory copied into each new demo vault. | `server/demo-template/` |
|
||||
|
||||
The standard Ignis env vars (`PORT`, `VAULT_ROOT`, `OBSIDIAN_VERSION`, etc.) still apply. See the [main README](../../README.md#environment-variables) for those.
|
||||
|
||||
## Custom starter vault
|
||||
|
||||
The bundled `server/demo-template/` is a minimal walkthrough of what Ignis is. To ship a richer starter vault for your own demo without committing it to the repo, mount a directory at `/app/demo-template` and point `DEMO_TEMPLATE_DIR` at it. The compose file has the wiring commented out.
|
||||
38
apps/ignis-server/examples/demo/docker-compose.yml
Normal file
38
apps/ignis-server/examples/demo/docker-compose.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
# Public demo of Ignis.
|
||||
#
|
||||
# - Vaults live on tmpfs (RAM-backed, transient by design)
|
||||
# - 20 MB total tmpfs, 700 KB per session, 3 vaults per session
|
||||
# - 30-minute inactivity timeout, in-process cleanup
|
||||
# - CORS proxy locked down to a known-safe domain allowlist
|
||||
# - Obsidian account login blocked (proxy + UI)
|
||||
|
||||
services:
|
||||
ignis-demo:
|
||||
build:
|
||||
context: ../../../..
|
||||
dockerfile: apps/ignis-server/Dockerfile
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- DEMO_MODE=true
|
||||
- DEMO_MAX_SESSIONS=20
|
||||
- DEMO_VAULTS_PER_SESSION=3
|
||||
- DEMO_SESSION_QUOTA_BYTES=716800 # 700 KB
|
||||
- DEMO_TIMEOUT_MS=1800000 # 30 min
|
||||
# Mount your own template at /app/demo-template to ship a richer
|
||||
# starter vault without committing it to the repo. Defaults to the
|
||||
# bundled server/demo-template/.
|
||||
# - DEMO_TEMPLATE_DIR=/app/demo-template
|
||||
- WRITE_COALESCE_MS=0 # tmpfs doesn't need debouncing
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
tmpfs:
|
||||
- /vaults:size=20m,mode=1700
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- obsidian-app:/app/obsidian-app
|
||||
# - ./my-demo-template:/app/demo-template:ro
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
obsidian-app:
|
||||
Reference in New Issue
Block a user