···8484 # Organization name for Terms of Service and Privacy Policy. Defaults to server.client_name.
8585 company_name: ""
8686 # Governing law jurisdiction for legal terms.
8787- jurisdiction: State of Texas, United States
8787+ jurisdiction: ""
-216
deploy/.env.prod.template
···11-# ATCR Production Environment Configuration
22-# Copy this file to .env and fill in your values
33-#
44-# Usage:
55-# 1. cp deploy/.env.prod.template .env
66-# 2. Edit .env with your configuration
77-# 3. systemctl restart atcr
88-#
99-# NOTE: This file is loaded by docker-compose.prod.yml
1010-1111-# ==============================================================================
1212-# Domain Configuration
1313-# ==============================================================================
1414-1515-# Main AppView domain (registry API + web UI)
1616-# REQUIRED: Update with your domain
1717-APPVIEW_DOMAIN=atcr.io
1818-1919-# ==============================================================================
2020-# Hold Service Configuration
2121-# ==============================================================================
2222-2323-# Hold service domain (REQUIRED)
2424-# The hostname where the hold service will be accessible
2525-# Used by docker-compose.prod.yml to derive:
2626-# - HOLD_PUBLIC_URL: https://${HOLD_DOMAIN}
2727-# - ATCR_DEFAULT_HOLD_DID: did:web:${HOLD_DOMAIN}
2828-# Example: hold01.atcr.io
2929-HOLD_DOMAIN=hold01.atcr.io
3030-3131-# Your ATProto DID (REQUIRED for hold registration)
3232-# Get your DID from: https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=yourhandle.bsky.social
3333-# Example: did:plc:abc123xyz789
3434-HOLD_OWNER=did:plc:pddp4xt5lgnv2qsegbzzs4xg
3535-3636-# Directory path for embedded PDS carstore (SQLite database)
3737-# Default: /var/lib/atcr-hold
3838-# If empty, embedded PDS is disabled
3939-#
4040-# Note: This should be a directory path, NOT a file path
4141-# Carstore creates db.sqlite3 inside this directory
4242-#
4343-# The embedded PDS makes the hold a proper ATProto user with:
4444-# - did:web identity (derived from HOLD_DOMAIN)
4545-# - DID document at /.well-known/did.json
4646-# - XRPC endpoints for crew management
4747-# - ATProto blob endpoints (wraps existing presigned URL logic)
4848-#
4949-# Example: For HOLD_DOMAIN=hold01.atcr.io, the hold becomes did:web:hold01.atcr.io
5050-HOLD_DATABASE_DIR=/var/lib/atcr-hold
5151-5252-# Path to signing key (auto-generated on first run if missing)
5353-# Default: {HOLD_DATABASE_DIR}/signing.key
5454-# HOLD_KEY_PATH=/var/lib/atcr-hold/signing.key
5555-5656-# Allow public blob reads (pulls) without authentication
5757-# - true: Anyone can pull images (read-only)
5858-# - false: Only authenticated users can pull
5959-# Default: false (private)
6060-HOLD_PUBLIC=false
6161-6262-# Allow all authenticated users to write to this hold
6363-# This setting controls write permissions for authenticated ATCR users
6464-#
6565-# - true: Any authenticated ATCR user can push images (treat all as crew)
6666-# Useful for shared/community holds where you want to allow
6767-# multiple users to push without explicit crew membership.
6868-# Users must still authenticate via ATProto OAuth.
6969-#
7070-# - false: Only hold owner and explicit crew members can push (default)
7171-# Write access requires io.atcr.hold.crew record in owner's PDS.
7272-# Most secure option for production holds.
7373-#
7474-# Read permissions are controlled by HOLD_PUBLIC (above).
7575-#
7676-# Security model:
7777-# Read: HOLD_PUBLIC=true → anonymous + authenticated users
7878-# HOLD_PUBLIC=false → authenticated users only
7979-# Write: HOLD_ALLOW_ALL_CREW=true → all authenticated users
8080-# HOLD_ALLOW_ALL_CREW=false → owner + crew only (verified via PDS)
8181-#
8282-# Use cases:
8383-# - Public registry: HOLD_PUBLIC=true, HOLD_ALLOW_ALL_CREW=true
8484-# - ATProto users only: HOLD_PUBLIC=false, HOLD_ALLOW_ALL_CREW=true
8585-# - Private hold (default): HOLD_PUBLIC=false, HOLD_ALLOW_ALL_CREW=false
8686-#
8787-# Default: false
8888-HOLD_ALLOW_ALL_CREW=false
8989-9090-# Enable Bluesky posts when manifests are pushed
9191-# When enabled, the hold service creates Bluesky posts announcing new container
9292-# image pushes. Posts include image name, tag, size, and layer count.
9393-#
9494-# - true: Create Bluesky posts for manifest uploads
9595-# - false: Silent operation (no Bluesky posts)
9696-#
9797-# Note: This requires the hold owner to have OAuth credentials for posting.
9898-# See docs/BLUESKY_MANIFEST_POSTS.md for setup instructions.
9999-#
100100-# Default: false
101101-HOLD_BLUESKY_POSTS_ENABLED=true
102102-103103-# ==============================================================================
104104-# S3/UpCloud Object Storage Configuration (REQUIRED)
105105-# ==============================================================================
106106-107107-# S3 is the only supported storage backend. Presigned URLs are used for direct
108108-# client ↔ S3 transfers, eliminating the hold service as a bandwidth bottleneck.
109109-110110-# S3 Access Credentials
111111-# Get these from UpCloud Object Storage console
112112-AWS_ACCESS_KEY_ID=
113113-AWS_SECRET_ACCESS_KEY=
114114-115115-# S3 Region (for distribution S3 driver)
116116-# For third-party S3 providers (UpCloud, Storj, Minio), this value is ignored
117117-# when S3_ENDPOINT is set, but must be a valid AWS region to pass validation.
118118-# Default: us-east-1
119119-AWS_REGION=us-east-1
120120-121121-# S3 Bucket Name
122122-# Create this bucket in UpCloud Object Storage
123123-# Example: atcr-blobs
124124-S3_BUCKET=atcr
125125-126126-# S3 Endpoint
127127-# Get this from UpCloud Console → Storage → Object Storage → Your bucket → "S3 endpoint"
128128-# Format: https://[bucket-id].upcloudobjects.com
129129-# Example: https://6vmss.upcloudobjects.com
130130-#
131131-# NOTE: Use the bucket-specific endpoint, NOT a custom domain
132132-# Custom domains break presigned URL generation
133133-S3_ENDPOINT=https://6vmss.upcloudobjects.com
134134-135135-# ==============================================================================
136136-# AppView Configuration
137137-# ==============================================================================
138138-139139-# Default hold service DID (derived from HOLD_DOMAIN in docker-compose.prod.yml)
140140-# Uncomment to override if you want to use a different hold service as the default
141141-# ATCR_DEFAULT_HOLD_DID=did:web:some-other-hold.example.com
142142-143143-# OAuth client display name (shown in authorization screens)
144144-# Default: AT Container Registry
145145-# ATCR_CLIENT_NAME=AT Container Registry
146146-147147-# Short brand name for page titles and metadata
148148-# Used in meta tags, page titles, and UI text
149149-# Default: ATCR
150150-# ATCR_CLIENT_SHORT_NAME=ATCR
151151-152152-# ==============================================================================
153153-# Legal Page Customization
154154-# ==============================================================================
155155-156156-# Company/organization name displayed in legal pages (Terms, Privacy)
157157-# Default: AT Container Registry
158158-ATCR_LEGAL_COMPANY_NAME=AT Container Registry
159159-160160-# Governing law jurisdiction for legal terms
161161-# Default: State of Texas, United States
162162-ATCR_LEGAL_JURISDICTION=State of Texas, United States
163163-164164-# ==============================================================================
165165-# Logging Configuration
166166-# ==============================================================================
167167-168168-# Log level: debug, info, warn, error
169169-# Default: info
170170-ATCR_LOG_LEVEL=debug
171171-172172-# Log formatter: text, json
173173-# Default: text
174174-ATCR_LOG_FORMATTER=text
175175-176176-# ==============================================================================
177177-# Jetstream Configuration (ATProto event streaming)
178178-# ==============================================================================
179179-180180-# Jetstream WebSocket URL for real-time ATProto events
181181-# Default: wss://jetstream2.us-west.bsky.network/subscribe
182182-JETSTREAM_URL=wss://jetstream2.us-west.bsky.network/subscribe
183183-184184-# Enable backfill worker to sync historical records
185185-# Default: true (recommended for production)
186186-ATCR_BACKFILL_ENABLED=true
187187-188188-# ATProto relay endpoint for backfill sync API
189189-# Default: https://relay1.us-east.bsky.network
190190-ATCR_RELAY_ENDPOINT=https://relay1.us-east.bsky.network
191191-192192-# ==============================================================================
193193-# CHECKLIST
194194-# ==============================================================================
195195-#
196196-# Before starting ATCR, ensure you have:
197197-#
198198-# ☐ Set APPVIEW_DOMAIN (e.g., atcr.io)
199199-# ☐ Set HOLD_DOMAIN (e.g., hold01.atcr.io)
200200-# ☐ Set HOLD_OWNER (your ATProto DID)
201201-# ☐ Set HOLD_DATABASE_DIR (default: /var/lib/atcr-hold) - enables embedded PDS
202202-# ☐ Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
203203-# ☐ Set S3_BUCKET (created in UpCloud Object Storage)
204204-# ☐ Set S3_ENDPOINT (UpCloud bucket endpoint, e.g., https://6vmss.upcloudobjects.com)
205205-# ☐ Configured DNS records:
206206-# - A record: atcr.io → server IP
207207-# - A record: hold01.atcr.io → server IP
208208-# - CNAME: blobs.atcr.io → [bucket].upcloudobjects.com
209209-# ☐ Disabled Cloudflare proxy (gray cloud, not orange)
210210-# ☐ Waited for DNS propagation (check with: dig atcr.io)
211211-#
212212-# After starting:
213213-# ☐ Complete hold OAuth registration (run: /opt/atcr/get-hold-oauth.sh)
214214-# ☐ Verify hold PDS: curl https://hold01.atcr.io/.well-known/did.json
215215-# ☐ Test registry: docker pull atcr.io/test/image
216216-# ☐ Monitor logs: /opt/atcr/logs.sh
···11-#!/bin/bash
22-#
33-# ATCR UpCloud Initialization Script for Rocky Linux
44-#
55-# This script sets up ATCR on a fresh Rocky Linux instance.
66-# Paste this into UpCloud's "User data" field when creating a server.
77-#
88-# What it does:
99-# - Updates system packages
1010-# - Creates 2GB swap file (for 1GB RAM instances)
1111-# - Installs Docker and Docker Compose
1212-# - Creates directory structure
1313-# - Clones ATCR repository
1414-# - Creates systemd service for auto-start
1515-# - Builds and starts containers
1616-#
1717-# Post-deployment:
1818-# 1. Edit /opt/atcr/.env with your configuration
1919-# 2. Run: systemctl restart atcr
2020-# 3. Check logs: docker logs atcr-hold (for OAuth URL)
2121-# 4. Complete hold registration via OAuth
2222-2323-set -euo pipefail
2424-2525-# Configuration
2626-ATCR_DIR="/opt/atcr"
2727-ATCR_REPO="https://tangled.org/evan.jarrett.net/at-container-registry" # UPDATE THIS
2828-ATCR_BRANCH="main"
2929-3030-# Simple logging without colors (for cloud-init log compatibility)
3131-log_info() {
3232- echo "[INFO] $1"
3333-}
3434-3535-log_warn() {
3636- echo "[WARN] $1"
3737-}
3838-3939-log_error() {
4040- echo "[ERROR] $1"
4141-}
4242-4343-# Function to check if command exists
4444-command_exists() {
4545- command -v "$1" >/dev/null 2>&1
4646-}
4747-4848-log_info "Starting ATCR deployment on Rocky Linux..."
4949-5050-# Update system packages
5151-log_info "Updating system packages..."
5252-dnf update -y
5353-5454-# Install required packages
5555-log_info "Installing prerequisites..."
5656-dnf install -y \
5757- git \
5858- wget \
5959- curl \
6060- nano \
6161- vim
6262-6363-log_info "Required ports: HTTP (80), HTTPS (443), SSH (22)"
6464-6565-# Create swap file for instances with limited RAM
6666-if [ ! -f /swapfile ]; then
6767- log_info "Creating 2GB swap file (allows builds on 1GB RAM instances)..."
6868- dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
6969- chmod 600 /swapfile
7070- mkswap /swapfile
7171- swapon /swapfile
7272-7373- # Make swap permanent
7474- echo '/swapfile none swap sw 0 0' >> /etc/fstab
7575-7676- log_info "Swap file created and enabled"
7777- free -h
7878-else
7979- log_info "Swap file already exists"
8080-fi
8181-8282-# Install Docker
8383-if ! command_exists docker; then
8484- log_info "Installing Docker..."
8585-8686- # Add Docker repository
8787- dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
8888-8989- # Install Docker
9090- dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
9191-9292- # Start and enable Docker
9393- systemctl enable --now docker
9494-9595- log_info "Docker installed successfully"
9696-else
9797- log_info "Docker already installed"
9898-fi
9999-100100-# Verify Docker Compose
101101-if ! docker compose version >/dev/null 2>&1; then
102102- log_error "Docker Compose plugin not found. Please install manually."
103103- exit 1
104104-fi
105105-106106-log_info "Docker Compose version: $(docker compose version)"
107107-108108-# Create ATCR directory
109109-log_info "Creating ATCR directory: $ATCR_DIR"
110110-mkdir -p "$ATCR_DIR"
111111-cd "$ATCR_DIR"
112112-113113-# Clone repository or create minimal structure
114114-if [ -n "$ATCR_REPO" ] && [ "$ATCR_REPO" != "https://tangled.org/evan.jarrett.net/at-container-registry" ]; then
115115- log_info "Cloning ATCR repository..."
116116- git clone -b "$ATCR_BRANCH" "$ATCR_REPO" .
117117-else
118118- log_warn "ATCR_REPO not configured. You'll need to manually copy files to $ATCR_DIR"
119119- log_warn "Required files:"
120120- log_warn " - deploy/docker-compose.prod.yml"
121121- log_warn " - deploy/.env.prod.template"
122122- log_warn " - Dockerfile.appview"
123123- log_warn " - Dockerfile.hold"
124124-fi
125125-126126-# Create .env file from template if it doesn't exist
127127-if [ -f "deploy/.env.prod.template" ] && [ ! -f "$ATCR_DIR/.env" ]; then
128128- log_info "Creating .env file from template..."
129129- cp deploy/.env.prod.template "$ATCR_DIR/.env"
130130- log_warn "IMPORTANT: Edit $ATCR_DIR/.env with your configuration!"
131131-fi
132132-133133-# Create systemd services (caddy, appview, hold)
134134-log_info "Creating systemd services..."
135135-136136-# Caddy service (reverse proxy for both appview and hold)
137137-cat > /etc/systemd/system/atcr-caddy.service <<'EOF'
138138-[Unit]
139139-Description=ATCR Caddy Reverse Proxy
140140-Requires=docker.service
141141-After=docker.service network-online.target
142142-Wants=network-online.target
143143-144144-[Service]
145145-Type=oneshot
146146-RemainAfterExit=yes
147147-WorkingDirectory=/opt/atcr
148148-EnvironmentFile=/opt/atcr/.env
149149-150150-# Start caddy container
151151-ExecStart=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml up -d caddy
152152-153153-# Stop caddy container
154154-ExecStop=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml stop caddy
155155-156156-# Restart caddy container
157157-ExecReload=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml restart caddy
158158-159159-# Always restart on failure
160160-Restart=on-failure
161161-RestartSec=10
162162-163163-[Install]
164164-WantedBy=multi-user.target
165165-EOF
166166-167167-# AppView service (registry + web UI)
168168-cat > /etc/systemd/system/atcr-appview.service <<'EOF'
169169-[Unit]
170170-Description=ATCR AppView (Registry + Web UI)
171171-Requires=docker.service atcr-caddy.service
172172-After=docker.service network-online.target atcr-caddy.service
173173-Wants=network-online.target
174174-175175-[Service]
176176-Type=oneshot
177177-RemainAfterExit=yes
178178-WorkingDirectory=/opt/atcr
179179-EnvironmentFile=/opt/atcr/.env
180180-181181-# Start appview container
182182-ExecStart=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml up -d atcr-appview
183183-184184-# Stop appview container
185185-ExecStop=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml stop atcr-appview
186186-187187-# Restart appview container
188188-ExecReload=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml restart atcr-appview
189189-190190-# Always restart on failure
191191-Restart=on-failure
192192-RestartSec=10
193193-194194-[Install]
195195-WantedBy=multi-user.target
196196-EOF
197197-198198-# Hold service (storage backend)
199199-cat > /etc/systemd/system/atcr-hold.service <<'EOF'
200200-[Unit]
201201-Description=ATCR Hold (Storage Service)
202202-Requires=docker.service atcr-caddy.service
203203-After=docker.service network-online.target atcr-caddy.service
204204-Wants=network-online.target
205205-206206-[Service]
207207-Type=oneshot
208208-RemainAfterExit=yes
209209-WorkingDirectory=/opt/atcr
210210-EnvironmentFile=/opt/atcr/.env
211211-212212-# Start hold container
213213-ExecStart=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml up -d atcr-hold
214214-215215-# Stop hold container
216216-ExecStop=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml stop atcr-hold
217217-218218-# Restart hold container
219219-ExecReload=/usr/bin/docker compose -f /opt/atcr/deploy/docker-compose.prod.yml restart atcr-hold
220220-221221-# Always restart on failure
222222-Restart=on-failure
223223-RestartSec=10
224224-225225-[Install]
226226-WantedBy=multi-user.target
227227-EOF
228228-229229-# Reload systemd
230230-log_info "Reloading systemd daemon..."
231231-systemctl daemon-reload
232232-233233-# Enable all services (but don't start yet - user needs to configure .env)
234234-systemctl enable atcr-caddy.service
235235-systemctl enable atcr-appview.service
236236-systemctl enable atcr-hold.service
237237-238238-log_info "Systemd services created and enabled"
239239-240240-# Create helper scripts
241241-log_info "Creating helper scripts..."
242242-243243-# Script to rebuild and restart
244244-cat > "$ATCR_DIR/rebuild.sh" <<'EOF'
245245-#!/bin/bash
246246-set -e
247247-cd /opt/atcr
248248-docker compose -f deploy/docker-compose.prod.yml build
249249-docker compose -f deploy/docker-compose.prod.yml up -d
250250-docker compose -f deploy/docker-compose.prod.yml logs -f
251251-EOF
252252-chmod +x "$ATCR_DIR/rebuild.sh"
253253-254254-# Script to view logs
255255-cat > "$ATCR_DIR/logs.sh" <<'EOF'
256256-#!/bin/bash
257257-cd /opt/atcr
258258-docker compose -f deploy/docker-compose.prod.yml logs -f "$@"
259259-EOF
260260-chmod +x "$ATCR_DIR/logs.sh"
261261-262262-log_info "Helper scripts created in $ATCR_DIR"
263263-264264-# Print completion message
265265-cat <<'EOF'
266266-267267-================================================================================
268268-ATCR Installation Complete!
269269-================================================================================
270270-271271-NEXT STEPS:
272272-273273-1. Configure environment variables:
274274- nano /opt/atcr/.env
275275-276276- Required settings:
277277- - AWS_ACCESS_KEY_ID (UpCloud S3 credentials)
278278- - AWS_SECRET_ACCESS_KEY
279279-280280- Pre-configured (verify these are correct):
281281- - APPVIEW_DOMAIN=atcr.io
282282- - HOLD_DOMAIN=hold01.atcr.io
283283- - HOLD_OWNER=did:plc:pddp4xt5lgnv2qsegbzzs4xg
284284- - S3_BUCKET=atcr
285285- - S3_ENDPOINT=https://blobs.atcr.io
286286-287287-2. Configure UpCloud Cloud Firewall (in control panel):
288288- Allow: TCP 22 (SSH)
289289- Allow: TCP 80 (HTTP)
290290- Allow: TCP 443 (HTTPS)
291291- Drop: Everything else
292292-293293-3. Configure DNS (Cloudflare - DNS-only mode):
294294-EOF
295295-296296-echo " A atcr.io → $(curl -s ifconfig.me || echo '[server-ip]') (gray cloud)"
297297-echo " A hold01.atcr.io → $(curl -s ifconfig.me || echo '[server-ip]') (gray cloud)"
298298-echo " CNAME blobs.atcr.io → atcr.us-chi1.upcloudobjects.com (gray cloud)"
299299-300300-cat <<'EOF'
301301-302302-4. Start ATCR services:
303303- systemctl start atcr-caddy atcr-appview atcr-hold
304304-305305-5. Check status:
306306- systemctl status atcr-caddy
307307- systemctl status atcr-appview
308308- systemctl status atcr-hold
309309- docker ps
310310- /opt/atcr/logs.sh
311311-312312-Helper Scripts:
313313- /opt/atcr/rebuild.sh - Rebuild and restart containers
314314- /opt/atcr/logs.sh [service] - View logs (e.g., logs.sh atcr-hold)
315315-316316-Service Management:
317317- systemctl start atcr-caddy - Start Caddy reverse proxy
318318- systemctl start atcr-appview - Start AppView (registry + UI)
319319- systemctl start atcr-hold - Start Hold (storage service)
320320-321321- systemctl stop atcr-appview - Stop AppView only
322322- systemctl stop atcr-hold - Stop Hold only
323323- systemctl stop atcr-caddy - Stop all (stops reverse proxy)
324324-325325- systemctl restart atcr-appview - Restart AppView
326326- systemctl restart atcr-hold - Restart Hold
327327-328328- systemctl status atcr-caddy - Check Caddy status
329329- systemctl status atcr-appview - Check AppView status
330330- systemctl status atcr-hold - Check Hold status
331331-332332-Documentation:
333333- https://tangled.org/evan.jarrett.net/at-container-registry
334334-335335-IMPORTANT:
336336- - Edit /opt/atcr/.env with S3 credentials before starting!
337337- - Configure UpCloud cloud firewall (see step 2)
338338- - DNS must be configured and propagated
339339- - Cloudflare proxy must be DISABLED (gray cloud)
340340- - Complete hold OAuth registration before first push
341341-342342-EOF
343343-344344-log_info "Installation complete. Follow the next steps above."
-41
deploy/quotas.yaml
···11-# ATCR Hold Service Quota Configuration
22-# Copy this file to quotas.yaml to enable quota enforcement.
33-# If quotas.yaml doesn't exist, quotas are disabled (unlimited for all users).
44-55-# Tiers define quota levels using nautical crew ranks.
66-# Each tier has a quota limit specified in human-readable format.
77-# Supported units: B, KB, MB, GB, TB, PB (case-insensitive)
88-tiers:
99- # Entry-level crew - starter tier for new users (free)
1010- swabbie:
1111- quota: 2GB
1212-1313- # Standard crew - for regular users
1414- deckhand:
1515- quota: 5GB
1616-1717- # Mid-level crew - for regular contributors
1818- bosun:
1919- quota: 10GB
2020-2121- # Senior crew - for power users or trusted contributors
2222- #quartermaster:
2323- # quota: 50GB
2424-2525- # You can add custom tiers with any name:
2626- # admiral:
2727- # quota: 1TB
2828-2929-defaults:
3030- # Default tier assigned to new crew members who don't have an explicit tier.
3131- # This tier must exist in the tiers section above.
3232- new_crew_tier: swabbie
3333-3434-# Notes:
3535-# - The hold captain (owner) always has unlimited quota regardless of tiers.
3636-# - Crew members can be assigned a specific tier in their crew record.
3737-# - If a crew member's tier doesn't exist in config, they fall back to the default.
3838-# - Quota is calculated per-user by summing unique blob sizes (deduplicated).
3939-# - Quota is checked when pushing manifests (after blobs are already uploaded).
4040-# - Billing configuration (Stripe prices, descriptions) goes in a separate
4141-# top-level "billing:" section. See billing documentation for details.
-55
deploy/request-crawl.sh
···11-#!/bin/bash
22-#
33-# Request crawl for a PDS from the Bluesky relay
44-#
55-# Usage: ./request-crawl.sh <hostname> [relay-url]
66-# Example: ./request-crawl.sh hold01.atcr.io
77-#
88-99-set -e
1010-1111-DEFAULT_RELAY="https://bsky.network/xrpc/com.atproto.sync.requestCrawl"
1212-1313-# Parse arguments
1414-HOSTNAME="${1:-}"
1515-RELAY_URL="${2:-$DEFAULT_RELAY}"
1616-1717-# Validate hostname
1818-if [ -z "$HOSTNAME" ]; then
1919- echo "Error: hostname is required" >&2
2020- echo "" >&2
2121- echo "Usage: $0 <hostname> [relay-url]" >&2
2222- echo "Example: $0 hold01.atcr.io" >&2
2323- echo "" >&2
2424- echo "Options:" >&2
2525- echo " hostname Hostname of the PDS to request crawl for (required)" >&2
2626- echo " relay-url Relay URL to send crawl request to (default: $DEFAULT_RELAY)" >&2
2727- exit 1
2828-fi
2929-3030-# Log what we're doing
3131-echo "Requesting crawl for hostname: $HOSTNAME"
3232-echo "Sending to relay: $RELAY_URL"
3333-3434-# Make the request
3535-RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$RELAY_URL" \
3636- -H "Content-Type: application/json" \
3737- -d "{\"hostname\":\"$HOSTNAME\"}")
3838-3939-# Split response and status code
4040-HTTP_BODY=$(echo "$RESPONSE" | head -n -1)
4141-HTTP_CODE=$(echo "$RESPONSE" | tail -n 1)
4242-4343-# Check response
4444-if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
4545- echo "✅ Success! Crawl requested for $HOSTNAME"
4646- if [ -n "$HTTP_BODY" ]; then
4747- echo "Response: $HTTP_BODY"
4848- fi
4949-else
5050- echo "❌ Failed with status $HTTP_CODE" >&2
5151- if [ -n "$HTTP_BODY" ]; then
5252- echo "Response: $HTTP_BODY" >&2
5353- fi
5454- exit 1
5555-fi
+4-10
docker-compose.yml
···1010 # Optional: Load from .env.appview file (create from .env.appview.example)
1111 # env_file:
1212 # - .env.appview
1313+ # Base config: config-appview.example.yaml (passed via Air entrypoint)
1414+ # Env vars below override config file values for local dev
1315 environment:
1416 # ATCR_SERVER_CLIENT_NAME: "Seamark"
1517 # ATCR_SERVER_CLIENT_SHORT_NAME: "Seamark"
1616- # Server configuration
1717- ATCR_SERVER_ADDR: :5000
1818 ATCR_SERVER_DEFAULT_HOLD_DID: did:web:172.28.0.3:8080
1919- ATCR_JETSTREAM_BACKFILL_ENABLED: "true"
2020- # Test mode - fallback to default hold when user's hold is unreachable
2119 ATCR_SERVER_TEST_MODE: "true"
2222- # Logging
2320 ATCR_LOG_LEVEL: debug
2424- # Log shipping (uncomment to enable)
2521 LOG_SHIPPER_BACKEND: victoria
2622 LOG_SHIPPER_URL: http://172.28.0.10:9428
2723 # Limit local Docker logs - real logs go to Victoria Logs
···5349 atcr-hold:
5450 env_file:
5551 - ../atcr-secrets.env # Load S3/Storj credentials from external file
5252+ # Base config: config-hold.example.yaml (passed via Air entrypoint)
5353+ # Env vars below override config file values for local dev
5654 environment:
5757- HOLD_ADMIN_ENABLED: true
5855 HOLD_SERVER_PUBLIC_URL: http://172.28.0.3:8080
5956 HOLD_REGISTRATION_OWNER_DID: did:plc:pddp4xt5lgnv2qsegbzzs4xg
6060- HOLD_SERVER_PUBLIC: false
6157 HOLD_REGISTRATION_ALLOW_ALL_CREW: true
6258 HOLD_SERVER_TEST_MODE: true
6359 # Stripe billing (only used with -tags billing)
6460 STRIPE_SECRET_KEY: sk_test_
6561 STRIPE_PUBLISHABLE_KEY: pk_test_
6662 STRIPE_WEBHOOK_SECRET: whsec_
6767- # Logging
6863 HOLD_LOG_LEVEL: debug
6969- # Log shipping (uncomment to enable)
7064 LOG_SHIPPER_BACKEND: victoria
7165 LOG_SHIPPER_URL: http://172.28.0.10:9428
7266 # S3 storage config comes from env_file (AWS_*, S3_*)
+1-1
pkg/appview/config.go
···181181182182 // Legal defaults
183183 v.SetDefault("legal.company_name", "")
184184- v.SetDefault("legal.jurisdiction", "State of Texas, United States")
184184+ v.SetDefault("legal.jurisdiction", "")
185185186186 // Log formatter (used by distribution config, not in Config struct)
187187 v.SetDefault("log_formatter", "text")