Skip to content

Commit 5b79ca6

Browse files
leex279Wirasm
authored andcommitted
deploy: harden cloud-init with archon user, swap, and fixes (#981)
* deploy: harden cloud-init with archon user, swap, and fixes - Create dedicated 'archon' user (sudo + docker groups, passwordless sudo, locked password) and copy SSH authorized_keys from default cloud user (with root fallback) so login works immediately. - Run docker pulls and the image build as the archon user via sudo -u. - Add 2GB swapfile to prevent OOM during docker build on small VPS (<2GB RAM). - Remove package_upgrade to speed up boot and avoid surprise kernel updates. - Drop redundant systemctl enable/start docker (get.docker.com handles it). - ufw allow 443/tcp for consistency with 22/80. - set -e before clone for fail-fast on network errors. - Update docs link to https://archon.diy/deployment/docker/. - SETUP_COMPLETE now instructs ssh archon@<server-ip>. - Header lists supported providers (incl. Hostinger) and notes the archon user + swap behavior. * deploy: address PR review feedback on cloud-init - Fix set -e regression: merge clone/cp/chown into single shell block so fail-fast actually applies (CodeRabbit). - Drop passwordless sudo from archon user — docker group only. Removes trivial privilege escalation path (Wirasm). - Remove non-existent 'docker' group from initial users.groups list; it is added via usermod later (CodeRabbit). - Restore package_upgrade: true to patch CVEs in the base image before anything else runs (Wirasm). - Add ufw allow 443/udp for HTTP/3 QUIC — Caddy exposes 443:443/udp in docker-compose (CodeRabbit). - Update SETUP_COMPLETE and header comment to note archon user has no sudo (use default cloud user / root for maintenance).
1 parent e778994 commit 5b79ca6

1 file changed

Lines changed: 72 additions & 18 deletions

File tree

deploy/cloud-init.yml

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,30 @@
66
#
77
# Paste this into your VPS provider's "User Data" field when creating a server.
88
# Tested on: Ubuntu 22.04+, Debian 12+
9+
# Works with any cloud-init compatible provider (DigitalOcean, Hetzner, Linode,
10+
# Vultr, AWS EC2, Hostinger, etc.)
911
#
1012
# What this does:
1113
# 1. Installs Docker + Docker Compose plugin
1214
# 2. Opens firewall ports (SSH, HTTP, HTTPS)
13-
# 3. Clones the repo to /opt/archon
14-
# 4. Prepares .env and Caddyfile from examples
15-
# 5. Builds the Docker image (~5 min)
15+
# 3. Creates a 2GB swapfile (helps small VPS builds avoid OOM)
16+
# 4. Clones the repo to /opt/archon
17+
# 5. Prepares .env and Caddyfile from examples
18+
# 6. Creates a dedicated 'archon' user (docker group only, no sudo)
19+
# 7. Builds the Docker image (~5 min) as the archon user
1620
#
17-
# After the server boots (~5-8 min), SSH in and:
21+
# Note: On VPS with <2GB RAM, the docker build step can OOM without swap.
22+
# Note: The 'archon' user has docker access but NOT sudo. For administrative
23+
# tasks (updates, reboots), use the default cloud user or root.
24+
#
25+
# After the server boots (~5-8 min), SSH in as the archon user:
26+
# ssh archon@your-server-ip
1827
# 1. Edit /opt/archon/.env — set your AI credentials, DOMAIN, DATABASE_URL
1928
# 2. cd /opt/archon && docker compose --profile with-db --profile cloud up -d
2029
# 3. Open https://your-domain.com
2130
#
2231
# IMPORTANT: Before starting, point your domain's DNS A record to this server's IP.
32+
# SSH keys from the default cloud user are copied to 'archon'.
2333
#
2434

2535
package_update: true
@@ -30,29 +40,66 @@ packages:
3040
- git
3141
- ufw
3242

43+
users:
44+
- default
45+
- name: archon
46+
gecos: Archon Service User
47+
shell: /bin/bash
48+
lock_passwd: true
49+
3350
runcmd:
51+
# --- Swap (helps small VPS avoid OOM during docker build) ---
52+
- |
53+
if [ ! -f /swapfile ]; then
54+
fallocate -l 2G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=2048
55+
chmod 600 /swapfile
56+
mkswap /swapfile
57+
swapon /swapfile
58+
echo '/swapfile none swap sw 0 0' >> /etc/fstab
59+
fi
60+
3461
# --- Docker ---
3562
- curl -fsSL https://get.docker.com | sh
36-
- systemctl enable docker
37-
- systemctl start docker
63+
- usermod -aG docker archon
3864

39-
# --- Firewall ---
65+
# --- Copy SSH keys from default user to archon (so login works immediately) ---
66+
- |
67+
DEFAULT_USER=$(getent passwd 1000 | cut -d: -f1)
68+
if [ -n "$DEFAULT_USER" ] && [ -f /home/$DEFAULT_USER/.ssh/authorized_keys ]; then
69+
mkdir -p /home/archon/.ssh
70+
cp /home/$DEFAULT_USER/.ssh/authorized_keys /home/archon/.ssh/authorized_keys
71+
chmod 700 /home/archon/.ssh
72+
chmod 600 /home/archon/.ssh/authorized_keys
73+
chown -R archon:archon /home/archon/.ssh
74+
elif [ -f /root/.ssh/authorized_keys ]; then
75+
mkdir -p /home/archon/.ssh
76+
cp /root/.ssh/authorized_keys /home/archon/.ssh/authorized_keys
77+
chmod 700 /home/archon/.ssh
78+
chmod 600 /home/archon/.ssh/authorized_keys
79+
chown -R archon:archon /home/archon/.ssh
80+
fi
81+
82+
# --- Firewall (443/udp needed for HTTP/3 QUIC via Caddy) ---
4083
- ufw allow 22/tcp
4184
- ufw allow 80/tcp
42-
- ufw allow 443
85+
- ufw allow 443/tcp
86+
- ufw allow 443/udp
4387
- ufw --force enable
4488

45-
# --- Clone and configure ---
46-
- git clone https://github.com/coleam00/Archon.git /opt/archon
47-
- cp /opt/archon/.env.example /opt/archon/.env
48-
- cp /opt/archon/Caddyfile.example /opt/archon/Caddyfile
89+
# --- Clone and configure (fail fast — single shell so set -e applies) ---
90+
- |
91+
set -e
92+
git clone https://github.com/coleam00/Archon.git /opt/archon
93+
cp /opt/archon/.env.example /opt/archon/.env
94+
cp /opt/archon/Caddyfile.example /opt/archon/Caddyfile
95+
chown -R archon:archon /opt/archon
4996
50-
# --- Pre-pull external images ---
51-
- docker pull postgres:17-alpine
52-
- docker pull caddy:2-alpine
97+
# --- Pre-pull external images (as archon, via docker group) ---
98+
- sudo -u archon docker pull postgres:17-alpine
99+
- sudo -u archon docker pull caddy:2-alpine
53100

54-
# --- Build the app image ---
55-
- cd /opt/archon && docker compose build
101+
# --- Build the app image as archon ---
102+
- sudo -u archon -H bash -c 'cd /opt/archon && docker compose build'
56103

57104
# --- Signal completion ---
58105
- |
@@ -61,6 +108,13 @@ runcmd:
61108
Archon server setup complete!
62109
============================================
63110
111+
Log in as the 'archon' user (not root):
112+
ssh archon@<server-ip>
113+
114+
Note: the 'archon' user has docker access but no sudo. For system
115+
maintenance (apt upgrade, reboots), log in as the default cloud user
116+
or root.
117+
64118
Next steps:
65119
66120
1. Edit credentials and domain:
@@ -85,7 +139,7 @@ runcmd:
85139
86140
Logs: docker compose logs -f
87141
Health: curl https://your-domain.com/api/health
88-
Docs: https://github.com/coleam00/Archon/blob/main/docs/docker.md
142+
Docs: https://archon.diy/deployment/docker/
89143
============================================
90144
DONE
91145
- echo "[archon] Setup complete. Edit /opt/archon/.env and run docker compose up."

0 commit comments

Comments
 (0)