/callback`. Copy it with the copy button and add it as callback URL to your Pocket ID application.
+
+### 4. Test the Configuration
1. Log out of OrcaCD if you are currently logged in.
-2. Click on the "Login with Pocket ID" button on the login page.
-3. You will be redirected to the Pocket Id login page. Enter your credentials and log in.
+2. Click on the "Continue with Pocket ID" button on the login page.
+3. You will be redirected to the Pocket ID login page. Enter your credentials and log in.
4. After successful authentication, you will be redirected back to OrcaCD and logged in with your Pocket ID account.

+
+## Provider settings
+
+When a provider is saved, the Hub loads its discovery document (`/.well-known/openid-configuration`). If that fails, the provider is not saved. The client secret is stored encrypted; leave it blank when editing to keep the current one.
+
+The following options are enabled by default:
+
+- **Enabled**: Disabled providers are not shown on the login page. Disabling or deleting a provider signs out all users linked to it.
+- **Require verified emails**: Logins are only accepted if the provider confirms the email address with `email_verified=true`.
+- **Allow auto signup**: New OrcaCD users are created on their first login. If disabled, only existing users can log in.
+
+### Self-hosted providers in a private network
+
+The Hub talks to the provider directly to load the discovery document, exchange the login code and fetch user information. These requests are protected against SSRF, so issuers that resolve to a private IP address (e.g. `192.168.x.x` or `10.x.x.x`) are rejected and the provider can not be saved. Add the IP or range of your provider to the `ALLOWED_INTERNAL_IPS` environment variable of the Hub to allow it. See the [environment variables documentation](/docs/configuration/env-variables).
+
+## How SSO users are handled
+
+- **Login flow**: OrcaCD uses the authorization code flow with PKCE (`S256`), a state parameter and a nonce.
+- **User information**: The email address, name and profile picture are read from the ID token. If the ID token does not contain the email address or `email_verified`, the Hub fetches them from the userinfo endpoint of the provider. An email address is required to log in.
+- **Account linking**: On the first login with a provider, OrcaCD looks for an existing user with the same email address and links the SSO login to it. This also works for accounts that were created with a password, including the admin account. Accounts whose users changed the email address themselves are not linked, because OrcaCD does not verify these addresses. Such logins fail with "Your account could not be linked. Please contact an administrator." An admin can resolve this by changing the email address of the account in **User Management**. Only a change by an admin clears the unverified state; saving the same address again does not. If no user exists, a new one is created (see "Allow auto signup"). Later logins are matched by the provider's user ID, and the name and email address are updated from the provider on every login.
+- **Roles**: New SSO users get the role `User`. Groups or roles from the provider are not mapped. Admins can promote users in the **User Management** section of the Admin settings.
+
+
+ Because SSO logins are linked to existing accounts by email address, only disable "Require
+ verified emails" if your provider makes sure that users can not use email addresses they do not
+ own. Otherwise, someone could log in as an existing user, including an admin.
+
diff --git a/content/docs/guides/reverse-proxy.mdx b/content/docs/guides/reverse-proxy.mdx
index c0e56dd..ef0b1ee 100644
--- a/content/docs/guides/reverse-proxy.mdx
+++ b/content/docs/guides/reverse-proxy.mdx
@@ -6,18 +6,23 @@ description: Learn how to use a reverse proxy with OrcaCD
In a production environment, it is strongly recommended to run the OrcaCD Hub behind a reverse proxy with a domain and a valid TLS certificate.
- Make sure to adjust the `TRUSTED_PROXIES` environment variable to include the IP address of your
- reverse proxy, otherwise the Hub will not be able to determine the correct client IP address. You
- will also need to set the public URL in the hub and agent environment variables.
+ Make sure to adjust the `TRUSTED_PROXIES` environment variable to include the IP address (or CIDR
+ range) of your reverse proxy, otherwise the Hub will not be able to determine the correct client
+ IP address. You will also need to set the public URL in the hub and agent environment variables.
## Nginx
To use Nginx as a reverse proxy for OrcaCD, expose the Hub on localhost only and forward traffic from your public domain to the Hub port.
-Use this `server` block in your Nginx config:
+Use this `map` and `server` block in your Nginx config (the `map` block belongs into the `http` context):
```nginx lineNumbers
+map $http_upgrade $connection_upgrade {
+ default upgrade;
+ '' close;
+}
+
server {
listen 80;
server_name orcacd.example.com;
@@ -36,7 +41,7 @@ server {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
- # Prevent Websocket being closed by Nginx
+ # Prevent the Agent WebSocket and the live updates (SSE) from being closed by Nginx
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}
@@ -62,13 +67,17 @@ services:
hub:
image: ghcr.io/orcacd/hub:latest
container_name: orca-hub
- ports:
- - "127.0.0.1:8080:8080"
restart: unless-stopped
env_file: .env
- labels: // [!code ++]
- - "traefik.enable=true" // [!code ++]
- - "traefik.http.routers.orcacd.rule=Host(`orcacd.example.com`)" // [!code ++]
+ security_opt:
+ - no-new-privileges:true
+ cap_drop:
+ - ALL
+ ports:
+ - "127.0.0.1:8080:8080"
+ labels: # [!code ++]
+ - "traefik.enable=true" # [!code ++]
+ - "traefik.http.routers.orcacd.rule=Host(`orcacd.example.com`)" # [!code ++]
volumes:
- ./data/hub:/app/data
```
diff --git a/content/docs/helping-out/contributing.mdx b/content/docs/helping-out/contributing.mdx
index 61ba795..4d46d8f 100644
--- a/content/docs/helping-out/contributing.mdx
+++ b/content/docs/helping-out/contributing.mdx
@@ -26,21 +26,90 @@ We use Go and Node.js for the development of the backend and frontend respective
### Setting up the development environment
1. Install all required tools listed above.
-2. Clone the repository and navigate to the project directory.
-3. For the frontend, navigate to the `frontend/` directory and run `npm ci` to install dependencies.
-4. Run the frontend development server with `node --run dev` from the `frontend/` directory.
-5. Run the backend services with `just run-hub` and `just run-agent` in the `backend/` directory.
-6. Access the app at `http://localhost:3000` and the hub API at `http://localhost:8080`.
+2. Clone the [repository](https://github.com/OrcaCD/orca-cd) and navigate to the project directory.
+3. Install the frontend dependencies:
+
+ ```sh
+ cd frontend
+ pnpm i --frozen-lockfile
+ ```
+
+4. Copy `backend/.env.dev.example` to `backend/.env` and set `APP_SECRET` to a random value with at least 32 characters. The `Justfile` loads this file automatically.
+
+ ```sh
+ cp backend/.env.dev.example backend/.env
+ ```
+
+5. Start the Hub and the frontend development server from the repository root:
+
+ ```sh
+ just dev
+ ```
+
+6. Open the app at `http://localhost:3000`. The Hub API runs on `http://localhost:8080`, and the Vite dev server proxies `/api` requests to it.
+
+To run an Agent locally, [register an agent](/docs/advanced/architecture/agents) in the UI, set `AUTH_TOKEN` in `backend/.env` and start it with `just run-agent` (or use `just dev-all` to start the Hub, Agent and frontend together).
+
+### Just commands
+
+The `Justfile` in the repository root includes all backend commands, so they can be run from the root or from the `backend/` directory. To list all available commands with a short description, run:
+
+```sh
+just -l
+```
+
+Backend tests need `CGO_ENABLED=1`. The `just` recipes set it for you. If you run `go test` directly, set it yourself:
+
+```sh
+CGO_ENABLED=1 go test -v -race -run TestName ./internal/hub/routes/
+```
+
+### Linting, formatting and type checking
+
+Run these commands from the `frontend/` directory (and from `e2e/` if you changed the E2E tests):
+
+```sh
+node --run lint # oxlint
+node --run format # oxfmt (use format:check to only verify)
+node --run typecheck # TypeScript type check
+node --run translations:check # check for unused and missing message keys (frontend only)
+```
+
+For the backend, use `just lint`, `just fmt` and `just test`.
+
+### Translations
+
+The frontend uses Paraglide (inlang) for translations. Messages are stored in `frontend/messages/.json`, with `en.json` as the source file. When you add a new message key, add it to every locale file. Remove messages you no longer use, because `node --run translations:check` fails on unused messages and on keys that are missing in `en.json`. All other translations are managed on Crowdin, see [Translating](/docs/helping-out/translating).
+
+### End-to-end tests
+
+The E2E tests use [Playwright](https://playwright.dev) and live in the `e2e/` directory. Install the dependencies and browsers first:
+
+```sh
+cd e2e
+pnpm i --frozen-lockfile && pnpm run install:browsers
+```
+
+Then run the tests:
+
+```sh
+pnpm test # run all tests headless
+pnpm test:ui # run the tests in the interactive Playwright UI
+```
+
+- Playwright builds the Hub and Agent images and starts the Hub with `docker-compose.e2e.yml` on `http://127.0.0.1:8090`. Set `E2E_SKIP_BUILD=1` to skip the image build if the images are already built.
+- External services are mocked by small Node.js servers in `e2e/mock/`: `gitea` (Git provider), `oidc` (OIDC provider) and `receiver` (notification targets). The `certs` folder contains the self-signed certificate of the Gitea mock, which the Hub is configured to trust.
+- The agent, application and image tests start an Agent container through Docker Compose and run after all other tests. They need access to the Docker socket.
### Running locally with Docker
A Docker Compose file is provided for running the full stack locally:
```sh
-docker compose -f docker-compose.dev.yaml up --build
+docker compose -f docker-compose.dev.yml up --build
```
-The hub service will be available at `http://localhost:8080`.
+The Hub will be available at `http://localhost:8080`. The Agent needs an `AUTH_TOKEN`, so [register an agent](/docs/advanced/architecture/agents) in the UI and set it in `docker-compose.dev.yml`. To test OIDC login, start a local [Pocket ID](https://pocket-id.org) instance on `http://localhost:1411` with `--profile pocket-id`.
### Submitting a Pull Request
@@ -56,11 +125,15 @@ Before you submit the pull request for review please ensure that
fix: hide global audit log switch for non admin users
```
- Where `TYPE` can be:
- - feat - is a new feature
- - doc - documentation only changes
+ Where `type` can be:
+ - feat - a new feature
- fix - a bug fix
- - refactor - code change that neither fixes a bug nor adds a feature
+ - docs - documentation only changes
+ - refactor - a code change that neither fixes a bug nor adds a feature
+ - test - adding or updating tests
+ - ci - changes to the CI workflows
+ - chore - maintenance such as dependency updates
- Your pull request has a detailed description
- You have added tests for any new features or bug fixes
+- Linting, formatting, type checks and tests pass
diff --git a/content/docs/helping-out/documentation.mdx b/content/docs/helping-out/documentation.mdx
index dca7d1f..3a99307 100644
--- a/content/docs/helping-out/documentation.mdx
+++ b/content/docs/helping-out/documentation.mdx
@@ -3,16 +3,18 @@ title: Documentation
description: Contribute to the OrcaCD website or documentation
---
-This guide explains how to add or edit the OrcaCD documentation. The source code of the documentation is stored in the [OracaCD/docs GitHub repository](https://github.com/OrcaCD/docs).
+This guide explains how to add or edit the OrcaCD documentation. The source code of the documentation is stored in the [OrcaCD/docs GitHub repository](https://github.com/OrcaCD/docs).
## 1. Where docs live
-All markdown pages are under `/content/docs`. The file `meta.json` controls the sidebar structure and order.
+All pages are MDX files under `/content/docs`. The file `/content/docs/meta.json` controls the sidebar structure and order. A section folder can have its own `meta.json` to define the order of its pages (e.g. `/content/docs/guides/meta.json`).
+
+To run the site locally, install the dependencies with `pnpm install` and start the development server with `pnpm run dev`.
## 2. Adding a new page
1. Pick the correct folder that matches a collection pattern (e.g. `/guides`).
-2. Create `/content/docs//.md`.
+2. Create `/content/docs//.mdx`.
3. Add the frontmatter code:
```yaml lineNumbers
@@ -22,15 +24,25 @@ description: Get OrcaCD running quickly with Docker installation
---
```
-4. Run `npm run dev` and check your page at `http://localhost:3000/docs//`.
+4. Run `pnpm run dev` and check your page at `http://localhost:3000/docs//`.
+5. If the section has its own `meta.json`, add the new page to its `pages` list.
- To use components in the documentation please look at the [Fumadadocs Documentation for
+ To use components in the documentation please look at the [Fumadocs Documentation for
Markdown](https://www.fumadocs.dev/docs/markdown)
## 3. Submitting changes
-After making changes you can create a pull request to the `main` branch. Please make sure to commit using Conventional Commits (`docs: update guides`).
+Before opening a pull request, format and check your changes:
+
+```sh
+pnpm run format # format with oxfmt
+pnpm run lint # lint with oxlint
+pnpm run types:check # type check
+pnpm run build # make sure the site builds
+```
+
+After that you can create a pull request to the `main` branch. Please make sure to commit using Conventional Commits (`docs: update guides`).
Thanks for helping out!
diff --git a/content/docs/helping-out/translating.mdx b/content/docs/helping-out/translating.mdx
index 73fed3a..9106655 100644
--- a/content/docs/helping-out/translating.mdx
+++ b/content/docs/helping-out/translating.mdx
@@ -16,6 +16,8 @@ Please use informal language for translations if appropriate.
3. Open the `en.json` source file.
4. Now you can start translating the strings.
+Translations are synced back to the repository automatically. A nightly GitHub Action downloads them from Crowdin and opens a pull request from the `i18n_crowdin` branch.
+
## Adding a New Language
Is your language missing from Crowdin? You can [request its addition](https://github.com/OrcaCD/orca-cd/issues/new?assignees=&labels=language-request&projects=&template=language-request.yml&title=%F0%9F%8C%90+Language+request%3A+%3Clanguage+name+in+english%3E).
diff --git a/content/docs/index.mdx b/content/docs/index.mdx
index e08826f..3114c74 100644
--- a/content/docs/index.mdx
+++ b/content/docs/index.mdx
@@ -40,14 +40,12 @@ The structure, architecture and concepts of OrcaCD can be found in the [architec

-import { HomeIcon } from "lucide-react";
-
Quickstart installation
- Learn more the configuration options.
+ Learn more about the configuration options.
diff --git a/content/docs/setup/installation.mdx b/content/docs/setup/installation.mdx
index 345fa7d..cca252f 100644
--- a/content/docs/setup/installation.mdx
+++ b/content/docs/setup/installation.mdx
@@ -19,31 +19,42 @@ Before you start, make sure you have:
- For a publicly reachable setup: a domain with a DNS record pointing to your server, and a reverse proxy which also handles TLS. By default the Hub only listens on `127.0.0.1:8080`, and you put your own reverse proxy (Nginx, Caddy, Traefik, ...) in front of it. See the [reverse proxy guide](../guides/reverse-proxy).
- Just testing OrcaCD locally? You can skip the domain and reverse proxy setup, set the
- `APP_URL=http://localhost:8080` in the `.env` file, and access the Hub at `http://localhost:8080`.
+ Just testing OrcaCD locally? You can skip the domain and reverse proxy setup, set
+ `APP_URL=http://localhost:8080` in the `.env` file and `HUB_URL=http://hub:8080` in the
+ `agent.env` file, and access the Hub at `http://localhost:8080`.
## Start Hub and Agent [step]
-Download the [`docker-compose.yml`](https://raw.githubusercontent.com/OrcaCD/orca-cd/main/docker-compose.yml) and [`.env`](https://raw.githubusercontent.com/OrcaCD/orca-cd/main/.env.example) file:
+Download the [`docker-compose.yml`](https://raw.githubusercontent.com/OrcaCD/orca-cd/main/docker-compose.yml), the [`.env`](https://raw.githubusercontent.com/OrcaCD/orca-cd/main/.env.example) file for the Hub and the [`agent.env`](https://raw.githubusercontent.com/OrcaCD/orca-cd/main/agent.env.example) file for the Agent:
```bash tab="curl"
curl -o docker-compose.yml https://raw.githubusercontent.com/OrcaCD/orca-cd/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/OrcaCD/orca-cd/main/.env.example
+curl -o agent.env https://raw.githubusercontent.com/OrcaCD/orca-cd/main/agent.env.example
```
```bash tab="wget"
wget -O docker-compose.yml https://raw.githubusercontent.com/OrcaCD/orca-cd/main/docker-compose.yml
wget -O .env https://raw.githubusercontent.com/OrcaCD/orca-cd/main/.env.example
+wget -O agent.env https://raw.githubusercontent.com/OrcaCD/orca-cd/main/agent.env.example
```
-Edit the `.env` file according to the instructions in the file. The most important values are:
+Edit both files according to the instructions in them. The most important values in the `.env` file of the Hub are:
- `APP_URL` - the URL under which the Hub will be reachable. OrcaCD does not provision this URL for you: it is your domain pointing at your reverse proxy (e.g. `https://orcacd.example.com`).
- `APP_SECRET` - used for authentication and database encryption. Generate one with `openssl rand -base64 42`.
+
+In the `agent.env` file of the Agent:
+
- `HUB_URL` - the URL the Agent uses to reach the Hub, usually the same as `APP_URL`.
- `AUTH_TOKEN` - leave empty for now; you will create it in the Hub UI in a later step.
+
+ Do not put `APP_SECRET` into the `agent.env` file or give the Agent the `.env` file of the Hub.
+ Compose files deployed by the Agent can read the Agent's environment.
+
+
We recommend customizing other environment variables as needed.
See the [environment variables page](../configuration/env-variables) for more details.
@@ -64,16 +75,28 @@ By default the hub only listens on port `8080` on localhost. Configure your reve
## Create an Admin Account [step]
-Open the Hub in your browser at the `APP_URL` you configured (e.g. `https://orcacd.example.com/login`) and create an admin account.
+As long as no user exists, the Hub prints a one-time setup code to its logs on every start. You need this code to create the first admin account:
+
+```bash
+docker compose logs hub | grep setup-code
+```
+
+The log entry also contains a link like `https://orcacd.example.com/register#setup-code=XXXX-XXXX-XXXX-XXXX`. Open it to get the code filled in automatically, or open `https://orcacd.example.com/register` and enter the code manually. The password must be at least 12 characters long and include an uppercase letter, a lowercase letter, a number and a special character.

## Connect your first Agent [step]
-Navigate to the Agents page and click "Add Agent". Follow the instructions and copy the token and add it as `AUTH_TOKEN` to the `.env` file of your Agent deployment and restart the Agent.
+Navigate to the Agents page, click "Add Agent" and enter a name. The setup dialog shows the generated token and a `compose.yml` for the Agent. As the Agent from this quickstart is already part of your `docker-compose.yml`, select **Copy agent auth token** in the menu next to **Copy** and add the token as `AUTH_TOKEN` to the `agent.env` file. Then recreate the Agent container so it picks up the new value (a plain `docker compose restart` does not reload the env file):
+
+```bash
+docker compose up -d agent
+```

+The dialog waits for the first connection and switches to **Connected** as soon as the Agent is online. The token is only shown once.
+
## Start Deploying [step]
Add your first repository and create your first deployment. Connect a [OIDC provider](../guides/oidc) to allow your team to log in or invite them on the admin page.
diff --git a/content/docs/setup/upgrading.mdx b/content/docs/setup/upgrading.mdx
index c15c203..d0f3839 100644
--- a/content/docs/setup/upgrading.mdx
+++ b/content/docs/setup/upgrading.mdx
@@ -11,15 +11,22 @@ description: Keep your OrcaCD installation up to date
To create a backup of your database, you can run the following command:
```bash
- docker compose exec hub /app/hub backup
+ docker compose exec hub /app/hub export
```
- After running this command make sure to copy the created backup file and include it in your backup strategy.
+ The backup is written to `./data/hub/hub-export-YYYYMMDD-HHMMSS.db` on the host. Make sure to include this file in your backup strategy. See the [CLI reference](../advanced/cli#export) for more details.