diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md deleted file mode 100644 index fa927a0..0000000 --- a/ARCHITECTURE.md +++ /dev/null @@ -1,43 +0,0 @@ -# Architecture - -This document covers how the shim layer is structured. - -## Loading - -The index file is patched to run the shim loader first. It replaces the module system and makes a blocking HTTP request to fetch the vault's directory tree into memory. The request has to be blocking because Obsidian makes synchronous filesystem calls during page load, before the event loop is running, so the cache has to already be populated. - -## Shims - -| Module | Implementation | -| -------------------- | --------------------------------------------------------------------------------- | -| `fs` / `original-fs` | HTTP transport + client-side metadata/content caches | -| `electron` | ipcRenderer dispatcher, webFrame stubs | -| `@electron/remote` | Partial: clipboard (browser API), shell, dialog, Menu, BrowserWindow, nativeTheme | -| `path` | path-browserify | -| `crypto` | Web Crypto (randomBytes, createHash, scrypt) | -| `url` | Browser URL API wrapper | -| `process` | Platform/version stubs | - -Unknown modules return an empty proxy and log a warning. The shim exposes two console helpers, one showing everything that has been accessed and one showing what is missing. - -## Filesystem - -On page load the server returns the full directory tree, which gets cached in memory with paths, sizes, and modification times. Sync filesystem calls hit the cache rather than the network. File contents are cached after first read and written through immediately on writes. - -Sync calls use synchronous XHR, to ensure blocking behavior. Async calls use fetch. Everything goes through a transport layer that handles vault ID injection, base64 encoding for binary files, and mapping HTTP error codes back to Node errno values. - -## IPC - -IPC is faked with a synchronous dispatcher that maps channel names to handlers. - -## Vaults - -Any subdirectory under the vault root is treated as a vault. The active vault is selected via a URL parameter. A custom vault manager modal replaces Obsidian's native startup screen. - -## Plugins - -Obsidian evals plugin code with its own require that checks its internal module map first, then falls back to the window-level require, which is our shim. Plugins that use the filesystem, path utilities, or crypto get our implementations without any changes. Plugins that need child processes or native addons won't work. - -## Server - -A simple Express server that handles filesystem operations, vault management, and static file serving. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6f7c338 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing to Ignis + +Thanks for your interest in contributing. Here are some ways you can help. + +## Reporting Plugin Compatibility Issues + +Testing plugins and reporting what works (or doesn't) is one of the most valuable contributions right now. When a plugin doesn't work, the browser console usually contains the information needed to diagnose the problem. + +### How to file a useful compatibility report + +1. Open the browser dev tools (F12 or Ctrl+Shift+I) +2. Go to the **Console** tab +3. Enable the plugin or trigger the failing action +4. Look for errors, especially lines starting with: + - `[ignis] Unshimmed require: ` - a Node.js module the plugin needs that Ignis doesn't provide yet + - `[shim:MISS] .` - a property or method on a shimmed module that isn't implemented + - `Plugin failure: ` - Obsidian caught a crash from the plugin +5. Copy the full error including the stack trace + +### What to include in the issue + +- Plugin name and version +- What you tried to do +- What happened (error, crash, nothing, partial functionality) +- The console output (errors and shim warnings) +- Whether the plugin loads at all or fails immediately + +### Example of a useful report + +> **Plugin:** Templater v1.18.4 +> **Status:** Broken on load +> +> Console shows: +> ``` +> [ignis] Unshimmed require: util +> [shim:MISS] UNKNOWN(util).promisify - property not found on shim +> Plugin failure: templater-obsidian TypeError: t is not a function +> ``` +> +> The plugin needs `util.promisify` which isn't shimmed yet. + +This kind of report makes it straightforward to add the missing shim. + +## Code Contributions + +If you want to contribute code: + +1. Fork the repo and create a branch for your change +2. Run `npm run build` to verify everything builds +3. start the server with `npm run dev`. +4. Test your change in the browser with at least one vault open +5. Keep PRs focused - one fix or feature per PR + +### Project structure + +- `src/shims/` - Browser shims for Node.js and Electron APIs +- `src/ui/` - Svelte UI components (vault manager, dialogs) +- `plugin/` - The ignis-bridge Obsidian plugin (settings, file actions) +- `server/` - Express server (fs routes, WebSocket, plugin system) +- `server/plugins/` - Server plugin packages (e.g., headless-sync) + +See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for more detail. + +### Adding a new shim + +If a plugin needs a Node.js module that isn't shimmed: + +1. Create the shim in `src/shims/node/.js` +2. Export the functions the plugin needs (stub what you can't implement) +3. Register it in `src/shims/require.js` (import + add to `rawRegistry`) +4. Build and test with the plugin that needed it diff --git a/README.md b/README.md index a1e9c67..607234a 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,128 @@ -# Ignis +
+

+ Ignis logo +

-An Electron shim and server bridge for running Obsidian in a browser. No VNC required. +

Ignis

-# Why +

+ Run Obsidian in the browser. No VNC required. +

+
-Obsidian is built on Electron but lacks browser access. Existing solutions rely on VNC/remote desktop, which provides a poor user experience. Since Electron is essentially a browser with Node.js integration, it should be possible to create a shim that routes Electron/Node APIs to a server, allowing Obsidian to run as a true web application. +## What is this -Ignis is a proof of concept testing this approach. +Ignis is a javascript shim that replaces the Electron APIs used by Obsidian and allows Obsidian to be run in the browser while keeping your vault on the server. As an alternative to sync based solutions, this lets you access your notes without installing an app on your device. Obsidian is not included in this repository, the Docker container downloads Obsidian directly from its official source on first run. -## How it works +## Why -Ignis replaces the electron backend of Obsidian with a browser-compatible 'shim' that intercepts calls to Node.js and Electron APIs and routes them to a server. +Obsidian's local first approach may not be the preference of some users, and while synchroniztion between devices is a perfectly good way to access your notes on multiple devices, options for accessing Obsidian remotely has been limited to VNC based solutions that have rather poor user experience. Ignis is an alternative for people who want to self-host a copy of Obsidian for easy access, in a (close-to) native format. -An in-memory metadata cache is built on page load so that sync filesystem calls (`existsSync`, `statSync`, etc.) work without round-tripping to the server every time. Async reads and writes go over HTTP. IPC channels like `ipcRenderer.sendSync("vault")` are faked with a dispatcher that returns what Obsidian expects. Native stuff like clipboard, menus, and dialogs have minimal stubs. +## Project Status -## Status +Ignis is **experimental**. Core functionality works, and some browser specific enhancements have been added, like file upload and download. Plugin support is an ongoing process of trying out plugins and finding what gaps in the shim still need to be plugged, but if a plugin uses primarily Obsidian's plugin API chances are it will work just fine. -Ignis is in an experimental state. Basic functionality works but no guarantee of stability or feature completeness. See [ARCHITECTURE.md](ARCHITECTURE.md) for details. +## What works + +- Creating, opening, and switching between multiple vaults +- Editing notes (markdown, canvas, bases, all core editor features) +- Community plugins to some degree (anything that doesn't need native Node modules, hopefully). +- File upload and download from the browser +- Live sync of external file changes via WebSocket +- Obsidian Sync has been tested and seems to be working fine, as long as the tab remains open obviously. +- Obsidian Headless has been integrated and can be used for continous synchronization. Can't be used alongside Obsidian Sycn in the browser, you can only pick one sync solution in order to avoid conflicts. + +## Plugin Compatibility + +Plugin support depends on what APIs a plugin uses. Anything built on Obsidian's plugin API generally works. Plugins that depend on Node.js modules might work depending on which are used. + +Compatibility is currently tracked in [Issue #9](https://github.com/Nystik-gh/ignis/issues/9). + +## Caveats + +_This section will be expanded as issues are documented._ + +- Community plugins that rely on `child_process` or native Node addons will not work at the moment. +- Mobile browser support is not a priority. It works, but the UX is not great. But I have ideas. +- File picker has a workaround to deal with synchronous file selection issues. Usable, a bit hacky. + +## Authentication + +Ignis has **no built-in authentication**. The server is completely open by default. + +If you are exposing Ignis to the internet, **you should really** put an authentication layer in front of it. Options include: + +- A reverse proxy with basic auth (nginx, Caddy, Traefik) +- An SSO proxy like Authelia, Authentik, or OAuth2 Proxy +- A VPN (Tailscale, WireGuard) +- Cloudflare Application Tunnel + +> [!CAUTION] +> Do not run Ignis on a public network without auth. Anyone with the url can read and write your vault files. + + + +## Setup with Docker Compose + +Ignis is not published to a registry yet. You need to build the image locally. + +```bash +git clone https://github.com/user/obsidian-bridge.git +cd obsidian-bridge +docker compose up -d +``` + +On first start, the container will download Obsidian from the official servers and set everything up, and also install Obsidian Headless CLI. This takes a minute or two. + +Example `docker-compose.yml`: + +```yaml +services: + ignis: + build: . + ports: + - "8080:8080" + environment: + - OBSIDIAN_VERSION=1.12.4 + - PUID=1000 + - PGID=1000 + volumes: + - ./vaults:/vaults + - ./data:/app/data + - obsidian-app:/app/obsidian-app + restart: unless-stopped + +volumes: + obsidian-app: +``` + +### Volumes + +| Mount | Description | +| ----- | ----------- | +| `/vaults` | Vault storage. Each subdirectory is a vault. | +| `/data` | state persistence for various ignis specific functionality, plugin management, headless sync config, etc | +| `/app/obsidian-app` | Cached Obsidian assets. Persisting this avoids re-downloading on container recreate. | + +### Environment Variables + +| Variable | Description | Default | +| -------- | ----------- | ------- | +| `PORT` | Server listen port | `8080` | +| `VAULT_ROOT` | Path to vault storage inside the container | `/vaults` | +| `DATA_ROOT` | Path to persistent data (plugin config, sync state, auth tokens) | `/app/data` | +| `OBSIDIAN_VERSION` | Obsidian version to download | `1.12.4` | +| `PUID` | User ID for file ownership | `1000` | +| `PGID` | Group ID for file ownership | `1000` | + +## Contributing + +Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, especially on how to report plugin compatibility issues. Check the [open issues](https://github.com/Nystik-gh/ignis/issues) for things to work on. + +## Architecture + +See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for details on the shim layer, plugin system, and server internals. + +## License + +This project is licensed under the [GNU Affero General Public License v3.0](LICENSE). diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..01fa103 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,100 @@ +# Architecture + +Ignis runs Obsidian in a browser by replacing its Electron backend with a shim layer that routes Node.js and Electron API calls to an Express server over HTTP and WebSocket. + +## Overview + +``` +Browser Server +┌──────────────────────┐ ┌──────────────────────┐ +│ Obsidian (unmodified)│ │ Express │ +│ ↕ │ HTTP │ /api/fs/* │ +│ Shim layer │ <────> │ /api/vault/* │ +│ fs, electron, etc. │ WS │ /api/plugins/* │ +│ ↕ │ <────> │ /api/ext/:plugin/* │ +│ Bridge plugin │ │ Ignis plugins │ +└──────────────────────┘ └──────────────────────┘ + ↕ + Filesystem (vaults/) +``` + +The shim layer makes Obsidian think it's running in Electron. The bridge plugin adds Ignis-specific features inside Obsidian. + +## Shim Layer + +### Loading + +The Obsidian index file is patched to run the shim loader first. It replaces the module system and makes a blocking HTTP request to fetch the vault's directory tree into memory. The request has to be blocking because Obsidian makes synchronous filesystem calls during page load, before the event loop is running, so the cache has to already be populated. + +### Modules + +| Module | Implementation | +| -------------------- | --------------------------------------------------------------------------------- | +| `fs` / `original-fs` | HTTP transport + client-side metadata/content caches | +| `electron` | ipcRenderer dispatcher, webFrame stubs | +| `@electron/remote` | Partial: clipboard (browser API), shell, dialog, Menu, BrowserWindow, nativeTheme | +| `path` | path-browserify | +| `crypto` | Web Crypto (randomBytes, createHash, scrypt) | +| `url` | Browser URL API wrapper | +| `process` | Platform/version stubs | +| `utils` | Utility functions | + +Unknown modules return an empty proxy and log a warning. The shim exposes two console helpers, one showing everything that has been accessed and one showing what is missing. + +### Filesystem + +On page load the server returns the full directory tree, which gets cached in memory with paths, sizes, and modification times. Sync filesystem calls hit the cache rather than the network. File contents are cached in an LRU cache after first read and written through immediately on writes. + +Sync calls use synchronous XHR to ensure blocking behavior. Async calls use fetch. Everything goes through a transport layer that handles vault ID injection, base64 encoding for binary files, and mapping HTTP error codes back to Node errno values. + +### IPC + +IPC is faked with a synchronous dispatcher that maps channel names to handlers. + +### Obsidian Plugin Compatibility + +Obsidian evals plugin code with its own require that checks its internal module map first, then falls back to the window-level require, which is the shim. Plugins that use the filesystem, path utilities, or crypto get the shim implementations without any changes. Plugins that need child processes or native addons won't work (for now)*. + +__child_process may be shimmable, not yet explored__ + +## Vaults + +Any subdirectory under the vault root is treated as a vault. The active vault is selected via a `?vault=` URL parameter. Without the queryparam, the last active vault is loaded, or the first discovered. + +## Server + +An Express server that handles filesystem operations, vault management, static file serving, and plugin route dispatch. + +**Route groups:** +- `/api/fs/*` - filesystem operations (read, write, stat, tree, mkdir, etc.) +- `/api/vault/*` - vault CRUD and config +- `/api/plugins/*` - Ignis plugin management (list, enable, disable) __WIP__ +- `/api/ext/:pluginId/*` - routes registered by individual Ignis plugins + +**WebSocket:** A file watcher monitors vault directories and pushes change events to connected clients, keeping the client-side metadata and content caches in sync. The websocket is also used by the headless-sync plugin to report status. + +**Bridge plugin auto-install:** On server startup and vault creation, the server copies the ignis-bridge plugin into each vault's `.obsidian/plugins/` directory. + +## Plugins + +Three things are called "plugin" in this project. + +### Obsidian Plugins + +Standard community and core Obsidian plugins. They work through the shim layer with no Ignis involvement beyond providing fs, path, and crypto. + +### Bridge Plugin (ignis-bridge) + +An Obsidian plugin auto-installed into every vault by the server. Source lives in `plugin/`, built to `plugin/main.js`. + +It adds file actions to Obsidian's UI: file download, folder ZIP download, and file upload via ribbon icon and context menu. It also injects custom settings tabs into Obsidian's settings modal by monkey-patching `app.setting.onOpen`, currently providing an Ignis plugin management tab. + +Not user-installable through Obsidian's plugin browser. Managed entirely by the server. + +### Ignis Plugins + +A basic plugin system for extending the server. Still early, the core lifecycle works but the API surface is minimal and likely to change. + +An Ignis plugin is a Node.js package under `server/plugins//` that exports an id, name, and a `register` function. On load it receives a context object with access to config, the WebSocket server, a file watcher, an Express router, a logger, and a persistent data directory. Plugins are enabled and disabled per vault, with state persisted in `data/plugin-config.json`. + +When enabled, a plugin's Express router is mounted at `/api/ext//`. A plugin can also optionally bundle an Obsidian plugin, a directory containing a standard Obsidian plugin (manifest.json, main.js) that gets auto-installed into the vault on enable and removed on disable. This bridges the server and client sides: the Ignis plugin handles server logic and routes, while the bundled Obsidian plugin provides the in-app UI or behavior. diff --git a/examples/INSTRUCTIONS.md b/examples/INSTRUCTIONS.md new file mode 100644 index 0000000..121c85b --- /dev/null +++ b/examples/INSTRUCTIONS.md @@ -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. diff --git a/examples/caddy-authelia/Caddyfile b/examples/caddy-authelia/Caddyfile new file mode 100644 index 0000000..27408a7 --- /dev/null +++ b/examples/caddy-authelia/Caddyfile @@ -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 +} diff --git a/examples/caddy-authelia/authelia/configuration.yml b/examples/caddy-authelia/authelia/configuration.yml new file mode 100644 index 0000000..904cb2d --- /dev/null +++ b/examples/caddy-authelia/authelia/configuration.yml @@ -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 diff --git a/examples/caddy-authelia/authelia/users_database.yml b/examples/caddy-authelia/authelia/users_database.yml new file mode 100644 index 0000000..72419c3 --- /dev/null +++ b/examples/caddy-authelia/authelia/users_database.yml @@ -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" diff --git a/examples/caddy-authelia/docker-compose.yml b/examples/caddy-authelia/docker-compose.yml new file mode 100644 index 0000000..598a1cc --- /dev/null +++ b/examples/caddy-authelia/docker-compose.yml @@ -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.4 + 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: diff --git a/examples/caddy-basic-auth/Caddyfile b/examples/caddy-basic-auth/Caddyfile new file mode 100644 index 0000000..c39f9d9 --- /dev/null +++ b/examples/caddy-basic-auth/Caddyfile @@ -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 +} diff --git a/examples/caddy-basic-auth/docker-compose.yml b/examples/caddy-basic-auth/docker-compose.yml new file mode 100644 index 0000000..c4e46e9 --- /dev/null +++ b/examples/caddy-basic-auth/docker-compose.yml @@ -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.4 + 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: