Files

243 lines
8.9 KiB
Bash

# ATCR Production Environment Configuration
# Copy this file to .env and fill in your values
#
# Usage:
# 1. cp deploy/.env.prod.template .env
# 2. Edit .env with your configuration
# 3. systemctl restart atcr
#
# NOTE: This file is loaded by docker-compose.prod.yml
# ==============================================================================
# Domain Configuration
# ==============================================================================
# Main AppView domain (registry API + web UI)
# REQUIRED: Update with your domain
APPVIEW_DOMAIN=atcr.io
# ==============================================================================
# Hold Service Configuration
# ==============================================================================
# Hold service domain (REQUIRED)
# The hostname where the hold service will be accessible
# Used by docker-compose.prod.yml to derive:
# - HOLD_PUBLIC_URL: https://${HOLD_DOMAIN}
# - ATCR_DEFAULT_HOLD_DID: did:web:${HOLD_DOMAIN}
# Example: hold01.atcr.io
HOLD_DOMAIN=hold01.atcr.io
# Your ATProto DID (REQUIRED for hold registration)
# Get your DID from: https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=yourhandle.bsky.social
# Example: did:plc:abc123xyz789
HOLD_OWNER=did:plc:pddp4xt5lgnv2qsegbzzs4xg
# Directory path for embedded PDS carstore (SQLite database)
# Default: /var/lib/atcr-hold
# If empty, embedded PDS is disabled
#
# Note: This should be a directory path, NOT a file path
# Carstore creates db.sqlite3 inside this directory
#
# The embedded PDS makes the hold a proper ATProto user with:
# - did:web identity (derived from HOLD_DOMAIN)
# - DID document at /.well-known/did.json
# - XRPC endpoints for crew management
# - ATProto blob endpoints (wraps existing presigned URL logic)
#
# Example: For HOLD_DOMAIN=hold01.atcr.io, the hold becomes did:web:hold01.atcr.io
HOLD_DATABASE_DIR=/var/lib/atcr-hold
# Path to signing key (auto-generated on first run if missing)
# Default: {HOLD_DATABASE_DIR}/signing.key
# HOLD_KEY_PATH=/var/lib/atcr-hold/signing.key
# Allow public blob reads (pulls) without authentication
# - true: Anyone can pull images (read-only)
# - false: Only authenticated users can pull
# Default: false (private)
HOLD_PUBLIC=false
# Allow all authenticated users to write to this hold
# This setting controls write permissions for authenticated ATCR users
#
# - true: Any authenticated ATCR user can push images (treat all as crew)
# Useful for shared/community holds where you want to allow
# multiple users to push without explicit crew membership.
# Users must still authenticate via ATProto OAuth.
#
# - false: Only hold owner and explicit crew members can push (default)
# Write access requires io.atcr.hold.crew record in owner's PDS.
# Most secure option for production holds.
#
# Read permissions are controlled by HOLD_PUBLIC (above).
#
# Security model:
# Read: HOLD_PUBLIC=true → anonymous + authenticated users
# HOLD_PUBLIC=false → authenticated users only
# Write: HOLD_ALLOW_ALL_CREW=true → all authenticated users
# HOLD_ALLOW_ALL_CREW=false → owner + crew only (verified via PDS)
#
# Use cases:
# - Public registry: HOLD_PUBLIC=true, HOLD_ALLOW_ALL_CREW=true
# - ATProto users only: HOLD_PUBLIC=false, HOLD_ALLOW_ALL_CREW=true
# - Private hold (default): HOLD_PUBLIC=false, HOLD_ALLOW_ALL_CREW=false
#
# Default: false
HOLD_ALLOW_ALL_CREW=false
# Enable Bluesky posts when manifests are pushed
# When enabled, the hold service creates Bluesky posts announcing new container
# image pushes. Posts include image name, tag, size, and layer count.
#
# - true: Create Bluesky posts for manifest uploads
# - false: Silent operation (no Bluesky posts)
#
# Note: This requires the hold owner to have OAuth credentials for posting.
# See docs/BLUESKY_MANIFEST_POSTS.md for setup instructions.
#
# Default: false
HOLD_BLUESKY_POSTS_ENABLED=true
# ==============================================================================
# S3/UpCloud Object Storage Configuration
# ==============================================================================
# Storage driver type
# Options: s3, filesystem
# Default: s3
STORAGE_DRIVER=s3
# S3 Access Credentials
# Get these from UpCloud Object Storage console
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
# S3 Region (for distribution S3 driver)
# For third-party S3 providers (UpCloud, Storj, Minio), this value is ignored
# when S3_ENDPOINT is set, but must be a valid AWS region to pass validation.
# Default: us-east-1
AWS_REGION=us-east-1
# S3 Bucket Name
# Create this bucket in UpCloud Object Storage
# Example: atcr-blobs
S3_BUCKET=atcr
# S3 Endpoint
# Get this from UpCloud Console → Storage → Object Storage → Your bucket → "S3 endpoint"
# Format: https://[bucket-id].upcloudobjects.com
# Example: https://6vmss.upcloudobjects.com
#
# NOTE: Use the bucket-specific endpoint, NOT a custom domain
# Custom domains break presigned URL generation
S3_ENDPOINT=https://6vmss.upcloudobjects.com
# ==============================================================================
# AppView Configuration
# ==============================================================================
# Default hold service DID (derived from HOLD_DOMAIN in docker-compose.prod.yml)
# Uncomment to override if you want to use a different hold service as the default
# ATCR_DEFAULT_HOLD_DID=did:web:some-other-hold.example.com
# JWT token expiration in seconds
# Default: 300 (5 minutes)
ATCR_TOKEN_EXPIRATION=300
# OAuth client display name (shown in authorization screens)
# Default: AT Container Registry
# ATCR_CLIENT_NAME=AT Container Registry
# Enable web UI
# Default: true
ATCR_UI_ENABLED=true
# Skip database migrations on startup
# Default: false (migrations are applied on startup)
# Set to "true" only for testing or when migrations are managed externally
# Production: Keep as "false" to ensure migrations are applied
SKIP_DB_MIGRATIONS=false
# ==============================================================================
# Logging Configuration
# ==============================================================================
# Log level: debug, info, warn, error
# Default: info
ATCR_LOG_LEVEL=debug
# Log formatter: text, json
# Default: text
ATCR_LOG_FORMATTER=text
# ==============================================================================
# Jetstream Configuration (ATProto event streaming)
# ==============================================================================
# Jetstream WebSocket URL for real-time ATProto events
# Default: wss://jetstream2.us-west.bsky.network/subscribe
JETSTREAM_URL=wss://jetstream2.us-west.bsky.network/subscribe
# Enable backfill worker to sync historical records
# Default: true (recommended for production)
ATCR_BACKFILL_ENABLED=true
# ATProto relay endpoint for backfill sync API
# Default: https://relay1.us-east.bsky.network
ATCR_RELAY_ENDPOINT=https://relay1.us-east.bsky.network
# Backfill interval
# Examples: 30m, 1h, 2h, 24h
# Default: 1h
ATCR_BACKFILL_INTERVAL=1h
# ==============================================================================
# Optional: Filesystem Storage (alternative to S3)
# ==============================================================================
# If using filesystem storage instead of S3:
# 1. Uncomment these lines
# 2. Comment out all S3 variables above
# 3. Set STORAGE_DRIVER=filesystem
# STORAGE_DRIVER=filesystem
# STORAGE_ROOT_DIR=/var/lib/atcr/hold
# ==============================================================================
# Advanced Configuration
# ==============================================================================
# Override service name (defaults to APPVIEW_DOMAIN)
# ATCR_SERVICE_NAME=atcr.io
# Debug listen address (optional - for pprof debugging)
# ATCR_DEBUG_ADDR=:5001
# ==============================================================================
# CHECKLIST
# ==============================================================================
#
# Before starting ATCR, ensure you have:
#
# ☐ Set APPVIEW_DOMAIN (e.g., atcr.io)
# ☐ Set HOLD_DOMAIN (e.g., hold01.atcr.io)
# ☐ Set HOLD_OWNER (your ATProto DID)
# ☐ Set HOLD_DATABASE_DIR (default: /var/lib/atcr-hold) - enables embedded PDS
# ☐ Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
# ☐ Set S3_BUCKET (created in UpCloud Object Storage)
# ☐ Set S3_ENDPOINT (UpCloud bucket endpoint, e.g., https://6vmss.upcloudobjects.com)
# ☐ Configured DNS records:
# - A record: atcr.io → server IP
# - A record: hold01.atcr.io → server IP
# - CNAME: blobs.atcr.io → [bucket].upcloudobjects.com
# ☐ Disabled Cloudflare proxy (gray cloud, not orange)
# ☐ Waited for DNS propagation (check with: dig atcr.io)
#
# After starting:
# ☐ Complete hold OAuth registration (run: /opt/atcr/get-hold-oauth.sh)
# ☐ Verify hold PDS: curl https://hold01.atcr.io/.well-known/did.json
# ☐ Test registry: docker pull atcr.io/test/image
# ☐ Monitor logs: /opt/atcr/logs.sh