Commit Graph
83 Commits
Author SHA1 Message Date
jarek 1ad16a7c2a Compose validate - a preflight linter & validator for compose files 2026-08-18 10:05:36 +02:00
jarek da26f7f764 OpenAPI spec at /api/docs with a Scalar viewer, opt-in via FEAT_API_DOCS 2026-08-17 09:50:34 +02:00
jarek ba8670af66 detect newer version tags for pinned images and show them as a badge with release notes 2026-08-17 09:50:34 +02:00
jarek 0a08c94287 optional indentation guides in the compose/YAML editor 2026-08-16 08:15:30 +02:00
jarek 19548772df reject duplicate secret provider name with a 400 2026-08-14 15:59:50 +02:00
jarek 5fef45e003 validate secret provider config before save 2026-08-14 14:01:36 +02:00
jarek 32a86129d0 stack secrets from external providers (1Password, HashiCorp Vault, Infisical and Doppler) 2026-08-14 09:35:36 +02:00
jarek 610e46dc19 read-side backup snapshot endpoints use job polling 2026-08-13 10:20:30 +02:00
jarek cc0d50913a updating a compose file over the API now saves it, not just deploys it 2026-08-13 10:20:29 +02:00
jarek 16ee5d82b9 reopening the MFA setup screen while MFA is enabled no longer wipes the secret and backup codes 2026-08-13 10:20:29 +02:00
jarek c91f38eddf upload a Docker image .tar through the UI (docker load) for air-gapped hosts 2026-08-13 10:20:29 +02:00
jarek f43736d94a stack secrets from external providers (1Password, HashiCorp Vault, Infisical and Doppler) 2026-08-13 10:20:29 +02:00
1ad36a83fb feat: Add pluggable secret providers (1Password, Infisical, HashiCorp Vault) (#1360)
* Add pluggable secret provider foundation

Introduces a provider-agnostic secret backend abstraction so stacks can
pull deploy-time secrets from 1Password, Infisical or HashiCorp Vault.

Providers implement the SecretProvider contract in secretproviders/shared.ts
and advertise which of the two resolution modes they support:

  - reference interpolation: a variable's value is an inline reference in
    the backend's own syntax (e.g. 1Password's op://vault/item/field)
  - bulk pull: every secret under a provider-defined selector, fetched as
    a flat key/value map

Adding a backend means dropping a file in secretproviders/ and registering
it in the index; no caller changes.

Four providers ship here: 1Password service account (references + bulk),
1Password Connect (references), Infisical (bulk) and HashiCorp Vault KV v2
(bulk). Provider config is persisted as an encrypted JSON blob in the new
secret_providers table, mirroring the existing notification_settings
type+config pattern, and stack_sources gains a nullable secret_provider_id.

Decrypted tokens stay in the provider modules for the duration of a call
and are never written to disk or returned to the client.

Co-authored-by: GooRoo <sergey.olendarenko@gmail.com>

* Add secret provider API routes and permissions

CRUD plus two test-connection endpoints under /api/secret-providers. The
unsaved variant validates a config posted from the provider form; the
stored variant tests a persisted provider by id.

Responses only ever carry provider summaries (id, type, name, timestamps).
The decrypted config never leaves the server.

Adds a "secrets" permission resource with view/create/edit/delete actions,
wired through the permission type, the role editor and the seeded roles,
and a secret_provider audit entity type so provider changes are logged.
Config rotations are audited as a boolean rather than a value.

* Resolve provider secrets at stack deploy time

Stacks can bind a secret provider; when one is bound, its secrets are
resolved and merged into the vars handed to docker compose.

Bulk pull is triggered by a selector variable: OP_ENVIRONMENT_ID, kept for
compatibility with the original 1Password integration, or the generic
DOCKHAND_SECRET_SELECTOR for any bulk-capable provider. The selector is
consumed by the provider and stripped before the vars reach the stack.
Values the bound provider recognises as inline references are resolved in
place, and references found only in the stack's .env file are promoted into
the secret set so they are never written back as literals.

Resolution is applied on deploy, on up, on recreate and on service update.
Explicitly configured secrets always win over bulk-pulled ones. A missing
or unsupported provider warns and leaves values untouched rather than
failing the deploy; a provider that errors mid-resolution fails it.

* Add secret provider settings UI and stack binding

A Secrets tab under settings lists configured providers and drives the
create/edit modal, which switches its fields on the selected provider type
and can test a connection before saving.

Both stack modals gain a provider selector so a stack can be bound to a
provider or left unbound. When a provider is bound, the bulk selector
variables are no longer reported as unused compose variables, since they
are consumed by the provider rather than the compose file.

---------

Co-authored-by: GooRoo <sergey.olendarenko@gmail.com>
Co-authored-by: Jarek Krochmalski <jotka@users.noreply.github.com>
2026-08-13 10:08:02 +02:00
jarek 95ee76bf97 backup engine internals - streaming, timeouts, typed snapshot layout, volume keys, route guards 2026-08-09 10:31:28 +02:00
jarek 16451d95d7 improved restic repository operations log (prune, check, repair index etc.) 2026-08-09 10:31:28 +02:00
jarek dab6797847 dashboard pending-update count now matches the containers list 2026-08-09 10:31:28 +02:00
jarek 3859888da6 deleting a stack shows which folders will be removed, with a choice to keep/delete folders 2026-08-09 10:31:28 +02:00
jarek 4e15c2677c dedupe duplicate mount points when recreating a container 2026-08-09 10:31:28 +02:00
jarek d33185d1fa container updates respect the new image's command/entrypoint 2026-08-09 10:31:28 +02:00
jarek 8f47eef1b7 GitLab and Harbor registries no longer report a misleading auth error when browsing 2026-08-09 10:31:27 +02:00
jarek b287cee31f registry browser shows tag size and date for self-hosted registries, loaded on expand 2026-08-09 10:31:27 +02:00
jarek 7bb688197a Google Cloud backup destinations now use a service-account JSON key 2026-08-09 10:31:27 +02:00
jarek 019bea222e S3 backup destinations take an AWS region with a region quick-pick 2026-08-09 10:31:27 +02:00
jarek 3d1b383ad7 snapshots from another Dockhand instance sharing the repo now appear as restorable orphans 2026-08-09 10:31:27 +02:00
jarek 5adac5e19e a stack restored to new locations always keeps its compose file and stays internal 2026-08-09 10:31:27 +02:00
jarek bd06b340c5 direct remote environments - remote stacks dir configurable, for putting the whole stack onto the remote 2026-08-09 10:31:27 +02:00
jarek 86ef3f743b configurable default homepage 2026-08-09 10:31:27 +02:00
jarek 6a6e82a481 reach own docker daemon over tcp on socket-proxy setups; re-run host detection when an environment is added or edited; keep scanner on the host socket 2026-07-31 10:10:56 +02:00
jarek 0a9d4ad10f validate git repo urls and refs, require a secret for webhook triggers, tidy internal endpoint comments 2026-07-31 10:10:56 +02:00
jarek c18ee21a66 git stack source badge with forge-aware icons and commit hash 2026-07-31 10:10:56 +02:00
jarek e3c07f32da backup engine fixes: shared-repo unlock, non-root uid reads, lock release, local-path repo, backblaze key id 2026-07-31 10:10:55 +02:00
jarek e700b5b6aa restore reproduces the stack as an internal stack with its secrets 2026-07-31 10:10:55 +02:00
jarek 64b6dcd744 1.0.38 2026-07-25 08:41:01 +02:00
jarek c718ac9a84 1.0.37 2026-07-11 15:31:52 +02:00
jarek 685132ff89 1.0.36 2026-06-27 15:15:54 +02:00
jarek ce12d7ae9f 1.0.35 2026-06-19 08:21:22 +02:00
jarek efb634701c 1.0.34 2026-06-17 08:21:38 +02:00
Pascal GUINETandClaude Opus 4.6 0eaf52fa66 SYS-11240 Translate all code comments from French to English
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-16 09:08:46 +02:00
Pascal GUINETandClaude Opus 4.6 eb5cf32d68 Add Harbor fallback for catalog and search endpoints
Harbor denies access to the V2 _catalog endpoint for robot accounts
(scope registry:catalog:* returns an empty JWT). This adds automatic
Harbor detection and falls back to the native Harbor project API
(/api/v2.0/projects/{name}/repositories) for both catalog listing
and image search.

- Detect Harbor via WWW-Authenticate header + /api/v2.0/ping (cached 5min)
- List repositories through Harbor project API with pagination
- Search repositories using Harbor's q=name=~ filter
- Transparent fallback: no configuration change required

Fixes #360

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-16 09:08:46 +02:00
jarek 83c3a5ea09 1.0.33 2026-06-15 14:56:51 +02:00
jarek 3cbcfa3cdb 1.0.32 2026-06-06 16:18:05 +02:00
jarek c8b3acc07e 1.0.30 2026-05-30 08:42:21 +02:00
jarek e7100f8926 1.0.29 2026-05-17 08:02:31 +02:00
jarek 002d969a5d 1.0.28 2026-05-09 09:55:18 +02:00
jarek 7e3797cbfe 1.0.27 2026-04-26 08:01:32 +02:00
Ivan Kara ccfda4c054 Adjust uploaded files permission 2026-04-19 18:56:01 +02:00
Dennis Braun 7c123833b5 fix: avoid duplicate volume binds during recreate 2026-04-19 16:26:56 +02:00
YewFence a1def17750 chore: delete the unnecessary functions called 2026-04-19 16:22:01 +02:00
YewFence 94657735fb feat: mirror Dockhand's ExtraHosts into scanner and self-update sidecar containers
Add `extraHosts` option to `runContainer` and `runContainerWithStreaming` so arbitrary `HostConfig.ExtraHosts` entries can be passed when spawning containers.

Expose `getOwnExtraHosts()` from `host-path.ts` and forward the cached entries into scanner and self-updater containers, ensuring custom host aliases (e.g. internal registry hostnames) are available inside those sidecars without additional user configuration.
2026-04-19 16:22:01 +02:00
GiulioSavini 8671dfaf32 fix: allow 6-field cron expressions with seconds
The cron editor rejected sub-minute expressions like `*/30 * * * * *`
because validation required exactly 5 fields. Now accepts both 5-field
(standard) and 6-field (with seconds) cron expressions.

Also fixes schedule type auto-detection to correctly fall back to
'custom' for 6-field expressions instead of misinterpreting field
positions.

Fixes #819
2026-04-19 16:01:50 +02:00