Cloud 배포
함께 보기: profile, build, configuration, troubleshooting을 포함한 전체 Docker reference는 Docker Guide를 참고하세요.
Archon을 24/7 운영하기 위해 cloud VPS에 배포합니다. Caddy를 사용해 HTTPS certificate을 자동으로 발급하고 갱신하며, 서비스가 계속 실행되도록 구성합니다. HarnessLab은 Archon fork이므로 같은 배포 절차를 그대로 사용할 수 있습니다.
목차: 사전 준비 | Server 설정 | DNS 설정 | Repository 설정 | Environment 설정 | Database migration | Caddy 설정 | Service 시작 | 확인
필수:
- Cloud VPS 계정(DigitalOcean, Linode, AWS EC2, Vultr 등)
- domain name 또는 subdomain(예:
archon.yourdomain.com) - 로컬 머신에 설치된 SSH client
- 기본적인 command-line 사용 경험
권장 사양:
- CPU: 1-2 vCPUs
- RAM: 최소 2GB(4GB 권장)
- Storage: 20GB SSD
- OS: Ubuntu 22.04 LTS
SSH Key 생성(필수)
Section titled “SSH Key 생성(필수)”VPS를 만들기 전에, 로컬 머신에서 SSH key pair를 생성합니다.
# Generate SSH key (ed25519 recommended)ssh-keygen -t ed25519 -C "archon"
# When prompted:# - File location: Press Enter (uses default ~/.ssh/id_ed25519)# - Passphrase: Optional but recommended
# View your public key (you'll need this for VPS setup)cat ~/.ssh/id_ed25519.pub# Windows: type %USERPROFILE%\.ssh\id_ed25519.pub출력된 public key를 복사해 둡니다. VPS 생성 과정에서 이 값을 추가합니다.
1. Server 프로비저닝 및 초기 설정
Section titled “1. Server 프로비저닝 및 초기 설정”VPS Instance 생성 예시
Section titled “VPS Instance 생성 예시”DigitalOcean Droplet
- DigitalOcean에 로그인합니다.
- “Create” -> “Droplets”를 클릭합니다.
- 다음을 선택합니다.
- Image: Ubuntu 22.04 LTS
- Plan: Basic($12/month - 2GB RAM 권장)
- Datacenter: 사용자와 가장 가까운 위치
- Authentication: SSH keys -> “New SSH Key” -> 사전 준비 단계에서 복사한 public key 붙여넣기
- “Create Droplet”을 클릭합니다.
- public IP address를 기록해 둡니다.
AWS EC2 Instance
- AWS Console에 로그인합니다.
- EC2 -> Launch Instance로 이동합니다.
- 다음을 선택합니다.
- AMI: Ubuntu Server 22.04 LTS
- Instance Type: t3.small(2GB RAM)
- Key Pair: “Create new key pair” 또는 사전 준비 단계에서 만든 public key import
- Security Group: SSH(22), HTTP(80), HTTPS(443) 허용
- instance를 launch합니다.
- public IP address를 기록해 둡니다.
Linode Instance
- Linode에 로그인합니다.
- “Create” -> “Linode”를 클릭합니다.
- 다음을 선택합니다.
- Image: Ubuntu 22.04 LTS
- Region: 사용자와 가장 가까운 위치
- Plan: Nanode 2GB($12/month)
- SSH Keys: 사전 준비 단계에서 복사한 public key 추가
- Root Password: 강한 password 설정(backup access용)
- “Create Linode”를 클릭합니다.
- public IP address를 기록해 둡니다.
초기 Server 설정
Section titled “초기 Server 설정”server에 접속합니다.
# Replace with your server IP (uses SSH key from Prerequisites)ssh -i ~/.ssh/id_ed25519 root@your-server-ipdeployment user를 생성합니다.
# Create user with sudo privilegesadduser deployusermod -aG sudo deploy
# Copy root's SSH authorized keys to deploy usermkdir -p /home/deploy/.sshcp /root/.ssh/authorized_keys /home/deploy/.ssh/chown -R deploy:deploy /home/deploy/.sshchmod 700 /home/deploy/.sshchmod 600 /home/deploy/.ssh/authorized_keys
# Test connection in a new terminal before proceeding:# ssh -i ~/.ssh/id_ed25519 deploy@your-server-ip보안을 위해 password authentication을 비활성화합니다.
# Edit SSH confignano /etc/ssh/sshd_config다음 항목을 찾아 변경합니다.
PasswordAuthentication no변경 후 Nano에서 나오려면
Ctrl + X->Y->Enter를 누릅니다.
SSH를 restart합니다.
systemctl restart ssh
# Switch to deploy user for remaining stepssu - deployfirewall을 설정합니다.
# Allow SSH, HTTP, HTTPS (including HTTP/3)sudo ufw allow 22/tcpsudo ufw allow 80/tcpsudo ufw allow 443
# Enable firewallsudo ufw --force enable
# Check statussudo ufw statusDependency 설치
Section titled “Dependency 설치”Docker를 설치합니다.
# Install Dockercurl -fsSL https://get.docker.com -o get-docker.shsudo sh get-docker.sh
# Add deploy user to docker groupsudo usermod -aG docker deploy
# Log out and back in for group changes to take effectexitssh -i ~/.ssh/id_ed25519 deploy@your-server-ipDocker Compose, Git, PostgreSQL Client를 설치합니다.
# Update package listsudo apt update
# Install required packagessudo apt install -y docker-compose-plugin git postgresql-client
# Verify installationsdocker --versiondocker compose versiongit --versionpsql --version2. DNS 설정
Section titled “2. DNS 설정”domain을 server의 IP address로 연결합니다.
A Record 설정:
- domain registrar 또는 DNS provider(Cloudflare, Namecheap 등)로 이동합니다.
- A Record를 만듭니다.
- Name:
archon(archon.yourdomain.com용) 또는@(yourdomain.com용) - Value: server의 public IP address
- TTL: 300(5분) 또는 기본값
- Name:
예시(Cloudflare):
Type: AName: archonContent: 123.45.67.89Proxy: Off (DNS Only)TTL: Auto3. Repository clone
Section titled “3. Repository clone”server에서 실행합니다.
# Create application directorysudo mkdir -p /opt/archonsudo chown deploy:deploy /opt/archon
# Clone repository into the directorycd /opt/archongit clone https://github.com/coleam00/Archon .4. Environment 설정
Section titled “4. Environment 설정”Environment file 생성
Section titled “Environment file 생성”# Copy example filecp .env.example .env
# Edit with nanonano .env4.1 Core 설정
Section titled “4.1 Core 설정”필수 variable을 설정합니다.
# Database - Use remote managed PostgreSQLDATABASE_URL=postgresql://user:password@host:5432/dbname
# GitHub tokens (same value for both)GH_TOKEN=ghp_your_token_hereGITHUB_TOKEN=ghp_your_token_here
# Server settingsPORT=3090ARCHON_HOME=/tmp/archon # Override base directory (optional)GitHub Token 설정:
- GitHub Settings > Tokens에 방문합니다.
- “Generate new token (classic)“을 클릭합니다.
- scope로 **
repo**를 선택합니다. - token을 복사합니다(
ghp_...로 시작). .env에GH_TOKEN과GITHUB_TOKEN을 모두 설정합니다.
Database 옵션:
참고: SQLite는 로컬 개발의 기본값이며 별도 설정이 필요 없습니다. Cloud 배포에서는 안정성과 network 접근성을 위해 PostgreSQL을 권장합니다.
Cloud 권장: Remote Managed PostgreSQL
backup과 scaling이 쉬운 managed database service를 사용합니다.
Supabase(무료 tier 제공):
- supabase.com에서 project를 생성합니다.
- Settings -> Database로 이동합니다.
- connection string을 복사합니다(Transaction pooler 권장).
DATABASE_URL로 설정합니다.
Neon:
- neon.tech에서 project를 생성합니다.
- dashboard에서 connection string을 복사합니다.
DATABASE_URL로 설정합니다.
대안: Local PostgreSQL(with-db profile)
app과 함께 Docker에서 PostgreSQL을 실행하려면 다음 값을 사용합니다.
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/remote_coding_agentservice를 시작할 때 with-db profile을 사용합니다(Section 7 참고).
4.2 AI Assistant 설정
Section titled “4.2 AI Assistant 설정”AI assistant를 최소 1개 설정합니다.
Claude Code
로컬 머신에서:
# Install Claude Code CLI (if not already installed)# Visit: https://docs.claude.com/claude-code/installation
# Generate OAuth tokenclaude setup-token
# Copy the token (starts with sk-ant-oat01-...)server에서:
nano .env다음을 추가합니다.
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-xxxxx대안: API Key
pay-per-use 방식을 선호한다면:
- console.anthropic.com/settings/keys에 방문합니다.
- key를 생성합니다(
sk-ant-로 시작). .env에 설정합니다.
CLAUDE_API_KEY=sk-ant-xxxxx기본값으로 설정(선택):
DEFAULT_AI_ASSISTANT=claudeCodex
로컬 머신에서:
# Install Codex CLI (if not already installed)# Visit: https://docs.codex.com/installation
# Authenticatecodex login
# Extract credentialscat ~/.codex/auth.json# On Windows: type %USERPROFILE%\.codex\auth.json
# Copy all four valuesserver에서:
nano .env네 가지 credential을 모두 추가합니다.
CODEX_ID_TOKEN=eyJhbGc...CODEX_ACCESS_TOKEN=eyJhbGc...CODEX_REFRESH_TOKEN=rt_...CODEX_ACCOUNT_ID=6a6a7ba6-...기본값으로 설정(선택):
DEFAULT_AI_ASSISTANT=codex4.3 Platform Adapter 설정
Section titled “4.3 Platform Adapter 설정”platform을 최소 1개 설정합니다.
Telegram
bot 생성:
- Telegram에서 @BotFather에게 message를 보냅니다.
/newbot을 보내고 안내를 따릅니다.- bot token을 복사합니다(format:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz).
server에서:
nano .env다음을 추가합니다.
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHI...TELEGRAM_STREAMING_MODE=stream # stream (default) | batchGitHub Webhooks
이 설정은 deployment 이후에 진행합니다. 먼저 public URL이 필요합니다.
지금은 webhook secret만 생성합니다.
# Generate secretopenssl rand -hex 32
# Copy the output.env에 추가합니다.
WEBHOOK_SECRET=your_generated_secret_hereGitHub webhook 설정은 service가 실행된 뒤 Section 9에서 진행합니다.
Nano 저장 및 종료: Ctrl+X, Y, Enter
5. Database migration
Section titled “5. Database migration”중요: application을 시작하기 전에 실행합니다.
필수 table을 포함한 database schema를 초기화합니다.
# For remote database (Supabase, Neon, etc.)psql $DATABASE_URL < migrations/000_combined.sql
# Verify tables were createdpsql $DATABASE_URL -c "\dt"# Should show: codebases, conversations, sessions, isolation_environments,# workflow_runs, workflow_events, messageslocal PostgreSQL을 with-db profile로 사용하는 경우:
Section 7에서 database를 시작한 뒤 migration을 실행합니다.
6. Caddy 설정
Section titled “6. Caddy 설정”Caddy는 Let’s Encrypt certificate을 사용해 HTTPS를 자동으로 제공합니다.
Caddyfile 생성
Section titled “Caddyfile 생성”# Copy the example — no manual editing neededcp Caddyfile.example CaddyfileCaddyfile은 .env에서 {$DOMAIN}과 {$PORT}를 자동으로 읽습니다. DOMAIN이 설정되어 있는지 확인합니다.
DOMAIN=archon.yourdomain.comCaddy 동작 방식
Section titled “Caddy 동작 방식”- Let’s Encrypt에서 SSL certificate을 자동으로 발급합니다.
- HTTPS(443)와 HTTP(80) -> HTTPS redirect를 처리합니다.
- request를 port 3090의 app container로 proxy합니다.
- certificate을 자동으로 갱신합니다.
7. Service 시작
Section titled “7. Service 시작”Workspace permission 설정(Linux 전용)
Section titled “Workspace permission 설정(Linux 전용)”# Create workspace directory and set permissions for container user (UID 1001)mkdir -p workspacesudo chown -R 1001:1001 workspaceOption A: Remote PostgreSQL 사용(권장)
Section titled “Option A: Remote PostgreSQL 사용(권장)”managed database를 사용하는 경우:
# Start app with Caddy reverse proxydocker compose --profile cloud up -d --build
# View logsdocker compose --profile cloud logs -f appOption B: Local PostgreSQL 사용
Section titled “Option B: Local PostgreSQL 사용”with-db profile을 사용하는 경우:
# Start app, postgres, and Caddydocker compose --profile with-db --profile cloud up -d --build
# View logsdocker compose --profile with-db --profile cloud logs -f appdocker compose --profile with-db --profile cloud logs -f postgresStartup 모니터링
Section titled “Startup 모니터링”# Watch logs for successful startup (use --profile with-db for local PostgreSQL)docker compose --profile cloud logs -f app
# Look for:# [App] Starting Archon# [Database] Connected successfully# [App] Archon is ready!log 화면을 종료하려면 Ctrl+C를 누릅니다(service는 계속 실행됩니다).
8. Deployment 확인
Section titled “8. Deployment 확인”Health endpoint 확인
Section titled “Health endpoint 확인”로컬 머신에서:
# Basic health checkcurl https://archon.yourdomain.com/api/health# Expected: {"status":"ok"}
# Database connectivitycurl https://archon.yourdomain.com/api/health/db# Expected: {"status":"ok","database":"connected"}
# Concurrency statuscurl https://archon.yourdomain.com/api/health/concurrency# Expected: {"status":"ok","active":0,"queued":0,"maxConcurrent":10}SSL Certificate 확인
Section titled “SSL Certificate 확인”browser에서 https://archon.yourdomain.com/api/health에 방문합니다.
- green padlock이 표시되어야 합니다.
- certificate issuer가 “Let’s Encrypt”여야 합니다.
- HTTP에서 HTTPS로 자동 redirect되어야 합니다.
Telegram 확인(설정한 경우)
Section titled “Telegram 확인(설정한 경우)”Telegram에서 bot에게 message를 보냅니다.
/help사용 가능한 command와 함께 bot response를 받아야 합니다.
9. GitHub Webhook 설정
Section titled “9. GitHub Webhook 설정”app에 public URL이 생겼으므로 GitHub webhook을 설정합니다.
Webhook Secret 생성(앞에서 하지 않은 경우)
Section titled “Webhook Secret 생성(앞에서 하지 않은 경우)”# On serveropenssl rand -hex 32
# Copy output to .env as WEBHOOK_SECRET if not already setRepository에 Webhook 추가
Section titled “Repository에 Webhook 추가”https://github.com/owner/repo/settings/hooks로 이동합니다.- “Add webhook”을 클릭합니다.
Webhook 설정:
| Field | Value |
|---|---|
| Payload URL | https://archon.yourdomain.com/webhooks/github |
| Content type | application/json |
| Secret | .env의 WEBHOOK_SECRET |
| SSL verification | SSL verification 활성화 |
| Events | individual events 선택: Issues, Issue comments, Pull requests |
- “Add webhook”을 클릭합니다.
- “Recent Deliveries” tab에서 성공한 delivery(green checkmark)를 확인합니다.
Webhook 테스트:
issue에 comment를 남깁니다.
@your-bot-name can you analyze this issue?bot이 analysis로 응답해야 합니다.
10. Maintenance 및 운영
Section titled “10. Maintenance 및 운영”Log 보기
Section titled “Log 보기”# All servicesdocker compose --profile cloud logs -f
# Specific servicedocker compose --profile cloud logs -f appdocker compose --profile cloud logs -f caddy
# Last 100 linesdocker compose --profile cloud logs --tail=100 appApplication 업데이트
Section titled “Application 업데이트”# Pull latest changescd /opt/archongit pull
# Rebuild and restartdocker compose --profile cloud up -d --build
# Check logsdocker compose --profile cloud logs -f appService restart
Section titled “Service restart”# Restart all servicesdocker compose --profile cloud restart
# Restart specific servicedocker compose --profile cloud restart appdocker compose --profile cloud restart caddyService 중지
Section titled “Service 중지”# Stop all servicesdocker compose --profile cloud down
# Stop and remove volumes (caution: deletes data)docker compose --profile cloud down -vCaddy가 SSL Certificate을 받지 못함
Section titled “Caddy가 SSL Certificate을 받지 못함”DNS 확인:
dig archon.yourdomain.com# Should return your server IPfirewall 확인:
sudo ufw status# Should allow ports 80 and 443Caddy log 확인:
docker compose --profile cloud logs caddy# Look for certificate issuance attempts흔한 원인:
- DNS가 아직 전파되지 않음(5-60분 대기)
- firewall이 80/443 port를 차단
- Caddyfile의 domain typo
- A record가 올바른 IP를 가리키지 않음
App이 응답하지 않음
Section titled “App이 응답하지 않음”실행 중인지 확인:
docker compose --profile cloud ps# Should show 'app' and 'caddy' with state 'Up'health endpoint 확인:
curl http://localhost:3000/api/health# Tests app directly (bypasses Caddy)log 확인:
docker compose --profile cloud logs -f appDatabase connection error
Section titled “Database connection error”remote database의 경우:
# Test connection from serverpsql $DATABASE_URL -c "SELECT 1"environment variable 확인:
cat .env | grep DATABASE_URLtable이 없으면 migration 실행:
psql $DATABASE_URL < migrations/000_combined.sqlGitHub Webhook이 동작하지 않음
Section titled “GitHub Webhook이 동작하지 않음”webhook delivery 확인:
- GitHub의 webhook settings로 이동합니다.
- “Recent Deliveries”를 클릭합니다.
- error message를 확인합니다.
webhook secret 확인:
cat .env | grep WEBHOOK_SECRET# Must match GitHub webhook configurationwebhook endpoint 테스트:
curl https://archon.yourdomain.com/webhooks/github# Should return 400 (missing signature) - means endpoint is reachableDisk space 부족
Section titled “Disk space 부족”disk usage 확인:
df -hdocker system dfDocker 정리:
# Remove unused images and containersdocker system prune -a
# Remove unused volumes (caution)docker volume prune