forgejo-actions-guide-docker.txt
· 12 KiB · Text
Raw
#!/bin/bash
# =============================================================================
# FORGEJO RUNNER - FULL SYSTEM DEPLOYMENT WITH SYSTEMD
# Supports both DIRECT and DOCKER modes
# =============================================================================
# --- CONFIGURATION VARIABLES ---
FORGEJO_URL="http://192.168.2.76:3006" # CHANGE THIS
REGISTRATION_TOKEN="your-registration-token" # CHANGE THIS
RUNNER_NAME="selfhosted-runner-01"
RUNNER_VERSION="latest" # Can be "latest" or specific like "v3.4.1"
RUNNER_MODE="direct" # "direct" or "docker"
# Direct mode variables - using current user
RUNNER_HOME="/opt/forgejo-runner"
# Docker mode variables
COMPOSE_DIR="$HOME/forgejo-runner"
DIND_IMAGE="docker:dind"
RUNNER_IMAGE="data.forgejo.org/forgejo/runner"
# =============================================================================
set -e
echo "============================================================"
echo "FORGEJO RUNNER DEPLOYMENT"
echo "============================================================"
echo "Mode: $RUNNER_MODE"
echo "Version: $RUNNER_VERSION"
echo "Instance: $FORGEJO_URL"
echo ""
# --- STEP 1: Detect system architecture ---
ARCH=$(uname -m)
case $ARCH in
x86_64)
ARCH="amd64"
;;
aarch64|arm64)
ARCH="arm64"
;;
armv7l|armhf)
ARCH="armv7"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
echo "Detected architecture: $ARCH"
# --- STEP 2: Get actual version if "latest" ---
if [ "$RUNNER_VERSION" = "latest" ]; then
echo "Fetching latest Forgejo Runner version..."
# Try multiple sources specifically for Forgejo Runner
LATEST_VERSION=""
# Try 1: Official Forgejo API
if [ -z "$LATEST_VERSION" ]; then
echo "Trying Forgejo API..."
LATEST_VERSION=$(curl -s -m 10 https://code.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | \
grep -o '"tag_name":"v[0-9]\+\.[0-9]\+\.[0-9]\+"' | \
head -1 | sed 's/"tag_name":"//' | sed 's/"//' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$')
fi
# Try 2: GitHub API (mirror)
if [ -z "$LATEST_VERSION" ]; then
echo "Trying GitHub API..."
LATEST_VERSION=$(curl -s -m 10 https://api.github.com/repos/forgejo/runner/releases/latest | \
grep -o '"tag_name":"v[0-9]\+\.[0-9]\+\.[0-9]\+"' | \
head -1 | sed 's/"tag_name":"//' | sed 's/"//' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$')
fi
# Try 3: Direct HTML parsing with more specific pattern
if [ -z "$LATEST_VERSION" ]; then
echo "Trying HTML parsing..."
LATEST_VERSION=$(curl -s -m 10 https://code.forgejo.org/forgejo/runner/releases | \
grep -o 'forgejo-runner-[0-9]\+\.[0-9]\+\.[0-9]\+-linux' | \
head -1 | sed 's/forgejo-runner-//' | sed 's/-linux//' | sed 's/^/v/')
fi
# Try 4: Direct download page
if [ -z "$LATEST_VERSION" ]; then
echo "Trying releases page..."
LATEST_VERSION=$(curl -s -m 10 https://code.forgejo.org/forgejo/runner/releases/ | \
grep -E 'href="/forgejo/runner/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+"' | \
head -1 | sed 's/.*tag\/v/v/' | sed 's/".*//')
fi
# Fallback to hardcoded version
if [ -z "$LATEST_VERSION" ] || [[ ! "$LATEST_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Failed to fetch valid version, using fallback v3.4.1"
LATEST_VERSION="v3.4.1"
fi
RUNNER_VERSION="$LATEST_VERSION"
fi
echo "Using version: $RUNNER_VERSION"
echo ""
# =============================================================================
# DIRECT MODE INSTALLATION
# =============================================================================
if [ "$RUNNER_MODE" = "direct" ]; then
echo "=== DIRECT MODE INSTALLATION ==="
echo "Installing runner directly on the system (no Docker required)"
echo "Using current user: $USER"
echo ""
# --- Create directory ---
echo "Creating runner directory..."
sudo mkdir -p "$RUNNER_HOME/bin"
sudo chown -R "$USER":"$USER" "$RUNNER_HOME"
# --- Download runner binary ---
echo "Downloading Forgejo runner binary..."
VERSION_NUM=${RUNNER_VERSION#v}
DOWNLOAD_URL="https://code.forgejo.org/forgejo/runner/releases/download/$RUNNER_VERSION/forgejo-runner-${VERSION_NUM}-linux-$ARCH"
echo "Downloading from: $DOWNLOAD_URL"
# Download with timeout and retry
if ! curl -L -m 30 --retry 3 "$DOWNLOAD_URL" -o "$RUNNER_HOME/bin/forgejo-runner"; then
echo "ERROR: Failed to download runner binary"
echo "Try manual download:"
echo " wget $DOWNLOAD_URL"
exit 1
fi
chmod +x "$RUNNER_HOME/bin/forgejo-runner"
chown -R "$USER":"$USER" "$RUNNER_HOME"
# --- Register runner ---
echo "Registering runner with Forgejo..."
"$RUNNER_HOME/bin/forgejo-runner" register \
--token "$REGISTRATION_TOKEN" \
--name "$RUNNER_NAME" \
--instance "$FORGEJO_URL" \
--labels "$RUNNER_NAME:host" \
--no-interactive
# --- Create config.yaml ---
echo "Creating configuration..."
cat > "$RUNNER_HOME/config.yaml" << EOF
instance: $FORGEJO_URL
token: "$REGISTRATION_TOKEN"
log:
level: info
runner:
file: .runner
capacity: 1
timeout: 30m
shutdown_timeout: 30m
insecure: true
fetch_timeout: 30s
fetch_interval: 60s
report_interval: 10s
labels:
- "$RUNNER_NAME:host"
cache:
enabled: true
dir: ""
host:
workdir_parent: ""
EOF
# --- Create systemd service ---
echo "Creating systemd service..."
sudo tee /etc/systemd/system/forgejo-runner.service > /dev/null << EOF
[Unit]
Description=Forgejo Actions Runner
After=network.target
[Service]
Type=simple
User=$USER
Group=$USER
WorkingDirectory=$RUNNER_HOME
ExecStart=$RUNNER_HOME/bin/forgejo-runner daemon --config $RUNNER_HOME/config.yaml
Restart=always
RestartSec=10
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=65536
LimitNPROC=65536
[Install]
WantedBy=multi-user.target
EOF
# --- Enable and start service ---
echo "Starting service..."
sudo systemctl daemon-reload
sudo systemctl enable forgejo-runner.service
sudo systemctl start forgejo-runner.service
echo ""
echo "=== DIRECT MODE DEPLOYMENT COMPLETE ==="
echo ""
echo "Service status:"
sudo systemctl status forgejo-runner.service --no-pager
echo ""
echo "To view logs:"
echo " sudo journalctl -u forgejo-runner -f"
echo ""
echo "Runner location: $RUNNER_HOME"
# =============================================================================
# DOCKER MODE INSTALLATION
# =============================================================================
elif [ "$RUNNER_MODE" = "docker" ]; then
echo "=== DOCKER MODE INSTALLATION ==="
echo "Installing runner with Docker Compose"
echo ""
# --- Check and install Docker if needed ---
echo "Checking Docker..."
if ! command -v docker &> /dev/null; then
echo "Docker not found. Installing Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
sudo systemctl enable docker --now
rm get-docker.sh
echo "Docker installed successfully"
else
echo "Docker is already installed"
fi
if ! systemctl is-active --quiet docker; then
echo "Starting Docker service..."
sudo systemctl start docker
fi
echo "Docker is running"
# --- Check and install Docker Compose if needed ---
echo "Checking Docker Compose..."
if ! command -v docker compose &> /dev/null; then
echo "Docker Compose not found. Installing..."
sudo apt update && sudo apt install -y docker-compose-plugin
else
echo "Docker Compose is already installed"
fi
echo ""
# --- Create working directory ---
echo "Creating working directory..."
mkdir -p "$COMPOSE_DIR"/{data,cache}
cd "$COMPOSE_DIR"
# --- Register runner using Docker ---
echo "Registering runner with Forgejo..."
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"
# --- Generate config.yaml ---
echo "Generating configuration..."
cat > data/config.yaml << EOF
instance: $FORGEJO_URL
token: "$REGISTRATION_TOKEN"
log:
level: info
runner:
file: .runner
capacity: 1
timeout: 30m
shutdown_timeout: 30m
insecure: true
fetch_timeout: 30s
fetch_interval: 60s
report_interval: 10s
labels:
- "$RUNNER_NAME:host"
cache:
enabled: true
dir: ""
container:
privileged: false
valid_volumes:
- '**'
docker_host: ""
force_pull: false
host:
workdir_parent: ""
EOF
# --- Create docker-compose.yml ---
echo "Creating docker-compose.yml..."
cat > docker-compose.yml << EOF
version: '3.8'
services:
docker-in-docker:
image: $DIND_IMAGE
container_name: ${RUNNER_NAME}_dind
privileged: true
command: ['dockerd', '-H', 'tcp://0.0.0.0:2375', '--tls=false']
restart: unless-stopped
volumes:
- dind-storage:/var/lib/docker
runner:
image: ${RUNNER_IMAGE}:${RUNNER_VERSION#v}
container_name: ${RUNNER_NAME}
depends_on:
docker-in-docker:
condition: service_started
environment:
DOCKER_HOST: tcp://docker-in-docker:2375
user: 0:0
volumes:
- ./data:/data
- ./cache:/cache
restart: unless-stopped
command: /bin/sh -c "
apk update && apk add --no-cache nodejs npm &&
sleep 5 &&
forgejo-runner daemon --config /data/config.yaml
"
volumes:
dind-storage:
EOF
# --- Create systemd service for docker-compose ---
echo "Creating systemd service..."
sudo tee /etc/systemd/system/forgejo-runner-docker.service > /dev/null << EOF
[Unit]
Description=Forgejo Runner (Docker Compose)
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=$COMPOSE_DIR
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
ExecReload=/usr/bin/docker compose restart
StandardOutput=journal
User=$USER
Group=$USER
[Install]
WantedBy=multi-user.target
EOF
# --- Enable and start service ---
echo "Starting service..."
sudo systemctl daemon-reload
sudo systemctl enable forgejo-runner-docker.service
sudo systemctl start forgejo-runner-docker.service
echo ""
echo "=== DOCKER MODE DEPLOYMENT COMPLETE ==="
echo ""
echo "Service status:"
sudo systemctl status forgejo-runner-docker.service --no-pager
echo ""
echo "To view logs:"
echo " docker compose -f $COMPOSE_DIR/docker-compose.yml logs -f runner"
echo ""
echo "To manage:"
echo " cd $COMPOSE_DIR"
echo " docker compose up -d # start"
echo " docker compose down # stop"
echo " docker compose restart # restart"
echo ""
echo "Runner location: $COMPOSE_DIR"
# =============================================================================
# INVALID MODE
# =============================================================================
else
echo "ERROR: Invalid RUNNER_MODE. Use 'direct' or 'docker'"
exit 1
fi
echo ""
echo "============================================================"
echo "DEPLOYMENT COMPLETE"
echo "============================================================"
echo ""
echo "Runner should now appear online in Forgejo Admin -> Actions -> Runners"
echo "URL: $FORGEJO_URL/admin/actions/runners"
echo ""
if [ "$RUNNER_MODE" = "direct" ]; then
echo "To check runner logs: sudo journalctl -u forgejo-runner -f"
else
echo "To check runner logs: docker compose -f $COMPOSE_DIR/docker-compose.yml logs -f runner"
fi
echo "============================================================"
| 1 | #!/bin/bash |
| 2 | # ============================================================================= |
| 3 | # FORGEJO RUNNER - FULL SYSTEM DEPLOYMENT WITH SYSTEMD |
| 4 | # Supports both DIRECT and DOCKER modes |
| 5 | # ============================================================================= |
| 6 | |
| 7 | # --- CONFIGURATION VARIABLES --- |
| 8 | FORGEJO_URL="http://192.168.2.76:3006" # CHANGE THIS |
| 9 | REGISTRATION_TOKEN="your-registration-token" # CHANGE THIS |
| 10 | RUNNER_NAME="selfhosted-runner-01" |
| 11 | RUNNER_VERSION="latest" # Can be "latest" or specific like "v3.4.1" |
| 12 | RUNNER_MODE="direct" # "direct" or "docker" |
| 13 | |
| 14 | # Direct mode variables - using current user |
| 15 | RUNNER_HOME="/opt/forgejo-runner" |
| 16 | |
| 17 | # Docker mode variables |
| 18 | COMPOSE_DIR="$HOME/forgejo-runner" |
| 19 | DIND_IMAGE="docker:dind" |
| 20 | RUNNER_IMAGE="data.forgejo.org/forgejo/runner" |
| 21 | # ============================================================================= |
| 22 | |
| 23 | set -e |
| 24 | |
| 25 | echo "============================================================" |
| 26 | echo "FORGEJO RUNNER DEPLOYMENT" |
| 27 | echo "============================================================" |
| 28 | echo "Mode: $RUNNER_MODE" |
| 29 | echo "Version: $RUNNER_VERSION" |
| 30 | echo "Instance: $FORGEJO_URL" |
| 31 | echo "" |
| 32 | |
| 33 | # --- STEP 1: Detect system architecture --- |
| 34 | ARCH=$(uname -m) |
| 35 | case $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 | ;; |
| 49 | esac |
| 50 | echo "Detected architecture: $ARCH" |
| 51 | |
| 52 | # --- STEP 2: Get actual version if "latest" --- |
| 53 | if [ "$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" |
| 98 | fi |
| 99 | echo "Using version: $RUNNER_VERSION" |
| 100 | echo "" |
| 101 | |
| 102 | # ============================================================================= |
| 103 | # DIRECT MODE INSTALLATION |
| 104 | # ============================================================================= |
| 105 | if [ "$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 |
| 146 | instance: $FORGEJO_URL |
| 147 | token: "$REGISTRATION_TOKEN" |
| 148 | |
| 149 | log: |
| 150 | level: info |
| 151 | |
| 152 | runner: |
| 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 | |
| 164 | cache: |
| 165 | enabled: true |
| 166 | dir: "" |
| 167 | |
| 168 | host: |
| 169 | workdir_parent: "" |
| 170 | EOF |
| 171 | |
| 172 | # --- Create systemd service --- |
| 173 | echo "Creating systemd service..." |
| 174 | sudo tee /etc/systemd/system/forgejo-runner.service > /dev/null << EOF |
| 175 | [Unit] |
| 176 | Description=Forgejo Actions Runner |
| 177 | After=network.target |
| 178 | |
| 179 | [Service] |
| 180 | Type=simple |
| 181 | User=$USER |
| 182 | Group=$USER |
| 183 | WorkingDirectory=$RUNNER_HOME |
| 184 | ExecStart=$RUNNER_HOME/bin/forgejo-runner daemon --config $RUNNER_HOME/config.yaml |
| 185 | Restart=always |
| 186 | RestartSec=10 |
| 187 | StartLimitBurst=3 |
| 188 | StartLimitInterval=60s |
| 189 | LimitNOFILE=65536 |
| 190 | LimitNPROC=65536 |
| 191 | |
| 192 | [Install] |
| 193 | WantedBy=multi-user.target |
| 194 | EOF |
| 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 | # ============================================================================= |
| 216 | elif [ "$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 |
| 273 | instance: $FORGEJO_URL |
| 274 | token: "$REGISTRATION_TOKEN" |
| 275 | |
| 276 | log: |
| 277 | level: info |
| 278 | |
| 279 | runner: |
| 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 | |
| 291 | cache: |
| 292 | enabled: true |
| 293 | dir: "" |
| 294 | |
| 295 | container: |
| 296 | privileged: false |
| 297 | valid_volumes: |
| 298 | - '**' |
| 299 | docker_host: "" |
| 300 | force_pull: false |
| 301 | |
| 302 | host: |
| 303 | workdir_parent: "" |
| 304 | EOF |
| 305 | |
| 306 | # --- Create docker-compose.yml --- |
| 307 | echo "Creating docker-compose.yml..." |
| 308 | cat > docker-compose.yml << EOF |
| 309 | version: '3.8' |
| 310 | |
| 311 | services: |
| 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 | |
| 340 | volumes: |
| 341 | dind-storage: |
| 342 | EOF |
| 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] |
| 348 | Description=Forgejo Runner (Docker Compose) |
| 349 | After=docker.service |
| 350 | Requires=docker.service |
| 351 | |
| 352 | [Service] |
| 353 | Type=oneshot |
| 354 | RemainAfterExit=yes |
| 355 | WorkingDirectory=$COMPOSE_DIR |
| 356 | ExecStart=/usr/bin/docker compose up -d |
| 357 | ExecStop=/usr/bin/docker compose down |
| 358 | ExecReload=/usr/bin/docker compose restart |
| 359 | StandardOutput=journal |
| 360 | User=$USER |
| 361 | Group=$USER |
| 362 | |
| 363 | [Install] |
| 364 | WantedBy=multi-user.target |
| 365 | EOF |
| 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 | # ============================================================================= |
| 393 | else |
| 394 | echo "ERROR: Invalid RUNNER_MODE. Use 'direct' or 'docker'" |
| 395 | exit 1 |
| 396 | fi |
| 397 | |
| 398 | echo "" |
| 399 | echo "============================================================" |
| 400 | echo "DEPLOYMENT COMPLETE" |
| 401 | echo "============================================================" |
| 402 | echo "" |
| 403 | echo "Runner should now appear online in Forgejo Admin -> Actions -> Runners" |
| 404 | echo "URL: $FORGEJO_URL/admin/actions/runners" |
| 405 | echo "" |
| 406 | if [ "$RUNNER_MODE" = "direct" ]; then |
| 407 | echo "To check runner logs: sudo journalctl -u forgejo-runner -f" |
| 408 | else |
| 409 | echo "To check runner logs: docker compose -f $COMPOSE_DIR/docker-compose.yml logs -f runner" |
| 410 | fi |
| 411 | echo "============================================================" |