Skip to main content

max / makenotwork

4.5 KB · 146 lines History Blame Raw
1 #!/bin/bash
2 # Multithreaded Deployment Script — Hetzner (alpha-west-1)
3 # Cross-compiles for x86_64 Linux on macOS, uploads, restarts.
4 # Run from the multithreaded project root.
5 #
6 # Usage:
7 # ./deploy/deploy-hetzner.sh # Build + deploy + restart
8 # ./deploy/deploy-hetzner.sh --setup # First-time: create user, dirs, db, build, install, seed
9 # ./deploy/deploy-hetzner.sh --config # Config only (Caddyfile, systemd, static, env)
10 #
11 # Prerequisites (one-time):
12 # brew install zig
13 # cargo install cargo-zigbuild
14 # rustup target add x86_64-unknown-linux-gnu
15
16 set -e
17
18 # Configuration
19 SERVER="root@100.120.174.96"
20 REMOTE_DIR="/opt/multithreaded"
21 BINARY_NAME="multithreaded"
22 TARGET="x86_64-unknown-linux-gnu"
23 DEPLOY_DIR="deploy"
24
25 # Check we're in the right directory
26 if [ ! -f "Cargo.toml" ] || ! grep -q 'name = "multithreaded"' Cargo.toml; then
27 echo "Error: Run this script from the MNW/multithreaded/ directory"
28 exit 1
29 fi
30
31 build_binary() {
32 echo "[build] Cross-compiling for $TARGET..."
33 ulimit -n 65536 2>/dev/null || true
34 cargo zigbuild --release --target $TARGET
35 echo "[build] Done: target/$TARGET/release/$BINARY_NAME"
36 }
37
38 upload_config() {
39 echo "[config] Uploading configuration files..."
40
41 # Systemd service
42 scp $DEPLOY_DIR/multithreaded.service $SERVER:/etc/systemd/system/multithreaded.service
43
44 # Static assets
45 echo "[config] Uploading static assets..."
46 ssh $SERVER "mkdir -p $REMOTE_DIR/static $REMOTE_DIR/migrations"
47 rsync -az --delete static/ $SERVER:$REMOTE_DIR/static/
48 rsync -az --delete migrations/ $SERVER:$REMOTE_DIR/migrations/
49
50 # Fix ownership
51 ssh $SERVER "chown -R multithreaded:multithreaded $REMOTE_DIR"
52
53 # Reload systemd
54 ssh $SERVER "systemctl daemon-reload"
55 echo "[config] Done"
56 }
57
58 upload_binary() {
59 echo "[upload] Stopping service and uploading binary..."
60 ssh $SERVER "systemctl stop multithreaded || true"
61 scp target/$TARGET/release/$BINARY_NAME $SERVER:$REMOTE_DIR/$BINARY_NAME
62 ssh $SERVER "chmod +x $REMOTE_DIR/$BINARY_NAME && chown multithreaded:multithreaded $REMOTE_DIR/$BINARY_NAME"
63 echo "[upload] Done"
64 }
65
66 restart_app() {
67 echo "[restart] Restarting multithreaded..."
68 ssh $SERVER "systemctl restart multithreaded"
69 sleep 2
70 echo ""
71 ssh $SERVER "systemctl status multithreaded --no-pager"
72 echo ""
73 echo "[health] Checking..."
74 ssh $SERVER "curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:3400/"
75 }
76
77 first_time_setup() {
78 echo "=== First-Time Setup (Hetzner) ==="
79
80 echo "[setup] Creating system user..."
81 ssh $SERVER "
82 useradd --system --shell /usr/sbin/nologin --home-dir $REMOTE_DIR multithreaded 2>/dev/null || echo 'User already exists'
83 "
84
85 echo "[setup] Creating directories..."
86 ssh $SERVER "
87 mkdir -p $REMOTE_DIR
88 chown multithreaded:multithreaded $REMOTE_DIR
89 "
90
91 echo "[setup] Creating database role + database..."
92 ssh $SERVER "
93 sudo -u postgres createuser multithreaded 2>/dev/null || echo 'Role already exists'
94 sudo -u postgres createdb -O multithreaded multithreaded 2>/dev/null || echo 'Database already exists'
95 sudo -u postgres psql -c 'GRANT ALL PRIVILEGES ON DATABASE multithreaded TO multithreaded;' 2>/dev/null
96 sudo -u postgres psql -d multithreaded -c 'GRANT ALL ON SCHEMA public TO multithreaded;' 2>/dev/null
97 "
98
99 build_binary
100 upload_config
101
102 echo "[setup] Installing binary..."
103 upload_binary
104
105 echo "[setup] Installing env file..."
106 scp $DEPLOY_DIR/env.hetzner $SERVER:$REMOTE_DIR/.env
107 ssh $SERVER "chmod 600 $REMOTE_DIR/.env && chown multithreaded:multithreaded $REMOTE_DIR/.env"
108
109 echo "[setup] Enabling and starting service..."
110 ssh $SERVER "systemctl enable multithreaded && systemctl start multithreaded"
111 sleep 2
112
113 echo "[setup] Running seed..."
114 ssh $SERVER "cd $REMOTE_DIR && sudo -u multithreaded $REMOTE_DIR/$BINARY_NAME --seed"
115
116 echo ""
117 ssh $SERVER "systemctl status multithreaded --no-pager"
118 echo ""
119 echo "[health] Checking..."
120 ssh $SERVER "curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:3400/"
121 }
122
123 case "${1:-deploy}" in
124 --setup)
125 first_time_setup
126 ;;
127 --config)
128 echo "=== Config Deploy (Hetzner) ==="
129 upload_config
130 ;;
131 deploy|"")
132 echo "=== Deploy (Hetzner) ==="
133 build_binary
134 upload_config
135 upload_binary
136 restart_app
137 ;;
138 *)
139 echo "Usage: $0 [--setup|--config]"
140 exit 1
141 ;;
142 esac
143
144 echo ""
145 echo "=== Done ==="
146