# Docker Compose Configuration Guide This guide explains every configuration value in the `docker-compose.yml` file for jotty·page. ## Basic docker-compose.yml Example ```yaml services: jotty: image: ghcr.io/fccview/jotty:latest container_name: jotty user: "1000:1000" ports: - "1122:3000" volumes: - ./data:/app/data:rw - ./config:/app/config:rw - ./cache:/app/.next/cache:rw restart: unless-stopped environment: - NODE_ENV=production # platform: linux/arm64 ``` **note**: Scroll down if you are running this with podman or via rootless docker ## Container Configuration ```yaml image: ghcr.io/fccview/jotty:latest ``` Specifies the Docker image to use. This pulls the latest stable version of jotty·page from GitHub Container Registry. You can use `latest`, `main`, `develop` _(for beta features when available)_ and the specific tag numbers for amd/arm specifically. ```yaml container_name: jotty ``` Sets a custom name for the running container. This makes it easier to manage with docker commands. ```yaml user: "1000:1000" ``` Runs the container with the specified user and group ID. This should match your host system user for proper file permissions. **Alternatively**, you can use the `PUID` and `PGID` environment variables instead of the `user:` directive. If neither is set, defaults to `1000:1000`. The `user:` directive takes precedence if both are used. This is particularly useful when running on NAS systems like Unraid. ```yaml userns_mode: keep-id ``` **Required for Podman and rootless Docker environments.** This option preserves the user namespace when mounting volumes, ensuring the container user (1000:1000) can properly access mounted directories. **When you need this option:** - Running with Podman instead of Docker - Running Docker in rootless mode - Getting permission denied errors when writing to mounted volumes (e.g., `EACCES: permission denied, open '/app/data/users/session-data.json'`) **Why it's needed:** In rootless environments, the container user cannot become root to access mounted volumes. The `userns_mode: keep-id` option maps the container user's UID/GID directly to the host's UID/GID, allowing proper file access. More info [here](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md#using-volumes) ## Network Configuration ```yaml ports: - "1122:3000" ``` Maps host port 1122 to container port 3000. You can change `1122` to any available port on your host system. ## Storage Configuration ```yaml volumes: - ./data:/app/data:rw - ./config:/app/config:rw - ./cache:/app/.next/cache:rw ``` Mounts host directories into the container for persistent data storage. Here's some detials: - `- ./data:/app/data:rw` Mounts your local `data` directory to `/app/data` inside the container with read-write permissions. This stores your checklists, notes, users, and settings. - `- ./config:/app/config:ro` Mounts your local `config` directory to `/app/config` as read-only. This contains custom themes and configuration files. - `- ./cache:/app/.next/cache:rw` Optional mount for Next.js build cache. Improves performance by persisting cache between container restarts. ## Runtime Configuration ```yaml restart: unless-stopped ``` Automatically restarts the container unless it was explicitly stopped. Ensures your app stays running. ## Environment Variables ```yaml environment: - NODE_ENV=production - PUID=1000 - PGID=1000 - UMASK=002 - HTTPS=true - SERVE_PUBLIC_IMAGES=yes - SERVE_PUBLIC_FILES=yes - STOP_CHECK_UPDATES=no - AUTH_MODE=oidc - OIDC_ISSUER= - OIDC_CLIENT_ID= - APP_URL=https://your-jotty-domain.com - OIDC_CLIENT_SECRET=your_client_secret - SSO_FALLBACK_LOCAL=yes - OIDC_ADMIN_GROUPS=admins ``` - `- NODE_ENV=production` Sets the Node.js environment to production mode for optimal performance and security. - `- PUID=1000` Optional. Process User ID that the container will run as. Defaults to `1000` if not set. Set this to match your host system's user ID (find it with `id -u` on Linux). Particularly useful on NAS systems like Unraid. **Note:** The `user:` directive in docker-compose takes precedence over PUID/PGID. - `- PGID=1000` Optional. Process Group ID that the container will run as. Defaults to `1000` if not set. Set this to match your host system's group ID (find it with `id -g` on Linux). **Note:** The `user:` directive in docker-compose takes precedence over PUID/PGID. - `- UMASK=002` Optional. Sets the default file creation mask. Defaults to `002` if not set. Controls default permissions for newly created files and directories. - `- HTTPS=true` Optional. Enables HTTPS mode for secure connections. - `- APP_URL=https://your-jotty-domain.com` Base URL of your jotty·page instance. Required for secure session (https) and SSO. - `- SERVE_PUBLIC_IMAGES=yes` Optional. Allows public access to uploaded images via direct URLs. - `- SERVE_PUBLIC_FILES=yes` Optional. Allows public access to uploaded files via direct URLs. - `- STOP_CHECK_UPDATES=no` Optional. If set to yes stops the github api call and won't give you a toast when a new update is available. - `- DISABLE_BRUTEFORCE_PROTECTION=true` Optional. Disables brute force protection for local login authentication. By default, accounts are temporarily locked after 3 failed login attempts with exponential delays (10s, 30s, 60s, etc.). Set to `true` to completely disable this security feature. ### SSO Configuration (Optional) - `- AUTH_MODE=oidc` Enables OIDC (OpenID Connect) single sign-on authentication. (Previously `SSO_MODE`, which still works as a fallback.) - `- OIDC_ISSUER=` URL of your OIDC provider (e.g., Authentik, Auth0, Keycloak). - `- OIDC_CLIENT_ID=` Client ID from your OIDC provider configuration. - `- OIDC_CLIENT_SECRET=your_client_secret` Optional. Client secret for confidential OIDC client authentication. - `- OIDC_CLIENT_ID_FILE=/run/secrets/oidc_client_id` Optional. Path to file containing the OIDC client ID. If set, takes priority over `OIDC_CLIENT_ID`. Useful for Docker Secrets. - `- OIDC_CLIENT_SECRET_FILE=/run/secrets/oidc_client_secret` Optional. Path to file containing the OIDC client secret. If set, takes priority over `OIDC_CLIENT_SECRET`. Useful for Docker Secrets. - `- SSO_FALLBACK_LOCAL=yes` Optional. Allows both SSO and local authentication methods. - `- OIDC_ADMIN_GROUPS=admins` Optional. Comma-separated list of OIDC groups that should have admin privileges. - `- OIDC_ADMIN_ROLES=admin` Optional. Comma-separated list of OIDC roles that should have admin privileges. - `- OIDC_USER_GROUPS=jotty_users,app_users` Optional. Comma-separated list of OIDC groups allowed to access the application. If set, only users in these groups (or admins) can log in. - `- OIDC_USER_ROLES=user,member` Optional. Comma-separated list of OIDC roles allowed to access the application. If set, only users with these roles (or admins) can log in. ## API Documentation Service jotty includes an optional API documentation service that provides interactive documentation for all API endpoints using ReDoc. ### Basic Setup 1. **Enable API Docs**: Add `ENABLE_API_DOCS=true` to your jotty environment variables 2. **Start the Service**: Run `docker-compose --profile api-docs up -d` 3. **Access**: Visit `http://localhost:8080` (or your configured `API_DOCS_PORT`) ### Health Checks To keep the image as small as possible I try to not install many extra dependencies if they are not needed by the main app. For health checks we will simply use node to make an http request to the health endpoint. ```yaml healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"] interval: 30s timeout: 10s start_period: 40s retries: 3 ``` ### Service Configuration ```yaml api-docs: image: redocly/redoc:latest container_name: jotty-api-docs ports: - "${API_DOCS_PORT:-8080}:80" environment: SPEC_URL: http://your-jotty-url.com/api/docs depends_on: - jotty profiles: - api-docs ``` ## Platform Configuration ```yaml platform: linux/arm64 ``` Optional. Specifies the target platform. Uncomment this line if running on ARM64 systems (like Apple Silicon Macs or Raspberry Pi). ## Podman Rootless via Quadlet If you are running via [podman-quadlet](https://docs.podman.io/en/latest/markdown/podman-quadlet.1.html) you will need to set the options above for - PUID & PGID - userns_mode A complete Container unit looks like ``` [Container] AutoUpdate=registry Image=ghcr.io/fccview/jotty:latest PublishPort=3000:3000 Volume=/srv/jotty/data:/app/data:rw Volume=/srv/jotty/config:/app/config:rw Volume=/srv/jotty/cache:/app/cache:rw Environment=NODE_ENV=production Environment=PUID=1000 Environment=PGID=1000 Environment=APP_URL=https://EXTERNAL_URL UserNS=keep-id ```