A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fixup atcr-appview readme

evan.jarrett.net d7e9580a 9eb69e2e

verified
+280 -63
+280 -63
docs/appview.md
··· 1 1 # ATCR AppView 2 2 3 - The **AppView** is the OCI-compliant registry server for ATCR (ATProto Container Registry). It provides the Docker Registry HTTP API V2 and a web interface for browsing container images. 3 + > The registry frontend component of ATCR (ATProto Container Registry) 4 4 5 - ## What is AppView? 5 + ## Overview 6 6 7 - AppView serves as the central registry server that: 7 + **AppView** is the frontend server component of ATCR. It serves as the OCI-compliant registry API endpoint and web interface that Docker clients interact with when pushing and pulling container images. 8 8 9 - - **Serves OCI Distribution API** - Compatible with Docker, containerd, podman, and other OCI clients 10 - - **Resolves ATProto identities** - Converts handles and DIDs to PDS endpoints 11 - - **Routes manifests** - Stores container manifests as ATProto records in users' Personal Data Servers 12 - - **Routes blobs** - Proxies blob operations to hold services (S3-compatible storage) 13 - - **Provides web UI** - Browse, search, and star repositories 9 + ### What AppView Does 10 + 11 + AppView is the orchestration layer that: 12 + 13 + - **Serves the OCI Distribution API V2** - Compatible with Docker, containerd, podman, and all OCI clients 14 + - **Resolves ATProto identities** - Converts handles (`alice.bsky.social`) and DIDs (`did:plc:xyz123`) to PDS endpoints 15 + - **Routes manifests** - Stores container image manifests as ATProto records in users' Personal Data Servers 16 + - **Routes blobs** - Proxies blob (layer) operations to hold services for S3-compatible storage 17 + - **Provides web UI** - Browse repositories, search images, view tags, track pull counts, manage stars 18 + - **Manages authentication** - Validates OAuth tokens and issues registry JWTs to Docker clients 19 + 20 + ### The ATCR Ecosystem 14 21 15 - ## Image Format 22 + AppView is the **frontend** of a multi-component architecture: 16 23 17 - Container images use ATProto identities: 24 + 1. **AppView** (this component) - Registry API + web interface 25 + 2. **[Hold Service](https://atcr.io/r/evan.jarrett.net/atcr-hold)** - Storage backend with embedded PDS for blob storage 26 + 3. **Credential Helper** - Client-side tool for ATProto OAuth authentication 18 27 28 + **Data flow:** 19 29 ``` 20 - atcr.io/alice.bsky.social/myapp:latest 21 - atcr.io/did:plc:xyz123/myapp:latest 30 + Docker Client → AppView (resolves identity) → User's PDS (stores manifest) 31 + 32 + Hold Service (stores blobs in S3/Storj/etc.) 22 33 ``` 23 34 24 - ## Using ATCR 35 + Manifests (small JSON metadata) live in users' ATProto PDS, while blobs (large binary layers) live in hold services. AppView orchestrates the routing between these components. 25 36 26 - ### Push Images 37 + ## When to Run Your Own AppView 38 + 39 + Most users can simply use **https://atcr.io** - you don't need to run your own AppView. 40 + 41 + **Run your own AppView if you want to:** 42 + - Host a private/organizational container registry with ATProto authentication 43 + - Run a public registry for a specific community 44 + - Customize the registry UI or policies 45 + - Maintain full control over registry infrastructure 46 + 47 + **Prerequisites:** 48 + - A running [Hold service](https://atcr.io/r/evan.jarrett.net/atcr-hold) (required for blob storage) 49 + - (Optional) Domain name with SSL/TLS certificates for production 50 + - (Optional) Access to ATProto Jetstream for real-time indexing 51 + 52 + ## Quick Start 53 + 54 + ### Using Docker Compose 55 + 56 + The fastest way to run AppView alongside a Hold service: 27 57 28 58 ```bash 29 - # Install credential helper 30 - curl -fsSL https://atcr.io/install.sh | bash 59 + # Clone repository 60 + git clone https://tangled.org/@evan.jarrett.net/at-container-registry 61 + cd atcr 62 + 63 + # Copy and configure environment 64 + cp .env.appview.example .env.appview 65 + # Edit .env.appview - set ATCR_DEFAULT_HOLD_DID (see Configuration below) 31 66 32 - # Configure Docker (add to ~/.docker/config.json) 33 - { 34 - "credHelpers": { 35 - "atcr.io": "atcr" 36 - } 37 - } 67 + # Start services 68 + docker-compose up -d 38 69 39 - # Push images (authenticates automatically) 40 - docker tag myapp:latest atcr.io/yourhandle/myapp:latest 41 - docker push atcr.io/yourhandle/myapp:latest 70 + # Verify 71 + curl http://localhost:5000/v2/ 42 72 ``` 43 73 44 - ### Pull Images 74 + ### Minimal Configuration 75 + 76 + At minimum, you must set: 45 77 46 78 ```bash 47 - # Public images (no auth required) 48 - docker pull atcr.io/alice.bsky.social/myapp:latest 79 + # Required: Default hold service for blob storage 80 + ATCR_DEFAULT_HOLD_DID=did:web:127.0.0.1:8080 49 81 50 - # Private images (automatic OAuth authentication) 51 - docker pull atcr.io/yourhandle/private-app:latest 82 + # Recommended for production 83 + ATCR_BASE_URL=https://registry.example.com 84 + ATCR_HTTP_ADDR=:5000 52 85 ``` 53 86 54 - ## Running Your Own AppView 87 + See **Configuration Reference** below for all options. 88 + 89 + ## Configuration Reference 90 + 91 + AppView is configured entirely via environment variables. Load them with: 92 + ```bash 93 + source .env.appview 94 + ./bin/atcr-appview serve 95 + ``` 96 + 97 + Or via Docker Compose (recommended). 98 + 99 + ### Server Configuration 100 + 101 + #### `ATCR_HTTP_ADDR` 102 + - **Default:** `:5000` 103 + - **Description:** HTTP listen address for the registry API and web UI 104 + - **Example:** `:5000`, `:8080`, `0.0.0.0:5000` 105 + 106 + #### `ATCR_BASE_URL` 107 + - **Default:** Auto-detected from `ATCR_HTTP_ADDR` (e.g., `http://127.0.0.1:5000`) 108 + - **Description:** Public URL for the AppView service. Used to generate OAuth redirect URIs and JWT realm claims. 109 + - **Development:** Auto-detection works fine (`http://127.0.0.1:5000`) 110 + - **Production:** Set to your public URL (e.g., `https://atcr.example.com`) 111 + - **Example:** `https://atcr.io`, `http://127.0.0.1:5000` 112 + 113 + #### `ATCR_SERVICE_NAME` 114 + - **Default:** Derived from `ATCR_BASE_URL` hostname, or `atcr.io` 115 + - **Description:** Service name used for JWT `service` and `issuer` fields. Controls token scope. 116 + - **Example:** `atcr.io`, `registry.example.com` 117 + 118 + #### `ATCR_DEBUG_ADDR` 119 + - **Default:** `:5001` 120 + - **Description:** Debug listen address for pprof debugging endpoints 121 + - **Example:** `:5001`, `:6060` 122 + 123 + ### Storage Configuration 124 + 125 + #### `ATCR_DEFAULT_HOLD_DID` ⚠️ REQUIRED 126 + - **Default:** None (required) 127 + - **Description:** DID of the default hold service for blob storage. Used when users don't have their own hold configured in their sailor profile. AppView routes all blob operations to this hold. 128 + - **Format:** `did:web:hostname[:port]` 129 + - **Docker Compose:** `did:web:atcr-hold:8080` (internal Docker network) 130 + - **Local dev:** `did:web:127.0.0.1:8080` 131 + - **Production:** `did:web:hold01.atcr.io` 132 + - **Note:** This hold must be reachable from AppView. To find a hold's DID, visit `https://hold-url/.well-known/did.json` 133 + 134 + ### Authentication Configuration 135 + 136 + #### `ATCR_AUTH_KEY_PATH` 137 + - **Default:** `/var/lib/atcr/auth/private-key.pem` 138 + - **Description:** Path to JWT signing private key (RSA). Auto-generated if missing. 139 + - **Note:** Keep this secure - it signs all registry JWTs issued to Docker clients 140 + 141 + #### `ATCR_AUTH_CERT_PATH` 142 + - **Default:** `/var/lib/atcr/auth/private-key.crt` 143 + - **Description:** Path to JWT signing certificate. Auto-generated if missing. 144 + - **Note:** Paired with `ATCR_AUTH_KEY_PATH` 145 + 146 + #### `ATCR_TOKEN_EXPIRATION` 147 + - **Default:** `300` (5 minutes) 148 + - **Description:** JWT token expiration in seconds. Registry JWTs are short-lived for security. 149 + - **Recommendation:** Keep between 300-900 seconds (5-15 minutes) 150 + 151 + ### Web UI Configuration 152 + 153 + #### `ATCR_UI_ENABLED` 154 + - **Default:** `true` 155 + - **Description:** Enable the web interface. Set to `false` to run registry API only (no web UI, no database). 156 + - **Use case:** API-only deployments where you don't need the browsing interface 157 + 158 + #### `ATCR_UI_DATABASE_PATH` 159 + - **Default:** `/var/lib/atcr/ui.db` 160 + - **Description:** SQLite database path for UI data (OAuth sessions, stars, pull counts, repository metadata) 161 + - **Note:** For multi-instance deployments, use PostgreSQL (see production docs) 162 + 163 + ### Logging Configuration 164 + 165 + #### `ATCR_LOG_LEVEL` 166 + - **Default:** `info` 167 + - **Options:** `debug`, `info`, `warn`, `error` 168 + - **Description:** Log verbosity level 169 + - **Development:** Use `debug` for detailed troubleshooting 170 + - **Production:** Use `info` or `warn` 171 + 172 + #### `ATCR_LOG_FORMATTER` 173 + - **Default:** `text` 174 + - **Options:** `text`, `json` 175 + - **Description:** Log output format 176 + - **Production:** Use `json` for structured logging (easier to parse with log aggregators) 177 + 178 + ### Hold Health Check Configuration 179 + 180 + AppView periodically checks if hold services are reachable and caches results to display health indicators in the UI. 181 + 182 + #### `ATCR_HEALTH_CHECK_INTERVAL` 183 + - **Default:** `15m` 184 + - **Description:** How often to check health of hold endpoints in the background 185 + - **Format:** Duration string (e.g., `5m`, `15m`, `30m`, `1h`) 186 + - **Recommendation:** 15-30 minutes for production 187 + 188 + #### `ATCR_HEALTH_CACHE_TTL` 189 + - **Default:** `15m` 190 + - **Description:** How long to cache health check results before re-checking 191 + - **Format:** Duration string (e.g., `15m`, `30m`, `1h`) 192 + - **Note:** Should be >= `ATCR_HEALTH_CHECK_INTERVAL` for efficiency 193 + 194 + ### Jetstream Configuration (ATProto Event Streaming) 195 + 196 + Jetstream provides real-time indexing of ATProto records (manifests, tags) into the AppView database for the web UI. 197 + 198 + #### `JETSTREAM_URL` 199 + - **Default:** `wss://jetstream2.us-west.bsky.network/subscribe` 200 + - **Description:** Jetstream WebSocket URL for real-time ATProto events 201 + - **Note:** Connects to Bluesky's public Jetstream by default 55 202 56 - Deploy your own registry instance with Docker Compose: 203 + #### `ATCR_BACKFILL_ENABLED` 204 + - **Default:** `false` 205 + - **Description:** Enable periodic sync of historical ATProto records. Set to `true` for production to ensure database completeness. 206 + - **Recommendation:** Enable for production AppView instances 207 + 208 + #### `ATCR_RELAY_ENDPOINT` 209 + - **Default:** `https://relay1.us-east.bsky.network` 210 + - **Description:** ATProto relay endpoint for backfill sync API 211 + - **Note:** Used when `ATCR_BACKFILL_ENABLED=true` 212 + 213 + #### `ATCR_BACKFILL_INTERVAL` 214 + - **Default:** `1h` 215 + - **Description:** How often to run backfill sync 216 + - **Format:** Duration string (e.g., `30m`, `1h`, `2h`, `24h`) 217 + 218 + ### Legacy Configuration 219 + 220 + #### `TEST_MODE` 221 + - **Default:** `false` 222 + - **Description:** Enable test mode (skips some validations). Do not use in production. 223 + 224 + ## Web Interface Features 225 + 226 + The AppView web UI provides: 227 + 228 + - **Home page** - Featured repositories and recent pushes feed 229 + - **Repository pages** - View tags, manifests, pull instructions, health status 230 + - **Search** - Find repositories by owner handle or repository name 231 + - **User profiles** - View a user's repositories and activity 232 + - **Stars** - Favorite repositories (requires OAuth login) 233 + - **Pull counts** - Track image pull statistics 234 + - **Multi-arch support** - Display platform-specific manifests (linux/amd64, linux/arm64) 235 + - **Health indicators** - Real-time hold service reachability status 236 + - **Install scripts** - Host credential helper installation scripts at `/install.sh` 237 + 238 + ## Deployment Scenarios 239 + 240 + ### Public Registry (like atcr.io) 241 + 242 + Open to all ATProto users: 57 243 58 244 ```bash 59 - # Create configuration 60 - cp .env.appview.example .env.appview 61 - # Edit .env.appview with your settings 245 + # AppView config 246 + ATCR_BASE_URL=https://registry.example.com 247 + ATCR_DEFAULT_HOLD_DID=did:web:hold01.example.com 248 + ATCR_UI_ENABLED=true 249 + ATCR_BACKFILL_ENABLED=true 62 250 63 - # Start services 64 - docker-compose up -d 251 + # Hold config (linked hold service) 252 + HOLD_PUBLIC=true # Allow public pulls 253 + HOLD_ALLOW_ALL_CREW=true # Allow all authenticated users to push 65 254 ``` 66 255 67 - ### Configuration 256 + ### Private Organizational Registry 257 + 258 + Restricted to crew members only: 68 259 69 - Key environment variables: 260 + ```bash 261 + # AppView config 262 + ATCR_BASE_URL=https://registry.internal.example.com 263 + ATCR_DEFAULT_HOLD_DID=did:web:hold.internal.example.com 264 + ATCR_UI_ENABLED=true 265 + 266 + # Hold config (linked hold service) 267 + HOLD_PUBLIC=false # Require auth for pulls 268 + HOLD_ALLOW_ALL_CREW=false # Only owner + explicit crew can push 269 + HOLD_OWNER=did:plc:your-org-did # Organization DID 270 + ``` 271 + 272 + ### Development/Testing 70 273 71 - - `ATCR_HTTP_ADDR` - HTTP listen address (default: `:5000`) 72 - - `ATCR_BASE_URL` - Public URL for OAuth/JWT realm 73 - - `ATCR_DEFAULT_HOLD_DID` - Default hold service DID for blob storage (required) 74 - - `ATCR_UI_ENABLED` - Enable web interface (default: `true`) 75 - - `JETSTREAM_URL` - ATProto event stream URL for real-time updates 274 + Local Docker Compose setup: 76 275 77 - See [deployment documentation](https://tangled.org/@evan.jarrett.net/at-container-registry/blob/main/deploy/README.md) for production setup. 276 + ```bash 277 + # AppView config 278 + ATCR_HTTP_ADDR=:5000 279 + ATCR_DEFAULT_HOLD_DID=did:web:atcr-hold:8080 280 + ATCR_LOG_LEVEL=debug 78 281 79 - ## Features 282 + # Hold config (linked hold service) 283 + STORAGE_DRIVER=filesystem 284 + STORAGE_ROOT_DIR=/tmp/atcr-hold 285 + HOLD_PUBLIC=true 286 + HOLD_ALLOW_ALL_CREW=true 287 + ``` 80 288 81 - - ✅ **OCI-compliant** - Full Docker Registry API V2 support 82 - - ✅ **ATProto OAuth** - Secure authentication with DPoP 83 - - ✅ **Decentralized storage** - Manifests stored in users' PDS 84 - - ✅ **Web UI** - Browse repositories, view tags, search images 85 - - ✅ **Real-time updates** - Jetstream integration for live indexing 86 - - ✅ **Multi-arch support** - ARM64, AMD64, and other platforms 87 - - ✅ **BYOS** - Bring Your Own Storage via hold services 289 + ## Production Deployment 88 290 89 - ## Storage Architecture 291 + For production deployments with: 292 + - Multiple AppView instances (load balancing) 293 + - PostgreSQL database (instead of SQLite) 294 + - SSL/TLS certificates 295 + - Systemd service files 296 + - Log rotation 297 + - Monitoring 90 298 91 - **Hybrid model:** 92 - - **Manifests** → ATProto records in user's PDS (small JSON metadata) 93 - - **Blobs** → Hold services with S3-compatible backends (large binary layers) 299 + See **[deploy/README.md](https://tangled.org/@evan.jarrett.net/at-container-registry/blob/main/deploy/README.md)** for comprehensive production deployment guide. 94 300 95 - This design keeps metadata portable and federated while leveraging cheap blob storage for layers. 301 + ### Quick Production Checklist 96 302 97 - ## License 303 + Before going to production: 98 304 99 - MIT 305 + - [ ] Set `ATCR_BASE_URL` to your public HTTPS URL 306 + - [ ] Set `ATCR_DEFAULT_HOLD_DID` to a production hold service 307 + - [ ] Enable Jetstream backfill (`ATCR_BACKFILL_ENABLED=true`) 308 + - [ ] Use `ATCR_LOG_FORMATTER=json` for structured logging 309 + - [ ] Secure JWT keys (`ATCR_AUTH_KEY_PATH`, `ATCR_AUTH_CERT_PATH`) 310 + - [ ] Configure SSL/TLS termination (nginx/Caddy/Cloudflare) 311 + - [ ] Set up database backups (if using SQLite, consider PostgreSQL) 312 + - [ ] Monitor hold health checks 313 + - [ ] Test OAuth flow end-to-end 314 + - [ ] Verify Docker push/pull works 100 315 101 - --- 316 + ## Configuration Files Reference 102 317 103 - **Documentation:** https://tangled.org/@evan.jarrett.net/at-container-registry 104 - **Source Code:** https://tangled.org/@evan.jarrett.net/at-container-registry 318 + - **[.env.appview.example](https://tangled.org/@evan.jarrett.net/at-container-registry/blob/main/.env.appview.example)** - All available environment variables with documentation 319 + - **[deploy/.env.prod.template](https://tangled.org/@evan.jarrett.net/at-container-registry/blob/main/deploy/.env.prod.template)** - Production configuration template 320 + - **[deploy/README.md](https://tangled.org/@evan.jarrett.net/at-container-registry/blob/main/deploy/README.md)** - Production deployment guide 321 + - **[Hold Service Documentation](https://atcr.io/r/evan.jarrett.net/atcr-hold)** - Storage backend setup