mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-28 12:49:03 +00:00
6275adc6b3
* feat(registries): add stateless test endpoint, ECR caching, URL and host hardening Adds a POST /api/registries/test endpoint so credentials can be verified before being persisted. Caches ECR authorization tokens in memory until their AWS-reported expiry (minus a safety margin) instead of fetching on every compose invocation. Normalizes registry URLs on save so the stored values match the keys Docker expects in ~/.docker/config.json, fixes a bidirectional host-match bug in getAuthForRegistry that could cross-match overlapping hostnames, and surfaces per-registry decryption failures as warnings in the deploy log stream instead of swallowing them. Also strips the Authorization header on cross-host redirects in the test probe, rejects non-http(s) schemes on save, and validates the shape of returned ECR authorization tokens before use. * refactor(registries): align UI with design system and add in-form test button Swaps the registry type dropdown from shadcn Select to the project's Combobox, applies the canonical card bevel and top-border hover styling to the form container and each registry row, restyles the delete button to the ghost + muted destructive pattern, uses strokeWidth 1.5 on every Lucide icon, and routes all toast errors through the standard defensive chain. Adds a Test connection button inside the form so credentials can be verified before saving. * test(registries): cover RegistryService and deploy warnings surface Adds unit coverage for URL normalization, the encrypt/decrypt round trip through create and resolveDockerConfig, exact-host matching in getAuthForRegistry, resolveDockerConfig warnings on decryption failure, ECR token cache hit/miss and invalidation on update, the stateless testWithCredentials path for 200, 401 with and without a challenge, network errors, and ECR success and failure including malformed tokens. Extends the ComposeService tests to verify that warnings from resolveDockerConfig reach the deploy log stream. * docs(registries): document test-before-save flow and troubleshooting Describes the in-form Test connection button, the two-point testing flow from the registries list, the cached ECR token behavior during deploys, the per-registry warning Sencho emits when a stored secret cannot be decrypted, and adds a Troubleshooting section covering common 401 causes, ECR token handling, warning interpretation, and per-node credential scoping.
170 lines
9.2 KiB
Plaintext
170 lines
9.2 KiB
Plaintext
---
|
|
title: Private Registries
|
|
description: Store credentials for private Docker registries so Sencho can automatically authenticate during deploy, pull, and image update checks.
|
|
---
|
|
|
|
<Note>
|
|
Private Registry Management requires a Sencho **Admiral** license. Skipper and Community Edition do not include this feature.
|
|
</Note>
|
|
|
|
Sencho can store credentials for your private Docker registries and inject them automatically whenever it runs `docker compose pull` or `docker compose up`. This means your stacks can reference private images without needing to manually `docker login` on the host.
|
|
|
|
## Supported registry types
|
|
|
|
| Type | Description | Credentials |
|
|
|------|-------------|-------------|
|
|
| **Docker Hub** | Private Docker Hub organizations and repositories | Username + access token |
|
|
| **GHCR** | GitHub Container Registry (`ghcr.io`) | GitHub username + personal access token (PAT) |
|
|
| **AWS ECR** | Amazon Elastic Container Registry | AWS Access Key ID + Secret Access Key |
|
|
| **Custom** | Any self-hosted Docker V2 registry | Username + password or token |
|
|
|
|
## Adding a registry
|
|
|
|
1. Open **Settings Hub** and navigate to the **Registries** tab (visible to Admiral admins only).
|
|
2. Click **Add Registry**.
|
|
3. Select the registry type. When you switch types, the URL field auto-fills with the standard endpoint for Docker Hub and GHCR.
|
|
4. Enter a descriptive name, the registry URL, and your credentials.
|
|
5. For **ECR** registries, also provide the AWS region (e.g., `us-east-1`).
|
|
6. Click **Test connection** to verify the credentials work before saving. Sencho talks to the registry's `/v2/` endpoint (or the AWS STS API for ECR) and reports success or the specific failure reason.
|
|
7. Click **Add** to store the credentials.
|
|
|
|
<Frame>
|
|
<img src="/images/private-registries/registries-with-entry.png" alt="Private Registries management view in Settings Hub showing a configured Docker Hub registry" />
|
|
</Frame>
|
|
|
|
<Frame>
|
|
<img src="/images/private-registries/registries-add-form.png" alt="Add Registry form with type selector, credentials, and URL fields" />
|
|
</Frame>
|
|
|
|
## Managing registries
|
|
|
|
Each configured registry appears as a card showing:
|
|
|
|
- **Name** and **type badge** (e.g., Docker Hub, GHCR, AWS ECR, Custom)
|
|
- **Registry URL** (monospaced)
|
|
- **Username**
|
|
- **Secret status** (whether a secret is stored)
|
|
- **AWS Region**, if the registry is an ECR type
|
|
- **Created date**
|
|
|
|
Each card has three action buttons:
|
|
|
|
- **Test connection** (checkmark icon) to verify credentials
|
|
- **Edit** (pencil icon) to modify the registry name, URL, credentials, or type
|
|
- **Delete** (trash icon) to remove the registry after confirmation
|
|
|
|
When editing a registry, you can leave the secret field blank to keep the existing stored secret. Only fill it in if you want to replace it.
|
|
|
|
### Testing connectivity
|
|
|
|
You can test credentials at two points:
|
|
|
|
- **Before saving**, using the **Test connection** button inside the add or edit form. This is useful for confirming a token or password works without committing it to storage first.
|
|
- **After saving**, by clicking the checkmark icon on any registry card. This re-decrypts the stored secret and re-runs the same probe.
|
|
|
|
For standard registries, Sencho authenticates against `/v2/` using Basic auth and falls back to the registry's token endpoint if it receives a `401` with a `WWW-Authenticate` challenge. For ECR registries, the test verifies that the AWS credentials can successfully obtain an authorization token.
|
|
|
|
## How credentials are applied
|
|
|
|
### Deploy and pull operations
|
|
|
|
When you deploy or update a stack, Sencho:
|
|
|
|
1. Resolves credentials for all configured registries.
|
|
2. For ECR registries, reuses a cached authorization token when one is still valid; otherwise fetches a fresh token from AWS. Cached tokens are refreshed a few minutes before AWS reports them as expired, so deploys never fail on a borderline token.
|
|
3. Writes a temporary Docker config file with all registry auth entries.
|
|
4. Sets the `DOCKER_CONFIG` environment variable so `docker compose` uses the temporary config.
|
|
5. Runs the compose operation (pull and/or up).
|
|
6. Cleans up the temporary config file immediately after.
|
|
|
|
This approach ensures credentials are never persisted on disk beyond the duration of the operation.
|
|
|
|
If a stored secret cannot be decrypted at deploy time (for example, because the encryption key file was replaced), Sencho skips that one registry, records a warning in the deploy log stream prefixed with `[Sencho] Warning:`, and continues. This lets public-image deploys succeed even when one private registry is misconfigured, while making the failure visible so you can re-save the credentials.
|
|
|
|
### Image update checks
|
|
|
|
Sencho's background image update checker also uses stored registry credentials. When checking for newer image versions, it passes your credentials to the registry's authentication endpoint so it can compare local and remote digests for private images.
|
|
|
|
## ECR setup
|
|
|
|
AWS ECR uses short-lived authentication tokens (valid for 12 hours) derived from your IAM credentials. Sencho handles this automatically:
|
|
|
|
1. Store your **AWS Access Key ID** and **Secret Access Key** as the username and secret.
|
|
2. Specify the **AWS Region** where your ECR registry lives.
|
|
3. On every deploy or pull, Sencho reuses a cached authorization token when one is still valid, or calls the AWS `GetAuthorizationToken` API to obtain a fresh one.
|
|
|
|
<Warning>
|
|
Use an IAM user or role with only the `ecr:GetAuthorizationToken` and `ecr:BatchGetImage` permissions. Avoid using root account credentials.
|
|
</Warning>
|
|
|
|
### IAM policy example
|
|
|
|
```json
|
|
{
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Action": [
|
|
"ecr:GetAuthorizationToken",
|
|
"ecr:BatchGetImage",
|
|
"ecr:GetDownloadUrlForLayer",
|
|
"ecr:BatchCheckLayerAvailability"
|
|
],
|
|
"Resource": "*"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Registry URL reference
|
|
|
|
| Registry | URL to use |
|
|
|----------|-----------|
|
|
| Docker Hub | `https://index.docker.io/v1/` |
|
|
| GHCR | `ghcr.io` |
|
|
| AWS ECR | `{account_id}.dkr.ecr.{region}.amazonaws.com` |
|
|
| Self-hosted | Your registry hostname, e.g. `registry.example.com` |
|
|
|
|
## Security
|
|
|
|
- **Encrypted storage** - Registry secrets are encrypted at rest, using the same encryption layer as remote node tokens and SSO secrets.
|
|
- **No persistent Docker login** - Credentials are written to a temporary file for the duration of each operation and immediately deleted afterward.
|
|
- **Secrets never exposed** - The API never returns decrypted secrets. The UI shows only whether a secret is stored.
|
|
- **Audit trail** - Registry create, update, and delete operations are recorded in the [Audit Log](/features/audit-log).
|
|
- **Admin-only access** - Only admin users with an Admiral license can manage registry credentials.
|
|
|
|
## Multi-node behavior
|
|
|
|
Registry credentials are stored per Sencho instance. When managing remote nodes, each node runs its own Sencho instance with its own registry credentials. Configure private registries on each node that needs access to private images.
|
|
|
|
## Troubleshooting
|
|
|
|
### Pull fails with a 401 even though the credentials saved successfully
|
|
|
|
The most common cause is a URL format mismatch. Use the forms in the **Registry URL reference** table above, and note that the URL is case-sensitive for most registries. For Docker Hub, any URL you enter is stored as the canonical `https://index.docker.io/v1/` because that is the key the Docker CLI expects.
|
|
|
|
If the URL is correct, re-open the registry, re-enter the secret, and click **Test connection** inside the form. Some providers rotate tokens silently, and the card view cannot tell you that the stored token was revoked without attempting a live probe.
|
|
|
|
### An ECR registry works for a while and then stops pulling
|
|
|
|
AWS ECR authorization tokens are valid for 12 hours. Sencho caches the token in memory and refreshes it automatically a few minutes before the AWS-reported expiry, so no action is needed on your part.
|
|
|
|
If pulls still fail, confirm the IAM user still has the `ecr:GetAuthorizationToken` permission and that the AWS Access Key ID has not been rotated. Click **Test connection** on the registry card to force a fresh token fetch.
|
|
|
|
### The deploy log shows `[Sencho] Warning: Registry "X" credentials unavailable`
|
|
|
|
Sencho could not decrypt the stored secret for that registry. The deploy continues without that registry's credentials, which is fine if the stack pulls only public images.
|
|
|
|
To fix the registry, open it in the Registries tab, re-enter the secret, and save. If the same warning appears for every registry, the encryption key file at your data directory has been replaced or lost, and every stored secret needs to be re-entered.
|
|
|
|
### Test connection says it failed, but deploys still pull images successfully
|
|
|
|
Some registries (notably certain self-hosted mirrors and proxy caches) restrict access to the `/v2/` discovery endpoint while still allowing pulls. Sencho uses `/v2/` as the probe target, so a failure there does not always indicate broken credentials.
|
|
|
|
If your deploys succeed, you can safely ignore the test result. The test is a best-effort check, not a gate on saving.
|
|
|
|
### Credentials work on the local node but not on a remote node
|
|
|
|
Registry credentials are stored per Sencho instance, not shared across nodes. Open the remote node from the node switcher and configure the same registry on that node's Registries tab.
|