mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-30 04:37:06 +00:00
335 lines
6.8 KiB
Markdown
335 lines
6.8 KiB
Markdown
# 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
|