Registry Connections
Registry connections link BRIDGEPORT to your container registries, enabling update detection, tag browsing, digest-based comparison, and automated deployments.
Quick Start
Section titled “Quick Start”Connect BRIDGEPORT to your container registry in under a minute:
- Go to Orchestration > Registries in the sidebar.
- Click Add Registry.
- Select your registry type, enter the URL and credentials.
- Click Test Connection to verify.
- Click Save.
BRIDGEPORT will start checking for image updates every 30 minutes automatically.
Supported Registry Types
Section titled “Supported Registry Types”BRIDGEPORT supports three registry types. The “Generic” type covers any Docker Registry V2-compatible service, which includes most private registries.
| Type | Description | Auth Method | Use For |
|---|---|---|---|
| DigitalOcean | DigitalOcean Container Registry | API token (Bearer) | DO-hosted registries |
| Docker Hub | Docker Hub public and private repos | Username/password or access token | Public images, Docker Hub private repos |
| Generic | Any Docker Registry V2-compatible API | Username/password (Basic) | Harbor, GitLab Container Registry, GitHub Container Registry (GHCR), AWS ECR, self-hosted registries |
Generic Registry Compatibility
Section titled “Generic Registry Compatibility”The Generic client works with any registry that implements the OCI Distribution Spec. Tested registries include:
- Harbor —
https://harbor.example.com - GitLab Container Registry —
https://registry.gitlab.com - GitHub Container Registry (GHCR) —
https://ghcr.io - AWS ECR —
https://<account>.dkr.ecr.<region>.amazonaws.com(useAWSas username, ECR auth token as password) - Self-hosted Docker Registry —
https://registry.example.com
How It Works
Section titled “How It Works”BRIDGEPORT’s registry system connects your container registries to the Container Images system. Registries are checked on a schedule, and when new tags are detected, the information flows through to linked images and services.
sequenceDiagram
participant Sched as Scheduler
participant BP as BRIDGEPORT
participant Reg as Container Registry
participant DB as Database
Sched->>BP: Time to check (every N minutes)
BP->>DB: Fetch images with registryConnectionId
BP->>DB: Decrypt registry credentials
loop For each image
BP->>Reg: List tags for repository
Reg-->>BP: Tags with digests + timestamps
BP->>BP: detectUpdate()<br/>Compare current vs latest
BP->>DB: Update latestTag, latestDigest, updateAvailable
alt autoUpdate enabled AND update found
BP->>BP: Build deployment plan
BP->>BP: Execute plan (deploy to all services)
end
end
Adding a Registry Connection
Section titled “Adding a Registry Connection”Via the UI
Section titled “Via the UI”- Navigate to Orchestration > Registries.
- Click Add Registry.
- Fill in the form:
| Field | Required | Description |
|---|---|---|
| Name | Yes | Display name (e.g., “Production DO Registry”). Must be unique per environment. |
| Type | Yes | digitalocean, dockerhub, or generic |
| Registry URL | Yes | The registry endpoint (see Authentication for examples) |
| Repository Prefix | No | Narrows repository listing (e.g., my-registry for DO) |
| Credentials | Depends | Token, or username/password — varies by type |
| Default | No | Mark as default registry for this environment |
| Refresh Interval | No | Minutes between update checks (default: 30, range: 5-1440) |
| Auto-Link Pattern | No | Glob pattern for auto-linking discovered images |
- Click Test Connection to verify credentials and connectivity.
- Click Save.
Via the API
Section titled “Via the API”POST /api/environments/:envId/registriesAuthorization: Bearer <token>Content-Type: application/json
{ "name": "Production DO Registry", "type": "digitalocean", "registryUrl": "https://api.digitalocean.com/v2/registry", "repositoryPrefix": "my-registry", "token": "dop_v1_abc123...", "isDefault": true, "refreshIntervalMinutes": 30, "autoLinkPattern": "myapp-*"}Response (200):
{ "registry": { "id": "clxyz...", "name": "Production DO Registry", "type": "digitalocean", "registryUrl": "https://api.digitalocean.com/v2/registry", "repositoryPrefix": "my-registry", "hasToken": true, "hasPassword": false, "isDefault": true, "refreshIntervalMinutes": 30, "autoLinkPattern": "myapp-*" }}Authentication
Section titled “Authentication”Each registry type accepts different credential formats:
DigitalOcean
Section titled “DigitalOcean”Registry URL: https://api.digitalocean.com/v2/registryToken: dop_v1_abc123... (DO personal access token with registry read scope)Prefix: my-registry (your registry name)The DO client uses two APIs: the DigitalOcean management API for tag listing, and the Docker Registry V2 API (registry.digitalocean.com) as a fallback for manifest digests.
Docker Hub
Section titled “Docker Hub”Registry URL: https://hub.docker.comUsername: myuserPassword: dckr_pat_abc123... (Docker Hub access token recommended over password)For public repositories, credentials are optional but recommended to avoid rate limits. For private repositories, credentials are required.
Generic (V2)
Section titled “Generic (V2)”Registry URL: https://registry.example.com (the registry's base URL)Username: myuserPassword: mypasswordThe Generic client authenticates via HTTP Basic auth and communicates using the standard Docker Registry V2 API (/v2/ endpoints).
GHCR example:
Registry URL: https://ghcr.ioUsername: USERNAMEPassword: ghp_abc123... (GitHub personal access token with read:packages scope)GitLab example:
Registry URL: https://registry.gitlab.comUsername: gitlab-ci-token (or your username for personal tokens)Password: glpat-abc123... (GitLab personal access token with read_registry scope)Server-Side Registry Login
Section titled “Server-Side Registry Login”Stored credentials are also used at deploy time to authenticate the target server against the registry, so docker pull and docker compose pull succeed for private images without any manual docker login on the box.
How it works:
- SSH-mode servers. Before the first pull from a given registry, BRIDGEPORT runs
docker loginover SSH. The password is written to a 0600 temp file and piped into--password-stdin— it is never passed as a CLI argument and never appears inpsor shell history. The temp file is removed in afinally, even if login fails. The resulting auth lives in the SSH user’s~/.docker/config.jsonon the server and is reused for subsequent pulls. - Socket-mode servers. When BRIDGEPORT talks directly to a local Docker daemon, no persistent state is written. Credentials are passed in-process to dockerode’s
pull()via theauthconfigoption for each pull.
Login state is tracked per (server, registry) in the ServerRegistryLogin table. BRIDGEPORT skips the login step when an existing row is at least as fresh as the registry’s updatedAt. Editing any auth-relevant field on a registry connection (token, username, password, registryUrl, type) deletes all of that registry’s login rows, forcing a re-login on the next deploy with the new credentials. Metadata-only edits (name, auto-link pattern, refresh interval, default flag) leave the cache intact.
DigitalOcean uses the API token as both the username and the password for docker login registry.digitalocean.com. Docker Hub omits the host argument so docker login uses its index.docker.io default. Generic registries use the registry hostname (scheme and any trailing /v2 are stripped).
If login fails — for example, a revoked token — the deploy fails fast with docker login failed: <reason> instead of falling through to a confusing “image not found” later.
Refresh Intervals
Section titled “Refresh Intervals”Each registry connection has a configurable refresh interval that controls how often BRIDGEPORT checks for new tags.
| Setting | Range | Default |
|---|---|---|
refreshIntervalMinutes | 5 — 1440 (24 hours) | 30 minutes |
The global scheduler runs at the interval configured by SCHEDULER_UPDATE_CHECK_INTERVAL (default: 1800 seconds / 30 minutes). During each run, it checks all container images whose linked registry is due for a refresh.
Force Check
Section titled “Force Check”You can trigger an immediate update check for all images linked to a registry:
POST /api/registries/:id/check-updatesAuthorization: Bearer <token>Returns results for each checked service:
{ "results": [ { "serviceId": "svc1", "name": "app-api", "hasUpdate": true, "latestTag": "v2.4.0" }, { "serviceId": "svc2", "name": "app-worker", "hasUpdate": false } ], "summary": { "checked": 2, "withUpdates": 1, "errors": 0 }}Auto-Link Patterns
Section titled “Auto-Link Patterns”An auto-link pattern is a string that BRIDGEPORT matches against image names during container discovery. When a new container is discovered and its image name matches the pattern, BRIDGEPORT creates a ContainerImage linked to this registry automatically.
Examples:
| Pattern | Matches |
|---|---|
myapp-* | myapp-backend, myapp-frontend, myapp-worker |
registry.example.com/* | Any image from registry.example.com |
| (empty) | No auto-linking (manual linking only) |
Set the pattern when creating or editing a registry:
PATCH /api/registries/:idAuthorization: Bearer <token>Content-Type: application/json
{ "autoLinkPattern": "myapp-*"}Tag Browser
Section titled “Tag Browser”Once a container image is linked to a registry, you can browse its available tags:
From the Container Image
Section titled “From the Container Image”GET /api/container-images/:id/tagsAuthorization: Bearer <token>From the Registry
Section titled “From the Registry”List all repositories in the registry:
GET /api/registries/:id/repositoriesAuthorization: Bearer <token>List tags for a specific repository:
GET /api/registries/:id/repositories/:repo/tagsAuthorization: Bearer <token>Each tag includes:
| Field | Description |
|---|---|
tag | Tag name (e.g., v2.4.0, latest) |
digest | Manifest digest (e.g., sha256:abc123...) |
size | Compressed image size in bytes |
updatedAt | When the tag was last updated |
Update Detection
Section titled “Update Detection”BRIDGEPORT uses a digest-based comparison system to detect updates accurately, even for rolling tags like latest.
Version Tags (e.g., v2.3.1 to v2.4.0)
Section titled “Version Tags (e.g., v2.3.1 to v2.4.0)”Tags are grouped into “families” based on their suffix:
v2.3.1andv2.4.0are in the same bare-version family2.9.0-alpineand2.10.0-alpineare in the-alpinefamilylatestandstableare each in their own family
Only tags in the same family as the current tag are compared. If a newer tag exists with a different digest, an update is reported.
Rolling Tags (e.g., latest)
Section titled “Rolling Tags (e.g., latest)”For rolling tags where the tag name never changes, BRIDGEPORT compares the manifest digest from the registry against the deployedDigest recorded after the last deployment. If the digests differ, the image was updated.
flowchart TD
A[Fetch tags from registry] --> B{Tag name changed?}
B -->|Yes: v2.3.1 vs v2.4.0| C[Compare digests if available]
B -->|No: latest vs latest| D{Registry returned digest?}
C --> E{Digests differ?}
E -->|Yes| F[Update available]
E -->|No| G[No update]
D -->|Yes| H{Compare with deployedDigest}
D -->|No| I[Cannot determine -- no false positive]
H -->|Differ| F
H -->|Same| G
F --> J{Companion tag?}
J -->|Digest matches another tag| K["Display: 20260225-a1b2c3d<br/>(instead of 'latest')"]
J -->|No match| L["Display: latest"]
Digest-Based Comparison Details
Section titled “Digest-Based Comparison Details”| Scenario | Detection Method |
|---|---|
New version tag (e.g., v2.3.1 to v2.4.0) | Tag name + digest comparison |
Rolling tag with digest (e.g., latest) | Digest comparison against deployedDigest |
| Rolling tag without digest | No detection (avoids false positives) |
| Same tag, same digest | No update |
Registry Client Differences
Section titled “Registry Client Differences”| Feature | DigitalOcean | Docker Hub | Generic V2 |
|---|---|---|---|
| Tag listing | DO management API | Hub API | /v2/{repo}/tags/list + manifest HEADs |
| Digest source | API field (+ V2 fallback) | API field | Docker-Content-Digest header |
| Real timestamps | Yes | Yes | No (set to current time) |
| Image sizes | Yes | Yes | No (always 0) |
| Auth method | Bearer token | Token exchange / Basic | Basic auth |
Configuration Options
Section titled “Configuration Options”Registry Connection Fields
Section titled “Registry Connection Fields”| Field | Type | Default | Description |
|---|---|---|---|
name | string | — | Display name (unique per environment) |
type | enum | — | digitalocean, dockerhub, or generic |
registryUrl | string | — | Registry API endpoint |
repositoryPrefix | string | null | Prefix for narrowing repository listing |
token | string | null | API token (encrypted at rest) |
username | string | null | Username for basic auth |
password | string | null | Password for basic auth (encrypted at rest) |
isDefault | boolean | false | Default registry for the environment |
refreshIntervalMinutes | integer | 30 | How often to check for updates (5-1440) |
autoLinkPattern | string | null | Pattern for auto-linking discovered images |
Related System Settings
Section titled “Related System Settings”| Setting | Location | Default | Description |
|---|---|---|---|
SCHEDULER_UPDATE_CHECK_INTERVAL | Env var | 1800s | Global scheduler interval for registry checks |
registryMaxTags | Admin > System | 50 | Max tags to fetch per repo (Generic registries) |
Troubleshooting
Section titled “Troubleshooting”“Connection test failed”
Verify the registry URL, credentials, and that the BRIDGEPORT server can reach the registry. For Generic registries, ensure the URL includes the scheme (e.g., https://registry.example.com). The test calls the /v2/ endpoint.
“Registry API error: 401”
Credentials are invalid or expired. For Docker Hub, ensure your access token has not expired. For GHCR, ensure the personal access token has the read:packages scope.
“Registry API error: 403”
The credentials are valid but lack permissions. For DO registries, the API token needs registry read access. For GHCR, the token needs the read:packages scope for the target repository.
“Cannot delete registry connection with N container image(s) attached”
Container images must be unlinked or deleted before the registry can be removed. Edit each container image and either set registryConnectionId to null or delete the image.
Tags show “0 bytes” and no real timestamps This is normal for Generic V2 registries. The Docker Registry V2 API does not provide size or timestamp information in tag listings. BRIDGEPORT fetches digests via manifest HEAD requests but cannot retrieve sizes or timestamps.
Update check finds updates but they are false positives This can happen if the deployed digest was not recorded (e.g., the service was deployed before the digest tracking feature was added). Deploy the current tag once to store the digest, which will clear the false positive.
“No registry connection configured for this image”
The container image has no registryConnectionId. Edit the container image and select a registry connection.
Related
Section titled “Related”- Container Images — Central image management, tag history, auto-update
- Deployment Plans — Orchestrated multi-service deployments
- Webhooks — CI/CD integration for push-based deployments
- Configuration Reference —
SCHEDULER_UPDATE_CHECK_INTERVALand other env vars