Last active 1 month ago

forgejo runner install script

Revision f2df1ad451d5b8534fbd64b9cc707bcb4b798e79

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