Files
at-container-registry/docs/TESTING.md
2025-10-06 16:28:58 -05:00

6.8 KiB

Local Testing Guide

Quick Start

./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

sudo mkdir -p /var/lib/atcr/{blobs,hold,auth}
sudo chown -R $USER:$USER /var/lib/atcr

2. Build Binaries

go build -o atcr-registry ./cmd/registry
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:

cp .env.example .env

Edit .env with your credentials:

# 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:

export $(cat .env | xargs)

4. Start Services

Terminal 1 - Registry:

./atcr-registry serve config/config.yml

Terminal 2 - Hold:

./atcr-hold config/hold.yml

5. Start Services and OAuth Registration

Terminal 1 - Registry:

./atcr-registry serve config/config.yml

Terminal 2 - Hold (OAuth registration):

./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

# 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

# Remove local image
docker rmi localhost:5000/alice/alpine:test

# Pull from registry
docker pull localhost:5000/alice/alpine:test

Test 3: Verify Storage

# 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

# 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:

{
  "credHelpers": {
    "localhost:5000": "atcr"
  }
}

Test with OAuth

# Push should now use OAuth automatically
docker push localhost:5000/alice/myapp:latest

Troubleshooting

Registry won't start

Error: failed to create storage driver

# 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

# 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

# Check hold directory
ls -ld /var/lib/atcr/hold
sudo chown -R $USER:$USER /var/lib/atcr/hold

Error: address already in use

# 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:
    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

curl http://localhost:5000/v2/
# Should return: {}

Check Hold is Running

curl http://localhost:8080/health
# Should return: {"status":"ok"}

Check Auth Endpoint

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):

# 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

# If using test script
kill $(cat .atcr-pids)

# Or manually
pkill atcr-registry
pkill atcr-hold

Remove Test Data

# Remove all stored data
sudo rm -rf /var/lib/atcr/*

# Remove OAuth tokens
rm -rf ~/.atcr/

Reset Docker Config

# 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