Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export default defineConfig({
site,
trailingSlash: 'never',
publicDir: './static',
server: { host: true },
build: { format: 'file' },
image: {
remotePatterns: [
{ protocol: 'https', hostname: 'i.ytimg.com' },
{ protocol: 'https', hostname: 'miro.medium.com' },
{ protocol: 'https', hostname: 'www.virtualizationhowto.com' }
{ protocol: 'https', hostname: 'miro.medium.com' }
]
},
vite: {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 8 additions & 3 deletions src/components/community/CommunityCard.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ interface Props {
}
const { item } = Astro.props;

// Remote thumbnails need their size fetched at build time; imported assets already carry it.
const thumbnail =
typeof item.thumbnail === 'string'
? { src: item.thumbnail, inferSize: true as const }
: item.thumbnail && { src: item.thumbnail };

const formatDate = (isoDate: string) => {
const date = new Date(`${isoDate}T00:00:00Z`);
if (Number.isNaN(date.getTime())) return isoDate;
Expand Down Expand Up @@ -56,11 +62,10 @@ const badge =
<a href={item.url} target="_blank" rel="noopener noreferrer" class={card}>
<div class={accent} />
<div class="relative aspect-video w-full overflow-hidden bg-muted">
{item.thumbnail ? (
{thumbnail ? (
<Image
src={item.thumbnail}
{...thumbnail}
alt=""
inferSize
widths={[480, 960]}
sizes="(min-width: 64rem) 30vw, (min-width: 40rem) 45vw, 90vw"
class="h-full w-full object-cover"
Expand Down
40 changes: 40 additions & 0 deletions src/content/blog/opentelemetry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: 'OpenTelemetry in Arcane 2.16.0'
description: 'Arcane 2.16.0 can export metrics, traces, and logs to any OpenTelemetry collector.'
date: 2026-10-10
kind: update
featured: true
banner: 'Arcane 2.16.0 adds OpenTelemetry metrics, traces, and logs.'
---

Arcane 2.16.0 can export metrics, traces, and logs with [OpenTelemetry](https://opentelemetry.io), so you can send them to a collector and view them alongside the rest of your monitoring.

It is off by default. Turn it on with the standard `OTEL_*` environment variables:

```yaml
environment:
- OTEL_METRICS_EXPORTER=otlp
- OTEL_TRACES_EXPORTER=otlp
- OTEL_LOGS_EXPORTER=otlp
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
```

## What gets sent

Metrics include container counts and states, CPU and memory for each container, API latency, background jobs, image updates, and vulnerability counts.

Traces follow a request through Arcane, down to the Docker calls and database queries it makes. If your agents send to the same backend, a request the manager passes to an agent stays in one trace.

Logs are the same lines Arcane already prints to stdout, now with the trace ID attached so you can jump from a log line to its trace.

The web UI sends its own page load times, Web Vitals, and JavaScript errors. It posts them to Arcane, and Arcane forwards them to your collector, so you don't have to expose the collector to browsers.

Query strings, SQL parameter values, request bodies, and credentials are left out.

## Dashboard

There is an official Grafana dashboard covering everything Arcane sends. Import dashboard ID [`25894`](https://grafana.com/grafana/dashboards/25894) and pick your Prometheus, Tempo, and Loki data sources.

## Getting started

The [OpenTelemetry guide](/docs/settings/opentelemetry) has a full collector config, the Prometheus scrape option, and the other settings you can use.
2 changes: 1 addition & 1 deletion src/content/docs/docs/docker/activity.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Go to **Settings → Activity**:
With the `jobs:manage` permission:

1. Open the environment's **Automations** tab.
2. Open **Run history** for a job to see each run's attempts, errors, and per-target results, plus its operation output when it has an activity.
2. Open **Run history** for a job to see each run's attempts, errors, and per-target results, plus its operation output when it has an activity. Runs of image update checks, auto updates, vulnerability scans, image patching, GitOps syncs, and backups also list their **Steps** with each step's status, progress, and failure count.

A queued run on a remote environment shows **Waiting for environment** until the agent is reachable. Agents running an older Arcane version must be upgraded to report run history.

Expand Down
2 changes: 2 additions & 0 deletions src/content/docs/docs/docker/auto-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The **Updates** page lists pending updates in **Containers** and **Projects** ta
- **Disable automatic updates** and **Enable automatic updates** toggle automatic installation for one container. Disabled rows stay listed and still get checks and notifications. If the action shows _Controlled by Docker label_, change the label instead.
- **Update All** applies every pending update in the selected environment, including rows not on the current page.

**Update Containers** on the **Containers** page runs the same **Update All** after confirmation. **Update Projects** on the **Projects** page asks for confirmation, checks every image for updates, and redeploys each project that has one.

> [!IMPORTANT]
> **Updates → Update All** updates your containers and projects. **Environments → Update All** upgrades Arcane managers and agents; see [Remote Environments](/docs/remote/environments). If Arcane's own container has a pending update, **Updates → Update All** includes it and restarts Arcane after the other updates finish. The confirmation tells you when this applies.

Expand Down
2 changes: 2 additions & 0 deletions src/content/docs/docs/docker/backups.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ Retention runs separately for each schedule, and separately for local and S3 cop

Deleting backups by hand also tries to remove every stored copy. If the local copy is deleted but S3 deletion fails, the row stays as S3-only and Arcane reports the error. If any remote copy can't be deleted, the row stays, so the backup isn't wrongly shown as gone.

Deleting a local backup doesn't free its disk space right away. Arcane prunes the local system and volume backup repositories at 04:15 and 16:15 every day in Arcane's configured timezone, and Rustic keeps deleted data for about a day before a prune removes it, so the space can take up to two days to come back.

### System-managed volume backups

To back up many volumes with one schedule, an admin can open **Settings → Backups**, click **Create schedule**, and choose the **Volume** type. Set the schedule, retention, destination, and stop-containers option as above, then pick which volumes to include:
Expand Down
4 changes: 4 additions & 0 deletions src/content/docs/docs/docker/containers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ The **Overview** tab's **Auto Update** toggle turns automatic installation on or

When a newer image is available, the detail header shows an **Update available** badge and an **Update** action to apply it on the spot (requires the `containers:autoupdate` permission). If the container belongs to a project, the header links to that project too.

## Open a shell

With `containers:exec`, a running container's detail view has a **Shell** tab. Pick `sh`, `bash`, `ash`, `zsh`, or a custom path. Your browser remembers the choice per Compose service, or per container name for standalone containers, so it survives recreating the container. Otherwise the tab uses the environment's **Default Shell** (**Environments → the environment → Docker**), `/bin/sh` by default.

## View logs

Open a container's detail view and switch to the **Logs** tab. The viewer:
Expand Down
6 changes: 4 additions & 2 deletions src/content/docs/docs/docker/projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ Use the **Labels** filter to find projects with a container label. Enter a key s
2. Enter a name.
3. Paste or write the Compose YAML.
4. Optional: open the **Environment Configuration (.env)** editor and add variables. Arcane saves them to a `.env` file next to the Compose file.
5. Click **Create Project**. Arcane saves the project and tries to start it.
5. Click **Create Project**, or press `Ctrl/Cmd+S`. Arcane saves the project and tries to start it.

Arcane creates the project folder from the name. If the Projects Directory already has a folder with that name that contains no Compose file and isn't used by another project, Arcane creates the project in it and keeps the files already there. An existing `.env` is kept if you leave the `.env` editor empty; different content is rejected. Otherwise Arcane adds a number to the folder name, such as `myapp-1`.

## Control a project

Expand Down Expand Up @@ -82,7 +84,7 @@ From the workspace panel you can:
- **Edit**: open any UTF-8 text file in its own tab. Binary files can be uploaded but not edited.
- **Rename**, **Move**, and **Delete**: reorganize the folder. Non-empty folders can be deleted recursively.

All file changes are staged until you **Save** the project. Build and dependency folders (`.git`, `node_modules`, `vendor`, `dist`, `build`, and similar) are hidden from the tree. For projects using Git **Pull**, files managed by the sync are read-only; other workspace files stay editable.
All file changes are staged until you **Save** the project or press `Ctrl/Cmd+S`. Middle-click a tab to close it. Build and dependency folders (`.git`, `node_modules`, `vendor`, `dist`, `build`, and similar) are hidden from the tree. For projects using Git **Pull**, files managed by the sync are read-only; other workspace files stay editable.

> [!NOTE]
> The Compose file, `.env`, `.env.git`, and `project.env` are protected. They show a lock icon and can't be renamed, moved, or deleted from the tree. Edit them through their own editors instead.
Expand Down
6 changes: 5 additions & 1 deletion src/content/docs/docs/docker/template-registries.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Include `$schema` so editors can validate the file:
"compose_url": "https://raw.githubusercontent.com/yourcompany/docker-templates/main/internal-app/docker-compose.yml",
"env_url": "https://raw.githubusercontent.com/yourcompany/docker-templates/main/internal-app/.env.example",
"documentation_url": "https://github.com/yourcompany/docker-templates/tree/main/internal-app",
"icon_url": "https://raw.githubusercontent.com/yourcompany/docker-templates/main/internal-app/icon.svg",
"tags": ["internal", "webapp", "postgres"]
}
]
Expand Down Expand Up @@ -92,7 +93,7 @@ The registry must match the schema at `https://github.com/getarcaneapp/arcane-te

### Template fields

All template fields are required.
All template fields are required except `icon_url`.

| Field | Description |
| ------------------- | --------------------------------------------------------- |
Expand All @@ -104,4 +105,7 @@ All template fields are required.
| `compose_url` | Direct URL to the Compose file. |
| `env_url` | Direct URL to the `.env.example` file. |
| `documentation_url` | URL to the template's docs or README. |
| `icon_url` | Direct URL to the template's icon. |
| `tags` | Array of unique slugs (lowercase, hyphens), at least one. |

Arcane shows `icon_url` for remote templates and doesn't read icons from their Compose files. After you **Download** a template, an `x-arcane` icon in its Compose file takes precedence.
4 changes: 4 additions & 0 deletions src/content/docs/docs/get-started/preview-builds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ volumes:
> [!TIP]
> To stay on one build instead of following `next`, use its versioned tag, for example `ghcr.io/getarcaneapp/manager:v2.4.0-next.1`.

## Development branding

Preview builds, and any other build whose version isn't a plain release such as `v2.4.0`, use a development icon in place of the Arcane logo, favicon, and app icons. To show the standard logo instead, click the version number at the bottom of the sidebar and switch off **Development Branding** (requires `settings:write`).

## Download a binary

<BinaryDownloads />
Expand Down
78 changes: 78 additions & 0 deletions src/content/docs/docs/get-started/preview-features.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: 'Preview Features'
description: 'Turn on features that are still in development in the web UI, iOS app, and CLI.'
---

import { Badge, TabItem, Tabs } from '@astrojs/starlight/components';

Preview features are still in development. They are off by default, and you turn each one on separately in the web UI, the iOS app, or the CLI. They may not work as expected, and their behavior may change or be removed in a later release.

## All environments

<Badge text="Preview" variant="caution" />

The all environments preview replaces the environment switcher with one combined view. Resource lists such as containers, projects, images, volumes, networks, ports, updates, and vulnerability scans show items from every enabled environment together, with each item labeled by the environment it belongs to. Actions on a resource run in that resource's environment.

The preview is turned on separately in each client. Turning it on in the web UI doesn't change the iOS app or the CLI.

### Turn on all environments

<Tabs syncKey="arcane-client">

<TabItem label="Web UI">

1. Click your avatar at the bottom of the sidebar and select **Account**.
2. Open the **Previews** tab.
3. Switch on **All environments (preview)**.

The setting is saved to your user account, so it follows you to any browser you sign in from. While the preview is on, the **Previews** tab also offers:

- **Environment labels**: show the environment's name in resource lists, or only a color dot with the name on hover.
- **Environment colors**: pick a color for each environment's label.

To turn the preview off, switch it off on the **Previews** tab, or open the environment switcher and click **Turn off preview**.

</TabItem>

<TabItem label="iOS app">

1. Open the **More** tab and select **Preview Features**.
2. Switch on **All Environments**.

You can also turn it on from the walkthrough: tap **Replay Walkthrough** on the same screen and tap **Enable Preview** on the last page. **Environment Colors** sets the color shown next to each environment's resources.

The setting is stored on the device. Environment switching is hidden while the preview is on; switch **All Environments** off to choose a single environment again.

</TabItem>

<TabItem label="CLI">

Set `previews.allEnvironments` in your [CLI config](/docs/reference/cli/config):

```bash
arcane-cli config set previews.allEnvironments true
arcane-cli containers list
```

Lists use one combined table with an `ENVIRONMENT` column. To run a single command against one environment, pass `--env <id>`. To turn the preview off and return to your saved default environment:

```bash
arcane-cli config set previews.allEnvironments false
```

See [Preview every environment](/docs/reference/cli/config#preview-every-environment) for resource pickers, fleet confirmations, and the aggregate JSON format.

</TabItem>

</Tabs>

### What changes while it's on

- **Only enabled environments are included.** Disabled environments don't appear. If an environment can't be reached, the rest still load and a notice lists the ones that are missing.
- **Environment switching is unavailable.** The combined view replaces picking a single environment. Use list filters to focus on one environment without leaving the view.
- **Bulk actions apply to every environment.** Update checks, updates, and pruning run on all enabled environments, even when a list is filtered. The confirmation shows how many environments the action will run on, so review it before you continue.
- **Global pages work as before.** Pages that aren't tied to one environment, such as users, registries, templates, and variables, keep their existing scope.

## Report a problem

Report problems with preview features on [GitHub Issues](https://github.com/getarcaneapp/arcane/issues). Include which client you were using and the version shown on your dashboard.
4 changes: 2 additions & 2 deletions src/content/docs/docs/networking/reverse-proxy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@ A working setup logs `Edge tunnel connected to manager` with `transport=grpc`. I

Arcane rate-limits authentication endpoints (login, token refresh, OIDC callback) per client IP. Behind a reverse proxy, every request appears to come from the proxy's IP. That weakens brute-force protection and can lock out legitimate users who share the proxy.

Set `TRUSTED_PROXIES` on the Arcane container to your proxy's address, such as `TRUSTED_PROXIES=10.0.0.5`, or to a CIDR range, such as the Docker network that the proxy and Arcane share (`TRUSTED_PROXIES=172.18.0.0/16`). Arcane then reads the real client IP from `X-Forwarded-For` for requests coming from those addresses. Docker's default address pools hand out subnets from `172.17.0.0`–`172.31.0.0` and then `192.168.0.0/16`, and your daemon may be configured differently, so look up the network's actual subnet:
Set `TRUSTED_PROXIES` on the Arcane container to your proxy's address, such as `TRUSTED_PROXIES=10.0.0.5/32`, or to a wider CIDR range, such as the Docker network that the proxy and Arcane share (`TRUSTED_PROXIES=172.18.0.0/16`). Arcane then reads the real client IP from `X-Forwarded-For` for requests coming from those addresses. Docker's default address pools hand out subnets from `172.17.0.0`–`172.31.0.0` and then `192.168.0.0/16`, and your daemon may be configured differently, so look up the network's actual subnet:

```bash
docker network inspect <network> --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
```

`TRUSTED_PROXIES` accepts a comma-separated list of IPs or CIDR ranges. Only requests whose direct peer is in this list have their forwarded headers trusted, so an untrusted client cannot spoof its IP via `X-Forwarded-For`. See the [Environment Variables](/docs/reference/environment-variables) reference for all configuration options.
`TRUSTED_PROXIES` accepts a comma-separated list of CIDR ranges. Write a single address as `/32` for IPv4 or `/128` for IPv6; Arcane logs a warning and ignores entries without a prefix length. Only requests whose direct peer is in this list have their forwarded headers trusted, so an untrusted client cannot spoof its IP via `X-Forwarded-For`. Loopback and private-network addresses are not trusted unless they are in the list. See the [Environment Variables](/docs/reference/environment-variables) reference for all configuration options.

> [!NOTE]
> If you bind Arcane to a loopback address with `LISTEN`, such as `LISTEN=127.0.0.1` for a proxy on the same host, Arcane trusts loopback proxies (`127.0.0.0/8`, `::1/128`) automatically and you don't need `TRUSTED_PROXIES`. This only works with literal loopback IPs, not hostnames such as `localhost`.
Expand Down
Loading
Loading