ATCR - ATProto Container Registry#
https://atcr.io#
An OCI-compliant container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
What is ATCR?#
ATCR integrates container registries with the AT Protocol ecosystem. Container image manifests are stored as ATProto records in your Personal Data Server (PDS), while layers are stored in S3-compatible storage.
Image names use your ATProto identity:
atcr.io/alice.bsky.social/myapp:latest
atcr.io/did:plc:xyz123/myapp:latest
Architecture#
Three components:
-
AppView - Registry API + web UI
- Serves OCI Distribution API (Docker push/pull)
- Resolves handles/DIDs to PDS endpoints
- Routes manifests to user's PDS, blobs to hold services
- Web interface for browsing/search
-
Hold Service - Storage service with embedded PDS (optional BYOS)
- Each hold has a full ATProto PDS for access control (captain + crew records)
- Identified by did:web (e.g.,
did:web:hold01.atcr.io) - Generates presigned URLs for S3/Storj/Minio/etc.
- Users can deploy their own storage and control access via crew membership
-
Credential Helper - Client authentication
- ATProto OAuth (DPoP handled transparently)
- Automatic authentication on first push/pull
Storage model:
- Manifests → ATProto records in user's PDS (small JSON, includes
holdDidreference) - Blobs → Hold services via XRPC multipart upload (large binaries, stored in S3/etc.)
- AppView uses service tokens to communicate with holds on behalf of users
Features#
- ✅ OCI-compliant - Works with Docker, containerd, podman
- ✅ Decentralized - You own your manifest data via your PDS
- ✅ ATProto OAuth - Secure authentication (DPoP-compliant)
- ✅ BYOS - Deploy your own storage service
- ✅ Web UI - Browse, search, star repositories
- ✅ Multi-backend - S3, Storj, Minio, Azure, GCS, filesystem
Quick Start#
Using the Registry#
1. Install credential helper:
curl -fsSL https://atcr.io/install.sh | bash
2. Configure Docker (add to ~/.docker/config.json):
{
"credHelpers": {
"atcr.io": "atcr"
}
}
3. Push/pull images:
docker tag myapp:latest atcr.io/yourhandle/myapp:latest
docker push atcr.io/yourhandle/myapp:latest # Authenticates automatically
docker pull atcr.io/yourhandle/myapp:latest
See INSTALLATION.md for detailed installation instructions.
Running Your Own AppView#
Using Docker Compose:
cp .env.appview.example .env.appview
# Edit .env.appview with your configuration
docker-compose up -d
Local development:
# Build
go build -o bin/atcr-appview ./cmd/appview
go build -o bin/atcr-hold ./cmd/hold
# Configure
cp .env.appview.example .env.appview
# Edit .env.appview - set ATCR_DEFAULT_HOLD
source .env.appview
# Run
./bin/atcr-appview serve
See deploy/README.md for production deployment.
Development#
Building from Source#
# Build all binaries
go build -o bin/atcr-appview ./cmd/appview
go build -o bin/atcr-hold ./cmd/hold
go build -o bin/docker-credential-atcr ./cmd/credential-helper
# Run tests
go test ./...
go test -race ./...
Project Structure#
cmd/
├── appview/ # Registry server + web UI
├── hold/ # Storage service (BYOS)
└── credential-helper/ # Docker credential helper
pkg/
├── appview/
│ ├── db/ # SQLite database (migrations, queries, stores)
│ ├── handlers/ # HTTP handlers (home, repo, search, auth, settings)
│ ├── jetstream/ # ATProto Jetstream consumer
│ ├── middleware/ # Auth & registry middleware
│ ├── storage/ # Storage routing (hold cache, blob proxy, repository)
│ ├── static/ # Static assets (JS, CSS, install scripts)
│ └── templates/ # HTML templates
├── atproto/ # ATProto client, records, manifest/tag stores
├── auth/
│ ├── oauth/ # OAuth client, server, refresher, storage
│ ├── token/ # JWT issuer, validator, claims
│ └── atproto/ # Session validation
└── hold/ # Hold service (authorization, storage, multipart, S3)
License#
MIT
Contributing#
Contributions welcome! Please open an issue or PR.