Last active 1 month ago

forgejo runner install script

Revision fac46b4cedd218682d4150cac93d5ed7e7371a24

forgejo-actions-guide-docker.txt Raw
1#!/bin/bash
2# =============================================================================
3# FORGEJO RUNNER - FULL SYSTEM DEPLOYMENT WITH SYSTEMD
4# Supports both DIRECT and DOCKER modes
5# =============================================================================
6
7# --- CONFIGURATION VARIABLES ---
8FORGEJO_URL="http://192.168.2.76:3006" # CHANGE THIS
9REGISTRATION_TOKEN="your-registration-token" # CHANGE THIS
10RUNNER_NAME="selfhosted-runner-01"
11RUNNER_VERSION="latest" # Can be "latest" or specific like "v3.4.1"
12RUNNER_MODE="direct" # "direct" or "docker"
13
14# Direct mode variables - using current user
15RUNNER_HOME="/opt/forgejo-runner"
16
17# Docker mode variables
18COMPOSE_DIR="$HOME/forgejo-runner"
19DIND_IMAGE="docker:dind"
20RUNNER_IMAGE="data.forgejo.org/forgejo/runner"
21# =============================================================================
22
23set -e
24
25echo "============================================================"
26echo "FORGEJO RUNNER DEPLOYMENT"
27echo "============================================================"
28echo "Mode: $RUNNER_MODE"
29echo "Version: $RUNNER_VERSION"
30echo "Instance: $FORGEJO_URL"
31echo ""
32
33# --- STEP 1: Detect system architecture ---
34ARCH=$(uname -m)
35case $ARCH in
36 x86_64)
37 ARCH="amd64"
38 ;;
39 aarch64|arm64)
40 ARCH="arm64"
41 ;;
42 armv7l|armhf)
43 ARCH="armv7"
44 ;;
45 *)
46 echo "Unsupported architecture: $ARCH"
47 exit 1
48 ;;
49esac
50echo "Detected architecture: $ARCH"
51
52# --- STEP 2: Get actual version if "latest" ---
53if [ "$RUNNER_VERSION" = "latest" ]; then
54 echo "Fetching latest Forgejo Runner version..."
55
56 # Try multiple sources specifically for Forgejo Runner
57 LATEST_VERSION=""
58
59 # Try 1: Official Forgejo API
60 if [ -z "$LATEST_VERSION" ]; then
61 echo "Trying Forgejo API..."
62 LATEST_VERSION=$(curl -s -m 10 https://code.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | \
63 grep -o '"tag_name":"v[0-9]\+\.[0-9]\+\.[0-9]\+"' | \
64 head -1 | sed 's/"tag_name":"//' | sed 's/"//' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$')
65 fi
66
67 # Try 2: GitHub API (mirror)
68 if [ -z "$LATEST_VERSION" ]; then
69 echo "Trying GitHub API..."
70 LATEST_VERSION=$(curl -s -m 10 https://api.github.com/repos/forgejo/runner/releases/latest | \
71 grep -o '"tag_name":"v[0-9]\+\.[0-9]\+\.[0-9]\+"' | \
72 head -1 | sed 's/"tag_name":"//' | sed 's/"//' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$')
73 fi
74
75 # Try 3: Direct HTML parsing with more specific pattern
76 if [ -z "$LATEST_VERSION" ]; then
77 echo "Trying HTML parsing..."
78 LATEST_VERSION=$(curl -s -m 10 https://code.forgejo.org/forgejo/runner/releases | \
79 grep -o 'forgejo-runner-[0-9]\+\.[0-9]\+\.[0-9]\+-linux' | \
80 head -1 | sed 's/forgejo-runner-//' | sed 's/-linux//' | sed 's/^/v/')
81 fi
82
83 # Try 4: Direct download page
84 if [ -z "$LATEST_VERSION" ]; then
85 echo "Trying releases page..."
86 LATEST_VERSION=$(curl -s -m 10 https://code.forgejo.org/forgejo/runner/releases/ | \
87 grep -E 'href="/forgejo/runner/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+"' | \
88 head -1 | sed 's/.*tag\/v/v/' | sed 's/".*//')
89 fi
90
91 # Fallback to hardcoded version
92 if [ -z "$LATEST_VERSION" ] || [[ ! "$LATEST_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
93 echo "Failed to fetch valid version, using fallback v3.4.1"
94 LATEST_VERSION="v3.4.1"
95 fi
96
97 RUNNER_VERSION="$LATEST_VERSION"
98fi
99echo "Using version: $RUNNER_VERSION"
100echo ""
101
102# =============================================================================
103# DIRECT MODE INSTALLATION
104# =============================================================================
105if [ "$RUNNER_MODE" = "direct" ]; then
106 echo "=== DIRECT MODE INSTALLATION ==="
107 echo "Installing runner directly on the system (no Docker required)"
108 echo "Using current user: $USER"
109 echo ""
110
111 # --- Create directory ---
112 echo "Creating runner directory..."
113 sudo mkdir -p "$RUNNER_HOME/bin"
114 sudo chown -R "$USER":"$USER" "$RUNNER_HOME"
115
116 # --- Download runner binary ---
117 echo "Downloading Forgejo runner binary..."
118 VERSION_NUM=${RUNNER_VERSION#v}
119 DOWNLOAD_URL="https://code.forgejo.org/forgejo/runner/releases/download/$RUNNER_VERSION/forgejo-runner-${VERSION_NUM}-linux-$ARCH"
120
121 echo "Downloading from: $DOWNLOAD_URL"
122
123 # Download with timeout and retry
124 if ! curl -L -m 30 --retry 3 "$DOWNLOAD_URL" -o "$RUNNER_HOME/bin/forgejo-runner"; then
125 echo "ERROR: Failed to download runner binary"
126 echo "Try manual download:"
127 echo " wget $DOWNLOAD_URL"
128 exit 1
129 fi
130
131 chmod +x "$RUNNER_HOME/bin/forgejo-runner"
132 chown -R "$USER":"$USER" "$RUNNER_HOME"
133
134 # --- Register runner ---
135 echo "Registering runner with Forgejo..."
136 "$RUNNER_HOME/bin/forgejo-runner" register \
137 --token "$REGISTRATION_TOKEN" \
138 --name "$RUNNER_NAME" \
139 --instance "$FORGEJO_URL" \
140 --labels "$RUNNER_NAME:host" \
141 --no-interactive
142
143 # --- Create config.yaml ---
144 echo "Creating configuration..."
145 cat > "$RUNNER_HOME/config.yaml" << EOF
146instance: $FORGEJO_URL
147token: "$REGISTRATION_TOKEN"
148
149log:
150 level: info
151
152runner:
153 file: .runner
154 capacity: 1
155 timeout: 30m
156 shutdown_timeout: 30m
157 insecure: true
158 fetch_timeout: 30s
159 fetch_interval: 60s
160 report_interval: 10s
161 labels:
162 - "$RUNNER_NAME:host"
163
164cache:
165 enabled: true
166 dir: ""
167
168host:
169 workdir_parent: ""
170EOF
171
172 # --- Create systemd service ---
173 echo "Creating systemd service..."
174 sudo tee /etc/systemd/system/forgejo-runner.service > /dev/null << EOF
175[Unit]
176Description=Forgejo Actions Runner
177After=network.target
178
179[Service]
180Type=simple
181User=$USER
182Group=$USER
183WorkingDirectory=$RUNNER_HOME
184ExecStart=$RUNNER_HOME/bin/forgejo-runner daemon --config $RUNNER_HOME/config.yaml
185Restart=always
186RestartSec=10
187StartLimitBurst=3
188StartLimitInterval=60s
189LimitNOFILE=65536
190LimitNPROC=65536
191
192[Install]
193WantedBy=multi-user.target
194EOF
195
196 # --- Enable and start service ---
197 echo "Starting service..."
198 sudo systemctl daemon-reload
199 sudo systemctl enable forgejo-runner.service
200 sudo systemctl start forgejo-runner.service
201
202 echo ""
203 echo "=== DIRECT MODE DEPLOYMENT COMPLETE ==="
204 echo ""
205 echo "Service status:"
206 sudo systemctl status forgejo-runner.service --no-pager
207 echo ""
208 echo "To view logs:"
209 echo " sudo journalctl -u forgejo-runner -f"
210 echo ""
211 echo "Runner location: $RUNNER_HOME"
212
213# =============================================================================
214# DOCKER MODE INSTALLATION
215# =============================================================================
216elif [ "$RUNNER_MODE" = "docker" ]; then
217 echo "=== DOCKER MODE INSTALLATION ==="
218 echo "Installing runner with Docker Compose"
219 echo ""
220
221 # --- Check and install Docker if needed ---
222 echo "Checking Docker..."
223 if ! command -v docker &> /dev/null; then
224 echo "Docker not found. Installing Docker..."
225 curl -fsSL https://get.docker.com -o get-docker.sh
226 sudo sh get-docker.sh
227 sudo usermod -aG docker $USER
228 sudo systemctl enable docker --now
229 rm get-docker.sh
230 echo "Docker installed successfully"
231 else
232 echo "Docker is already installed"
233 fi
234
235 if ! systemctl is-active --quiet docker; then
236 echo "Starting Docker service..."
237 sudo systemctl start docker
238 fi
239 echo "Docker is running"
240
241 # --- Check and install Docker Compose if needed ---
242 echo "Checking Docker Compose..."
243 if ! command -v docker compose &> /dev/null; then
244 echo "Docker Compose not found. Installing..."
245 sudo apt update && sudo apt install -y docker-compose-plugin
246 else
247 echo "Docker Compose is already installed"
248 fi
249 echo ""
250
251 # --- Create working directory ---
252 echo "Creating working directory..."
253 mkdir -p "$COMPOSE_DIR"/{data,cache}
254 cd "$COMPOSE_DIR"
255
256 # --- Register runner using Docker ---
257 echo "Registering runner with Forgejo..."
258 docker run -it --rm \
259 -v "$(pwd)/data:/data" \
260 -w /data \
261 --user root \
262 "${RUNNER_IMAGE}:${RUNNER_VERSION#v}" \
263 forgejo-runner register \
264 --no-interactive \
265 --token "$REGISTRATION_TOKEN" \
266 --name "$RUNNER_NAME" \
267 --instance "$FORGEJO_URL" \
268 --labels "$RUNNER_NAME:host"
269
270 # --- Generate config.yaml ---
271 echo "Generating configuration..."
272 cat > data/config.yaml << EOF
273instance: $FORGEJO_URL
274token: "$REGISTRATION_TOKEN"
275
276log:
277 level: info
278
279runner:
280 file: .runner
281 capacity: 1
282 timeout: 30m
283 shutdown_timeout: 30m
284 insecure: true
285 fetch_timeout: 30s
286 fetch_interval: 60s
287 report_interval: 10s
288 labels:
289 - "$RUNNER_NAME:host"
290
291cache:
292 enabled: true
293 dir: ""
294
295container:
296 privileged: false
297 valid_volumes:
298 - '**'
299 docker_host: ""
300 force_pull: false
301
302host:
303 workdir_parent: ""
304EOF
305
306 # --- Create docker-compose.yml ---
307 echo "Creating docker-compose.yml..."
308 cat > docker-compose.yml << EOF
309version: '3.8'
310
311services:
312 docker-in-docker:
313 image: $DIND_IMAGE
314 container_name: ${RUNNER_NAME}_dind
315 privileged: true
316 command: ['dockerd', '-H', 'tcp://0.0.0.0:2375', '--tls=false']
317 restart: unless-stopped
318 volumes:
319 - dind-storage:/var/lib/docker
320
321 runner:
322 image: ${RUNNER_IMAGE}:${RUNNER_VERSION#v}
323 container_name: ${RUNNER_NAME}
324 depends_on:
325 docker-in-docker:
326 condition: service_started
327 environment:
328 DOCKER_HOST: tcp://docker-in-docker:2375
329 user: 0:0
330 volumes:
331 - ./data:/data
332 - ./cache:/cache
333 restart: unless-stopped
334 command: /bin/sh -c "
335 apk update && apk add --no-cache nodejs npm &&
336 sleep 5 &&
337 forgejo-runner daemon --config /data/config.yaml
338 "
339
340volumes:
341 dind-storage:
342EOF
343
344 # --- Create systemd service for docker-compose ---
345 echo "Creating systemd service..."
346 sudo tee /etc/systemd/system/forgejo-runner-docker.service > /dev/null << EOF
347[Unit]
348Description=Forgejo Runner (Docker Compose)
349After=docker.service
350Requires=docker.service
351
352[Service]
353Type=oneshot
354RemainAfterExit=yes
355WorkingDirectory=$COMPOSE_DIR
356ExecStart=/usr/bin/docker compose up -d
357ExecStop=/usr/bin/docker compose down
358ExecReload=/usr/bin/docker compose restart
359StandardOutput=journal
360User=$USER
361Group=$USER
362
363[Install]
364WantedBy=multi-user.target
365EOF
366
367 # --- Enable and start service ---
368 echo "Starting service..."
369 sudo systemctl daemon-reload
370 sudo systemctl enable forgejo-runner-docker.service
371 sudo systemctl start forgejo-runner-docker.service
372
373 echo ""
374 echo "=== DOCKER MODE DEPLOYMENT COMPLETE ==="
375 echo ""
376 echo "Service status:"
377 sudo systemctl status forgejo-runner-docker.service --no-pager
378 echo ""
379 echo "To view logs:"
380 echo " docker compose -f $COMPOSE_DIR/docker-compose.yml logs -f runner"
381 echo ""
382 echo "To manage:"
383 echo " cd $COMPOSE_DIR"
384 echo " docker compose up -d # start"
385 echo " docker compose down # stop"
386 echo " docker compose restart # restart"
387 echo ""
388 echo "Runner location: $COMPOSE_DIR"
389
390# =============================================================================
391# INVALID MODE
392# =============================================================================
393else
394 echo "ERROR: Invalid RUNNER_MODE. Use 'direct' or 'docker'"
395 exit 1
396fi
397
398echo ""
399echo "============================================================"
400echo "DEPLOYMENT COMPLETE"
401echo "============================================================"
402echo ""
403echo "Runner should now appear online in Forgejo Admin -> Actions -> Runners"
404echo "URL: $FORGEJO_URL/admin/actions/runners"
405echo ""
406if [ "$RUNNER_MODE" = "direct" ]; then
407 echo "To check runner logs: sudo journalctl -u forgejo-runner -f"
408else
409 echo "To check runner logs: docker compose -f $COMPOSE_DIR/docker-compose.yml logs -f runner"
410fi
411echo "============================================================"