# Local Testing Guide ## Quick Start ```bash ./test-local.sh ``` This automated script will: 1. Create storage directories 2. Build all binaries 3. Start both services 4. Show test commands ## Manual Testing Steps ### 1. Setup Directories ```bash sudo mkdir -p /var/lib/atcr/{blobs,hold,auth} sudo chown -R $USER:$USER /var/lib/atcr ``` ### 2. Build Binaries ```bash go build -o atcr-appview ./cmd/appview go build -o atcr-hold ./cmd/hold go build -o docker-credential-atcr ./cmd/credential-helper ``` ### 3. Configure Environment Create a `.env` file in the project root: ```bash cp .env.example .env ``` Edit `.env` with your credentials: ```env # Your ATProto handle ATPROTO_HANDLE=your-handle.bsky.social # Hold service public URL (hostname becomes the hold name) HOLD_PUBLIC_URL=http://127.0.0.1:8080 # Enable OAuth registration on startup HOLD_AUTO_REGISTER=true ``` **Notes:** - Use your Bluesky handle (e.g., `alice.bsky.social`) - For localhost, use `127.0.0.1` instead of `localhost` for OAuth - The hostname from the URL becomes the hold name (e.g., `127.0.0.1` or `hold1.atcr.io`) **Load environment:** ```bash export $(cat .env | xargs) ``` ### 4. Start Services **Terminal 1 - AppView:** ```bash ./atcr-appview serve config/config.yml ``` **Terminal 2 - Hold:** ```bash ./atcr-hold config/hold.yml ``` ### 5. Start Services and OAuth Registration **Terminal 1 - AppView:** ```bash ./atcr-appview serve config/config.yml ``` **Terminal 2 - Hold (OAuth registration):** ```bash ./atcr-hold config/hold.yml ``` The hold service will start an OAuth flow. You'll see output like: ``` ================================================================================ OAUTH AUTHORIZATION REQUIRED ================================================================================ Please visit this URL to authorize the hold service: https://bsky.social/oauth/authorize?... Waiting for authorization... ================================================================================ ``` **Steps:** 1. Copy the OAuth URL from the logs 2. Open it in your browser 3. Sign in to Bluesky and authorize 4. The callback will complete automatically 5. Hold service registers in your PDS After successful OAuth, you'll see: ``` ✓ Created hold record: at://did:plc:.../io.atcr.hold/127.0.0.1 ✓ Created crew record: at://did:plc:.../io.atcr.hold.crew/127.0.0.1-did:plc:... ================================================================================ REGISTRATION COMPLETE ================================================================================ Hold service is now registered and ready to use! ``` This creates two records in your PDS: - `io.atcr.hold` - Defines the storage endpoint URL - `io.atcr.hold.crew` - Grants you admin access ### 6. Test Docker Push/Pull **Test 1: Basic Push** ```bash # Tag an image docker tag alpine:latest localhost:5000/alice/alpine:test # Push to local registry docker push localhost:5000/alice/alpine:test ``` **Test 2: Pull** ```bash # Remove local image docker rmi localhost:5000/alice/alpine:test # Pull from registry docker pull localhost:5000/alice/alpine:test ``` **Test 3: Verify Storage** ```bash # Check manifests were stored in ATProto # (Check your PDS for io.atcr.manifest records) # Check blobs were stored locally ls -lh /var/lib/atcr/blobs/docker/registry/v2/ ``` ## OAuth Testing (Optional) ### Setup Credential Helper ```bash # Configure OAuth ./docker-credential-atcr configure # Follow the browser flow to authorize # Verify token was saved ls -la ~/.atcr/oauth-token.json ``` ### Configure Docker to Use Helper Edit `~/.docker/config.json`: ```json { "credHelpers": { "localhost:5000": "atcr" } } ``` ### Test with OAuth ```bash # Push should now use OAuth automatically docker push localhost:5000/alice/myapp:latest ``` ## Troubleshooting ### Registry won't start **Error:** `failed to create storage driver` ```bash # Check directory permissions ls -ld /var/lib/atcr/blobs # Should be owned by your user # Fix permissions sudo chown -R $USER:$USER /var/lib/atcr ``` **Error:** `address already in use` ```bash # Check what's using port 5000 lsof -i :5000 # Kill existing process kill $(lsof -t -i :5000) ``` ### Hold service won't start **Error:** `failed to create storage driver` ```bash # Check hold directory ls -ld /var/lib/atcr/hold sudo chown -R $USER:$USER /var/lib/atcr/hold ``` **Error:** `address already in use` ```bash # Check port 8080 lsof -i :8080 kill $(lsof -t -i :8080) ``` ### Docker push fails **Error:** `unauthorized: authentication required` - Check `ATPROTO_DID` and `ATPROTO_ACCESS_TOKEN` are set - Verify token is valid (not expired) - Check registry logs for auth errors **Error:** `denied: requested access to the resource is denied` - Check the identity in the image name matches your DID - Example: If your handle is `alice.bsky.social`, use: ```bash docker push localhost:5000/alice/myapp:test # NOT localhost:5000/bob/myapp:test ``` **Error:** `failed to resolve identity` - Check internet connection (needs to resolve DIDs) - Verify handle is correct - Try using DID directly instead of handle ### OAuth issues **Error:** `Failed to exchange token` - Ensure registry is running and accessible - Check `/auth/exchange` endpoint is responding - Verify OAuth token hasn't expired **Error:** `Token validation failed` - Token might be expired - Run `./docker-credential-atcr configure` again - Check PDS is accessible ## Verifying the Flow ### Check Registry is Running ```bash curl http://localhost:5000/v2/ # Should return: {} ``` ### Check Hold is Running ```bash curl http://localhost:8080/health # Should return: {"status":"ok"} ``` ### Check Auth Endpoint ```bash curl -v http://localhost:5000/v2/ # Should return 401 with WWW-Authenticate header ``` ### Inspect Stored Data **Manifests (in ATProto):** - Check your PDS web interface - Look for `io.atcr.manifest` collection records **Blobs (local filesystem):** ```bash # List blobs find /var/lib/atcr/blobs -type f # Check blob content (should be binary) ls -lh /var/lib/atcr/blobs/docker/registry/v2/blobs/sha256/ ``` ## Clean Up ### Stop Services ```bash # If using test script kill $(cat .atcr-pids) # Or manually pkill atcr-appview pkill atcr-hold ``` ### Remove Test Data ```bash # Remove all stored data sudo rm -rf /var/lib/atcr/* # Remove OAuth tokens rm -rf ~/.atcr/ ``` ### Reset Docker Config ```bash # Remove credential helper config # Edit ~/.docker/config.json and remove "credHelpers" section ``` ## Next Steps Once local testing works: 1. **Deploy to production:** - Use S3/Storj for blob storage - Deploy registry and hold to separate hosts - Configure DNS for `atcr.io` 2. **Enable BYOS:** - Users create `io.atcr.hold` records - Deploy their own hold service - AppView automatically routes to their storage 3. **Add monitoring:** - Registry metrics - Hold service metrics - Storage usage tracking