♻️ 重构代码和`docker-runner`项目结构
Ubuntu System Information / show-system-info (push) Failing after 38s Details

 支持`docker`部署`archlinux`,预装`clang`跨平台编译工具链
This commit is contained in:
csh 2025-12-09 16:06:25 +08:00
parent 4829434408
commit 39820e656a
18 changed files with 639 additions and 2466 deletions

View File

@ -1,33 +0,0 @@
name: Hello from ImmortalWrt
on:
push:
branches:
- main
jobs:
say-hello:
runs-on: company
steps:
- name: 打印问候
run: echo "Hello form ImmortalWrt Router!"
- name: 显示系统信息
run: |
echo "===== 系统信息 ====="
uname -a
cat /etc/openwrt_release || echo "不是 OpenWrt 环境"
- name: 显示 CPU 和内存
run: |
echo "===== CPU 信息 ====="
cat /proc/cpuinfo | grep "model name" | head -1 || echo "ARM 架构"
echo "===== 内存信息 ====="
free -h
- name: 显示磁盘空间
run: df -h
- name: 列出当前目录
run: ls -la

View File

@ -0,0 +1,99 @@
name: Ubuntu System Information
on:
push:
branches:
- main
workflow_dispatch: # 允许手动触发
jobs:
show-system-info:
runs-on: ubuntu-22.04
steps:
- name: 打印问候
run: |
echo "====================================="
echo " Ubuntu System Information Check "
echo "====================================="
echo ""
- name: 显示系统信息
run: |
echo "===== 系统版本 ====="
cat /etc/os-release
echo ""
echo "===== 内核信息 ====="
uname -a
echo ""
echo "===== LSB 信息 ====="
lsb_release -a
- name: 显示 CPU 信息
run: |
echo "===== CPU 详细信息 ====="
lscpu
echo ""
echo "===== CPU 型号 ====="
cat /proc/cpuinfo | grep "model name" | head -1
echo ""
echo "===== CPU 核心数 ====="
nproc
- name: 显示内存信息
run: |
echo "===== 内存使用情况 ====="
free -h
echo ""
echo "===== 内存详细信息 ====="
cat /proc/meminfo | grep -E 'MemTotal|MemFree|MemAvailable'
- name: 显示磁盘信息
run: |
echo "===== 磁盘使用情况 ====="
df -h
echo ""
echo "===== 磁盘分区信息 ====="
lsblk
- name: 显示网络信息
run: |
echo "===== 网络接口 ====="
ip addr show
echo ""
echo "===== 路由表 ====="
ip route show
echo ""
echo "===== DNS 配置 ====="
cat /etc/resolv.conf
- name: 显示已安装的软件
run: |
echo "===== Python 版本 ====="
python3 --version
echo ""
echo "===== Node.js 版本 ====="
node --version || echo "Node.js 未安装"
echo ""
echo "===== Docker 版本 ====="
docker --version || echo "Docker 未安装"
echo ""
echo "===== Git 版本 ====="
git --version
- name: 显示环境变量
run: |
echo "===== 重要环境变量 ====="
echo "PATH: $PATH"
echo "HOME: $HOME"
echo "USER: $USER"
echo "SHELL: $SHELL"
echo "PWD: $PWD"
- name: 显示当前目录
run: |
echo "===== 当前工作目录 ====="
pwd
echo ""
echo "===== 目录内容 ====="
ls -lah

File diff suppressed because it is too large Load Diff

View File

@ -1,321 +0,0 @@
#!/bin/bash
set -e
echo "=========================================="
echo " Gitea Runner Registration Script "
echo "=========================================="
echo ""
# 检查 act_runner 是否安装
if ! command -v act_runner &> /dev/null; then
echo "✗ act_runner is not installed!"
echo ""
echo "Please run the setup script first:"
echo " docker-compose exec gitea-runner /data/setup.sh"
exit 1
fi
echo "✓ act_runner found: $(act_runner --version)"
echo ""
# 获取注册信息并验证
while true; do
read -p "Enter Gitea instance URL (e.g., https://gitea.example.com): " GITEA_INSTANCE
# 验证 URL 格式
if [[ ! "$GITEA_INSTANCE" =~ ^https?:// ]]; then
echo "✗ Error: URL must start with http:// or https://"
echo ""
continue
fi
# 移除末尾的斜杠
GITEA_INSTANCE="${GITEA_INSTANCE%/}"
echo "✓ URL validated: $GITEA_INSTANCE"
break
done
read -p "Enter registration token: " GITEA_TOKEN
if [ -z "$GITEA_TOKEN" ]; then
echo "✗ Error: Token cannot be empty!"
exit 1
fi
read -p "Enter runner name (default: docker-runner): " RUNNER_NAME
RUNNER_NAME=${RUNNER_NAME:-docker-runner}
# 多个 label逗号分隔无空格
# ubuntu-22.04:host://ubuntu:22.04,ubuntu-20.04:host://ubuntu:20.04,node:docker://node:18
read -p "Enter runner labels (default: ubuntu-22.04:host://ubuntu:22.04): " RUNNER_LABELS
RUNNER_LABELS=${RUNNER_LABELS:-ubuntu-22.04:host://ubuntu:22.04}
# 创建 runner 目录
RUNNER_DIR="/data/runners/${RUNNER_NAME}"
mkdir -p "$RUNNER_DIR"
cd "$RUNNER_DIR"
echo ""
echo "Registration Information:"
echo " Instance: $GITEA_INSTANCE"
echo " Name: $RUNNER_NAME"
echo " Labels: $RUNNER_LABELS"
echo " Directory: $RUNNER_DIR"
echo ""
# 检查是否已经注册
if [ -f ".runner" ] || [ -f "config.yaml" ]; then
echo "⚠ Runner already exists in this directory!"
read -p "Do you want to re-register? This will overwrite existing configuration. (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Registration cancelled."
exit 0
fi
echo "Cleaning up existing runner..."
# 停止现有 runner
echo "Stopping existing runner..."
supervisorctl stop "runner-${RUNNER_NAME}" 2>/dev/null || true
# 删除 supervisor 配置
rm -f "/etc/supervisor/conf.d/runner-${RUNNER_NAME}.conf"
# 重新加载 supervisor
supervisorctl reread 2>/dev/null || true
supervisorctl update 2>/dev/null || true
# 删除日志
rm -f "/var/log/supervisor/runner-${RUNNER_NAME}".*.log*
# 删除旧配置和缓存
rm -f .runner config.yaml
rm -rf cache
fi
# 执行注册
echo ""
echo "Registering runner..."
act_runner register \
--instance "$GITEA_INSTANCE" \
--token "$GITEA_TOKEN" \
--name "$RUNNER_NAME" \
--labels "$RUNNER_LABELS" \
--no-interactive
if [ ! -f ".runner" ]; then
echo ""
echo "✗ Registration failed! .runner file not created."
exit 1
fi
echo "✓ Registration successful!"
# 生成配置文件
echo ""
echo "Generating config.yaml..."
act_runner generate-config > config.yaml
echo "✓ Configuration file generated!"
# 创建缓存目录
mkdir -p cache
# 使用 Python 修改配置(最可靠的方法)
echo ""
echo "Configuring runner settings..."
if command -v python3 &> /dev/null; then
python3 << PYEOF
import yaml
import sys
try:
# 读取生成的配置
with open('config.yaml', 'r') as f:
config = yaml.safe_load(f)
# 读取 .runner 获取实际注册的 labels
import json
with open('.runner', 'r') as f:
runner_data = json.load(f)
# 使用 .runner 中的 labels这是实际注册的
registered_labels = runner_data.get('labels', [])
# 修改配置
if 'runner' not in config:
config['runner'] = {}
# 使用实际注册的 labels
config['runner']['labels'] = registered_labels
config['runner']['capacity'] = 2
# 启用缓存
if 'cache' not in config:
config['cache'] = {}
config['cache']['enabled'] = True
config['cache']['dir'] = './cache'
# 保存配置
with open('config.yaml', 'w') as f:
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
print("✓ Configuration updated using Python")
print(f" - Labels: {registered_labels}")
print(f" - Capacity: 2")
print(f" - Cache enabled: ./cache")
sys.exit(0)
except Exception as e:
print(f"✗ Python configuration failed: {e}", file=sys.stderr)
sys.exit(1)
PYEOF
PYTHON_EXIT=$?
if [ $PYTHON_EXIT -ne 0 ]; then
echo ""
echo "⚠ Python configuration failed, using basic sed..."
# 基本的 sed 修改(只修改简单的值,不动 labels
sed -i 's/capacity: 1/capacity: 2/g' config.yaml || true
sed -i 's/enabled: false/enabled: true/g' config.yaml || true
sed -i 's|dir: ""|dir: ./cache|g' config.yaml || true
echo "✓ Basic configuration applied"
echo " Note: Please manually verify labels in config.yaml match .runner"
fi
else
echo "⚠ Python3 not found, applying basic configuration..."
# 基本的 sed 修改
sed -i 's/capacity: 1/capacity: 2/g' config.yaml || true
sed -i 's/enabled: false/enabled: true/g' config.yaml || true
sed -i 's|dir: ""|dir: ./cache|g' config.yaml || true
echo "✓ Basic configuration applied"
echo " Note: Labels will use act_runner defaults"
fi
# 验证配置文件
echo ""
echo "Validating configuration..."
# 检查 YAML 语法
if command -v python3 &> /dev/null; then
python3 << PYEOF
import yaml
import sys
try:
with open('config.yaml', 'r') as f:
yaml.safe_load(f)
print("✓ config.yaml syntax is valid")
sys.exit(0)
except Exception as e:
print(f"✗ config.yaml syntax error: {e}", file=sys.stderr)
sys.exit(1)
PYEOF
if [ $? -ne 0 ]; then
echo ""
echo "✗ Configuration file has syntax errors!"
echo " Backup available at: config.yaml.bak"
exit 1
fi
fi
# 显示配置摘要
echo ""
echo "Configuration Summary:"
echo "-------------------------------------------"
echo ".runner labels:"
cat .runner | grep -A 10 '"labels"' | head -15
echo ""
echo "config.yaml labels:"
grep -A 5 "^ labels:" config.yaml | head -10
# 创建 supervisor 配置
echo ""
echo "Creating supervisor configuration..."
cat > "/etc/supervisor/conf.d/runner-${RUNNER_NAME}.conf" <<EOF
[program:runner-${RUNNER_NAME}]
command=/usr/local/bin/act_runner daemon --config ${RUNNER_DIR}/config.yaml
directory=${RUNNER_DIR}
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/runner-${RUNNER_NAME}.err.log
stdout_logfile=/var/log/supervisor/runner-${RUNNER_NAME}.out.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
stderr_logfile_maxbytes=50MB
stderr_logfile_backups=10
user=root
environment=HOME="/root"
EOF
echo "✓ Supervisor configuration created"
# 重新加载 supervisor
echo ""
echo "Reloading supervisor..."
supervisorctl reread
supervisorctl update
echo "Starting runner..."
sleep 2
# 启动 runner
supervisorctl restart "runner-${RUNNER_NAME}" 2>/dev/null || \
supervisorctl start "runner-${RUNNER_NAME}"
# 等待启动
sleep 3
# 显示状态
RUNNER_STATUS=$(supervisorctl status "runner-${RUNNER_NAME}" 2>/dev/null || echo "UNKNOWN")
echo ""
echo "=========================================="
echo "✓ Runner registered and started!"
echo "=========================================="
echo ""
echo "Runner Information:"
echo " Name: $RUNNER_NAME"
echo " Directory: $RUNNER_DIR"
echo " Status: $RUNNER_STATUS"
echo ""
echo "Configuration files:"
echo " .runner: $(ls -lh .runner 2>/dev/null | awk '{print $5}' || echo 'N/A')"
echo " config.yaml: $(ls -lh config.yaml 2>/dev/null | awk '{print $5}' || echo 'N/A')"
echo ""
echo "Useful commands:"
echo " View logs: docker-compose exec gitea-runner /data/manage.sh logs ${RUNNER_NAME}"
echo " Follow logs: docker-compose exec gitea-runner /data/manage.sh follow ${RUNNER_NAME}"
echo " Check status: docker-compose exec gitea-runner /data/manage.sh status"
echo " Restart: docker-compose exec gitea-runner /data/manage.sh restart ${RUNNER_NAME}"
echo ""
# 显示最近的日志
if [ -f "/var/log/supervisor/runner-${RUNNER_NAME}.out.log" ]; then
echo "Recent logs:"
echo "-------------------------------------------"
tail -n 20 "/var/log/supervisor/runner-${RUNNER_NAME}.out.log" 2>/dev/null || echo "No logs yet"
echo ""
fi
# 检查是否有错误
if [ -f "/var/log/supervisor/runner-${RUNNER_NAME}.err.log" ]; then
# 只查找 error/fatal/panic 级别的日志
ERR_CONTENT=$(grep -E 'level=(error|fatal|panic)' \
"/var/log/supervisor/runner-${RUNNER_NAME}.err.log" | tail -n 5 2>/dev/null)
if [ -n "$ERR_CONTENT" ]; then
echo "❌ Recent errors detected:"
echo "-------------------------------------------"
echo "$ERR_CONTENT"
echo ""
echo "Check full error log with:"
echo " docker-compose exec gitea-runner cat /var/log/supervisor/runner-${RUNNER_NAME}.err.log"
fi
fi

View File

@ -10,111 +10,134 @@ PERSISTENT_BIN="/data/bin"
RUNNER_PATH="$PERSISTENT_BIN/act_runner" RUNNER_PATH="$PERSISTENT_BIN/act_runner"
SYSTEM_LINK="/usr/local/bin/act_runner" SYSTEM_LINK="/usr/local/bin/act_runner"
# 读取环境变量配置
ENABLE_BUILDX="${ENABLE_BUILDX:-false}"
BINFMT_METHOD="${BINFMT_METHOD:-update-binfmts}" # update-binfmts 或 tonistiigi
# 创建必要目录 # 创建必要目录
mkdir -p /data/runners mkdir -p /data/runners
mkdir -p "$PERSISTENT_BIN" mkdir -p "$PERSISTENT_BIN"
mkdir -p /data/buildx
mkdir -p /var/log/supervisor mkdir -p /var/log/supervisor
mkdir -p /var/run mkdir -p /var/run
# ============================================ # ============================================
# 初始化 Docker Buildx 支持 # 初始化 Docker Buildx 支持(可选)
# ============================================ # ============================================
echo "" if [ "$ENABLE_BUILDX" = "true" ]; then
echo "Initializing Docker Buildx..."
# 启动 Docker 守护进程(如果使用主机 socket 则跳过)
if [ -S /var/run/docker.sock ]; then
echo "✓ Using host Docker socket"
else
echo "Starting Docker daemon..."
dockerd > /var/log/dockerd.log 2>&1 &
sleep 5
fi
# 等待 Docker 就绪
echo "Waiting for Docker daemon..."
for i in {1..30}; do
if docker info > /dev/null 2>&1; then
echo "✓ Docker daemon is ready"
break
fi
if [ $i -eq 30 ]; then
echo "✗ Docker daemon failed to start"
[ -f /var/log/dockerd.log ] && cat /var/log/dockerd.log
exit 1
fi
sleep 1
done
# 注册 QEMU binfmt
echo ""
echo "Registering QEMU binary formats..."
update-binfmts --enable 2>/dev/null || {
echo "⚠ binfmt_misc not available, trying to mount..."
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 2>/dev/null || true
update-binfmts --enable
}
# 验证多架构支持
echo "Verifying multi-arch support..."
if docker run --rm arm64v8/alpine uname -m > /dev/null 2>&1; then
echo " ✓ arm64 support verified"
else
echo " ⚠ arm64 verification failed"
fi
if docker run --rm amd64/alpine uname -m > /dev/null 2>&1; then
echo " ✓ amd64 support verified"
else
echo " ⚠ amd64 verification failed"
fi
# 配置 Buildx
if [ ! -f "/data/buildx/.configured" ]; then
echo "" echo ""
echo "Setting up Buildx for the first time..." echo "Initializing Docker Buildx..."
mkdir -p /data/buildx
# 创建 BuildKit 配置 # 启动 Docker 守护进程(如果使用主机 socket 则跳过)
cat > /data/buildx/buildkitd.toml <<EOF if [ -S /var/run/docker.sock ]; then
echo "✓ Using host Docker socket"
else
echo "Starting Docker daemon..."
dockerd > /var/log/dockerd.log 2>&1 &
sleep 5
fi
# 等待 Docker 就绪
echo "Waiting for Docker daemon..."
for i in {1..30}; do
if docker info > /dev/null 2>&1; then
echo "✓ Docker daemon is ready"
break
fi
if [ $i -eq 30 ]; then
echo "✗ Docker daemon failed to start"
[ -f /var/log/dockerd.log ] && cat /var/log/dockerd.log
exit 1
fi
sleep 1
done
# 注册 QEMU binfmt
echo ""
echo "Registering QEMU binary formats..."
if [ "$BINFMT_METHOD" = "tonistiigi" ]; then
# 使用 tonistiigi/binfmt更可靠
if docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 > /var/log/binfmt-install.log 2>&1; then
echo "✓ Installed binfmt via tonistiigi/binfmt"
grep -m1 "Installed" /var/log/binfmt-install.log || true
else
echo "⚠ binfmt install via tonistiigi/binfmt failed, trying local tools..."
if command -v update-binfmts > /dev/null 2>&1; then
update-binfmts --enable 2>/dev/null || true
else
echo "⚠ update-binfmts not available; multi-arch emulation may be limited"
fi
fi
else
# 使用 update-binfmts传统方法
update-binfmts --enable 2>/dev/null || {
echo "⚠ binfmt_misc not available, trying to mount..."
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 2>/dev/null || true
update-binfmts --enable
}
fi
# 验证多架构支持
echo "Verifying multi-arch support..."
if docker run --rm arm64v8/alpine uname -m > /dev/null 2>&1; then
echo " ✓ arm64 support verified"
else
echo " ⚠ arm64 verification failed"
fi
if docker run --rm amd64/alpine uname -m > /dev/null 2>&1; then
echo " ✓ amd64 support verified"
else
echo " ⚠ amd64 verification failed"
fi
# 配置 Buildx
if [ ! -f "/data/buildx/.configured" ]; then
echo ""
echo "Setting up Buildx for the first time..."
# 创建 BuildKit 配置
cat > /data/buildx/buildkitd.toml <<EOF
[worker.oci] [worker.oci]
max-parallelism = 4 max-parallelism = 4
EOF EOF
# 创建 Buildx builder # 创建 Buildx builder
docker buildx create \
--name gitea-multiarch \
--driver docker-container \
--bootstrap \
--use \
--config /data/buildx/buildkitd.toml 2>/dev/null || \
docker buildx use gitea-multiarch 2>/dev/null
# 验证
echo "Verifying Buildx..."
docker buildx inspect --bootstrap > /dev/null 2>&1
# 标记为已配置
touch /data/buildx/.configured
echo "✓ Buildx configured successfully!"
docker buildx inspect | grep "Platforms:" | head -1
else
echo "✓ Buildx already configured"
# 确保 builder 可用
docker buildx use gitea-multiarch 2>/dev/null || {
echo "⚠ Recreating Buildx builder..."
docker buildx rm gitea-multiarch 2>/dev/null || true
docker buildx create \ docker buildx create \
--name gitea-multiarch \ --name gitea-multiarch \
--driver docker-container \ --driver docker-container \
--bootstrap \ --bootstrap \
--use 2>/dev/null --use \
} --config /data/buildx/buildkitd.toml 2>/dev/null || \
fi docker buildx use gitea-multiarch 2>/dev/null
echo "" # 验证
echo "Verifying Buildx..."
docker buildx inspect --bootstrap > /dev/null 2>&1
# 标记为已配置
touch /data/buildx/.configured
echo "✓ Buildx configured successfully!"
docker buildx inspect | grep "Platforms:" | head -1
else
echo "✓ Buildx already configured"
# 确保 builder 可用
docker buildx use gitea-multiarch 2>/dev/null || {
echo "⚠ Recreating Buildx builder..."
docker buildx rm gitea-multiarch 2>/dev/null || true
docker buildx create \
--name gitea-multiarch \
--driver docker-container \
--bootstrap \
--use 2>/dev/null
}
fi
echo ""
fi
# ============================================ # ============================================
# 检查 act_runner 安装 # 检查 act_runner 安装

View File

@ -47,8 +47,9 @@ RUNNER_NAME=${RUNNER_NAME:-docker-runner}
# 多个 label逗号分隔无空格 # 多个 label逗号分隔无空格
# ubuntu-22.04:host://ubuntu:22.04,ubuntu-20.04:host://ubuntu:20.04,node:docker://node:18 # ubuntu-22.04:host://ubuntu:22.04,ubuntu-20.04:host://ubuntu:20.04,node:docker://node:18
read -p "Enter runner labels (default: ubuntu-22.04:host://ubuntu:22.04): " RUNNER_LABELS DEFAULT_LABEL="${DEFAULT_RUNNER_LABEL:-ubuntu-22.04:host://ubuntu:22.04}"
RUNNER_LABELS=${RUNNER_LABELS:-ubuntu-22.04:host://ubuntu:22.04} read -p "Enter runner labels (default: $DEFAULT_LABEL): " RUNNER_LABELS
RUNNER_LABELS=${RUNNER_LABELS:-$DEFAULT_LABEL}
# 创建 runner 目录 # 创建 runner 目录
RUNNER_DIR="/data/runners/${RUNNER_NAME}" RUNNER_DIR="/data/runners/${RUNNER_NAME}"

View File

@ -0,0 +1,68 @@
FROM archlinux:latest
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# 初始化密钥和软件源
RUN pacman-key --init && \
pacman-key --populate archlinux && \
sed -i 's/^#ParallelDownloads/ParallelDownloads/' /etc/pacman.conf && \
printf "\n[archlinuxcn]\nServer = https://mirrors.ustc.edu.cn/archlinuxcn/\$arch\n" >> /etc/pacman.conf && \
pacman -Syy --noconfirm
# 安装基础工具、Buildx 支持和开发环境
RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm --disable-download-timeout archlinuxcn-keyring && \
pacman -S --noconfirm --needed \
base-devel \
ca-certificates \
clang \
lld \
libc++ \
libc++abi \
cmake \
ninja \
curl \
git \
python \
python-pyyaml \
python-pip \
paru \
conan \
sudo \
vim \
supervisor \
qemu-user-static \
qemu-user-static-binfmt \
docker \
docker-buildx \
&& pacman -Scc --noconfirm
# AUR 用户paru 需非 root 运行)
RUN useradd -m aur && \
echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur && \
chmod 0440 /etc/sudoers.d/aur
# 安装额外的 AUR 工具
USER aur
WORKDIR /home/aur
RUN paru -S --noconfirm --needed --noprogressbar llvm-mingw-w64-toolchain-ucrt-bin && \
paru -Scc --noconfirm && \
rm -rf ~/.cache/paru
# 切换回 root
USER root
WORKDIR /root
# 验证 qemu 和 docker 安装
RUN qemu-aarch64-static --version && \
qemu-x86_64-static --version && \
docker --version
# 创建必要目录
RUN mkdir -p /data /etc/supervisor/conf.d /var/log/supervisor
# 设置工作目录
WORKDIR /data
# 使用自定义入口点
ENTRYPOINT ["/data/entrypoint.sh"]

View File

@ -0,0 +1,35 @@
services:
gitea-runner:
build: .
container_name: gitea-runner-buildx-archlinux
restart: unless-stopped
network_mode: "host" # 使用宿主机网络
privileged: true # Buildx 需要 privileged 模式
volumes:
- ./runner-data:/data
- ../../common/setup.sh:/data/setup.sh:ro
- ../../common/register.sh:/data/register.sh:ro
- ../../common/manage.sh:/data/manage.sh:ro
- ../../common/check_crlf.sh:/data/check_crlf.sh:ro
- ../../common/entrypoint.sh:/data/entrypoint.sh:ro
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ=Asia/Shanghai
# Arch Linux Buildx 配置 - 使用 tonistiigi/binfmt
- ENABLE_BUILDX=true
- BINFMT_METHOD=tonistiigi
- DEFAULT_RUNNER_LABEL=archlinux:host://archlinux:latest,company-server:host://archlinux:latest,buildx-archlinux:host://archlinux:latest
# 如果需要使用代理,取消下面的注释并修改为你的代理地址
# 注意:容器内访问宿主机需要使用 host.docker.internal 或宿主机IP
# - http_proxy=http://host.docker.internal:20122
# - https_proxy=http://host.docker.internal:20122
# - HTTP_PROXY=http://host.docker.internal:20122
# - HTTPS_PROXY=http://host.docker.internal:20122
# - no_proxy=localhost,127.0.0.1
# Linux 系统需要取消下面的注释以支持 host.docker.internal
# extra_hosts:
# - "host.docker.internal:host-gateway"

View File

@ -1,21 +1,27 @@
services: services:
gitea-runner: gitea-runner:
build: . build: .
container_name: gitea-runner container_name: gitea-runner-buildx-ubuntu-22
restart: unless-stopped restart: unless-stopped
network_mode: "host" # 使用宿主机网络 network_mode: "host" # 使用宿主机网络
privileged: true privileged: true # Buildx 需要 privileged 模式
volumes: volumes:
- ./runner-data:/data - ./runner-data:/data
- ./setup.sh:/data/setup.sh:ro - ../../common/setup.sh:/data/setup.sh:ro
- ./register.sh:/data/register.sh:ro - ../../common/register.sh:/data/register.sh:ro
- ./manage.sh:/data/manage.sh:ro - ../../common/manage.sh:/data/manage.sh:ro
- ./entrypoint.sh:/data/entrypoint.sh:ro - ../../common/check_crlf.sh:/data/check_crlf.sh:ro
- ../../common/entrypoint.sh:/data/entrypoint.sh:ro
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
# Buildx 配置 - 启用多架构构建
- ENABLE_BUILDX=true
- BINFMT_METHOD=update-binfmts
- DEFAULT_RUNNER_LABEL=ubuntu-22.04:host://ubuntu:22.04,company-server:host://ubuntu:22.04,buildx-ubuntu-22:host://ubuntu:22.04
# 如果需要使用代理,取消下面的注释并修改为你的代理地址 # 如果需要使用代理,取消下面的注释并修改为你的代理地址
# 注意:容器内访问宿主机需要使用 host.docker.internal 或宿主机IP # 注意:容器内访问宿主机需要使用 host.docker.internal 或宿主机IP
# - http_proxy=http://host.docker.internal:20122 # - http_proxy=http://host.docker.internal:20122

View File

@ -1,20 +1,24 @@
services: services:
gitea-runner: gitea-runner:
build: . build: .
container_name: gitea-runner container_name: gitea-runner-standard-ubuntu-22
restart: unless-stopped restart: unless-stopped
network_mode: "host" # 使用宿主机网络 network_mode: "host" # 使用宿主机网络
volumes: volumes:
- ./runner-data:/data - ./runner-data:/data
- ./setup.sh:/data/setup.sh:ro - ../../common/setup.sh:/data/setup.sh:ro
- ./register.sh:/data/register.sh:ro - ../../common/register.sh:/data/register.sh:ro
- ./manage.sh:/data/manage.sh:ro - ../../common/manage.sh:/data/manage.sh:ro
- ./entrypoint.sh:/data/entrypoint.sh:ro - ../../common/entrypoint.sh:/data/entrypoint.sh:ro
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
# Standard 配置 - 不启用 Buildx
- ENABLE_BUILDX=false
- DEFAULT_RUNNER_LABEL=ubuntu-22.04:host://ubuntu:22.04,company-server:host://ubuntu:22.04,standard-ubuntu-22:host://ubuntu:22.04
# 如果需要使用代理,取消下面的注释并修改为你的代理地址 # 如果需要使用代理,取消下面的注释并修改为你的代理地址
# 注意:容器内访问宿主机需要使用 host.docker.internal 或宿主机IP # 注意:容器内访问宿主机需要使用 host.docker.internal 或宿主机IP
# - http_proxy=http://host.docker.internal:20122 # - http_proxy=http://host.docker.internal:20122
@ -26,4 +30,3 @@ services:
# Linux 系统需要取消下面的注释以支持 host.docker.internal # Linux 系统需要取消下面的注释以支持 host.docker.internal
# extra_hosts: # extra_hosts:
# - "host.docker.internal:host-gateway" # - "host.docker.internal:host-gateway"

View File

@ -1,134 +0,0 @@
#!/bin/bash
set -e
echo "==================================="
echo "Gitea Runner Container Starting..."
echo "==================================="
# 定义路径
PERSISTENT_BIN="/data/bin"
RUNNER_PATH="$PERSISTENT_BIN/act_runner"
SYSTEM_LINK="/usr/local/bin/act_runner"
# 创建必要目录
mkdir -p /data/runners
mkdir -p "$PERSISTENT_BIN"
mkdir -p /var/log/supervisor
mkdir -p /var/run
# 创建主 supervisor 配置文件
cat > /etc/supervisor/supervisord.conf <<EOF
[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[include]
files=/etc/supervisor/conf.d/*.conf
EOF
# 检查持久化目录中的 act_runner
if [ -f "$RUNNER_PATH" ]; then
echo "✓ Found act_runner in persistent storage"
echo " Location: $RUNNER_PATH"
# 创建软链接到系统路径(如果不存在)
if [ ! -L "$SYSTEM_LINK" ] || [ ! -e "$SYSTEM_LINK" ]; then
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
echo " Created system link: $SYSTEM_LINK -> $RUNNER_PATH"
fi
# 验证版本
RUNNER_VERSION=$("$SYSTEM_LINK" --version 2>/dev/null || echo "unknown")
echo " Version: $RUNNER_VERSION"
elif [ -f "$SYSTEM_LINK" ]; then
# 旧版本可能在系统路径,迁移到持久化目录
echo "⚠ Found act_runner in system path, migrating to persistent storage..."
cp "$SYSTEM_LINK" "$RUNNER_PATH"
chmod +x "$RUNNER_PATH"
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
echo " ✓ Migrated to: $RUNNER_PATH"
else
# 没有找到 act_runner
echo "⚠ act_runner not installed yet!"
echo ""
echo "Please run the setup script first:"
echo " docker-compose exec gitea-runner /data/setup.sh"
echo ""
echo "This will download and install the Gitea Runner to persistent storage."
echo "Container is waiting..."
# 等待 act_runner 安装
while [ ! -f "$RUNNER_PATH" ] && [ ! -f "$SYSTEM_LINK" ]; do
sleep 10
done
# 再次检查并创建链接
if [ -f "$RUNNER_PATH" ]; then
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
echo "✓ act_runner detected and linked!"
elif [ -f "$SYSTEM_LINK" ]; then
cp "$SYSTEM_LINK" "$RUNNER_PATH"
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
echo "✓ act_runner detected and migrated!"
fi
fi
# 为每个已注册的 runner 创建 supervisor 配置
echo ""
echo "Scanning for registered runners..."
RUNNER_COUNT=0
if [ -d "/data/runners" ]; then
for runner_dir in /data/runners/*/; do
if [ -d "$runner_dir" ]; then
runner_name=$(basename "$runner_dir")
if [ -f "$runner_dir/.runner" ] && [ -f "$runner_dir/config.yaml" ]; then
echo "Found runner: $runner_name"
# 创建该 runner 的 supervisor 配置
cat > "/etc/supervisor/conf.d/runner-${runner_name}.conf" <<EOF
[program:runner-${runner_name}]
command=/usr/local/bin/act_runner daemon --config ${runner_dir}/config.yaml
directory=${runner_dir}
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/runner-${runner_name}.err.log
stdout_logfile=/var/log/supervisor/runner-${runner_name}.out.log
user=root
environment=HOME="/root"
EOF
RUNNER_COUNT=$((RUNNER_COUNT + 1))
fi
fi
done
fi
if [ $RUNNER_COUNT -eq 0 ]; then
echo "⚠ No runners registered yet!"
echo ""
echo "Please run the register script to add a runner:"
echo " docker-compose exec gitea-runner /data/register.sh"
echo ""
echo "Container will continue running and wait for runners..."
fi
echo "Total runners configured: $RUNNER_COUNT"
echo ""
echo "==================================="
echo "Starting Supervisor..."
echo "==================================="
# 启动 supervisord使用主配置文件
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf

View File

@ -1,288 +0,0 @@
#!/bin/bash
echo "=========================================="
echo " Gitea Runner Management Tool "
echo "=========================================="
echo ""
# 函数:列出所有 runners
list_runners() {
echo "Registered Runners:"
echo "-------------------------------------------"
if [ ! -d "/data/runners" ] || [ -z "$(ls -A /data/runners 2>/dev/null)" ]; then
echo "No runners registered yet."
return
fi
printf "%-20s %-15s %-30s\n" "Name" "Status" "Log File"
echo "-------------------------------------------"
for runner_dir in /data/runners/*/; do
if [ -d "$runner_dir" ]; then
runner_name=$(basename "$runner_dir")
if [ -f "$runner_dir/.runner" ]; then
# 获取状态
status=$(supervisorctl status "runner-${runner_name}" 2>/dev/null | awk '{print $2}')
[ -z "$status" ] && status="NOT_LOADED"
log_file="/var/log/supervisor/runner-${runner_name}.out.log"
printf "%-20s %-15s %-30s\n" "$runner_name" "$status" "$log_file"
fi
fi
done
echo ""
}
# 函数:查看 runner 详细信息
show_runner() {
local runner_name=$1
local runner_dir="/data/runners/${runner_name}"
if [ ! -d "$runner_dir" ]; then
echo "✗ Runner '$runner_name' not found!"
return 1
fi
echo "Runner Details: $runner_name"
echo "-------------------------------------------"
echo "Directory: $runner_dir"
if [ -f "$runner_dir/config.yaml" ]; then
echo ""
echo "Configuration:"
cat "$runner_dir/config.yaml"
fi
echo ""
echo "Status:"
supervisorctl status "runner-${runner_name}" 2>/dev/null | awk '{print $2}'
echo ""
}
# 函数:删除 runner
delete_runner() {
local runner_name=$1
local runner_dir="/data/runners/${runner_name}"
if [ ! -d "$runner_dir" ]; then
echo "✗ Runner '$runner_name' not found!"
return 1
fi
echo "⚠ Warning: This will permanently delete runner '$runner_name'"
read -p "Are you sure? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Deletion cancelled."
return 0
fi
echo "Stopping runner..."
supervisorctl stop "runner-${runner_name}" 2>/dev/null || true
echo "Removing configuration..."
rm -f "/etc/supervisor/conf.d/runner-${runner_name}.conf"
echo "Deleting runner directory..."
rm -rf "$runner_dir"
echo "Updating supervisor..."
supervisorctl reread
supervisorctl update
echo ""
echo "✓ Runner '$runner_name' deleted successfully!"
}
# 函数:查看 runner 日志
logs_runner() {
local runner_name=$1
local lines=${2:-50}
local log_file="/var/log/supervisor/runner-${runner_name}.out.log"
if [ ! -f "$log_file" ]; then
echo "✗ Log file not found for runner '$runner_name'"
return 1
fi
echo "Showing last $lines lines of '$runner_name' logs:"
echo "-------------------------------------------"
tail -n "$lines" "$log_file"
}
# 函数:实时查看日志
follow_logs() {
local runner_name=$1
local log_file="/var/log/supervisor/runner-${runner_name}.out.log"
if [ ! -f "$log_file" ]; then
echo "✗ Log file not found for runner '$runner_name'"
return 1
fi
echo "Following logs for '$runner_name' (Press Ctrl+C to exit):"
echo "-------------------------------------------"
tail -f "$log_file"
}
# 函数:启动/停止/重启 runner
control_runner() {
local action=$1
local runner_name=$2
case $action in
start|stop|restart)
echo "${action^}ing runner '$runner_name'..."
supervisorctl "$action" "runner-${runner_name}"
;;
*)
echo "✗ Invalid action: $action"
return 1
;;
esac
}
# 函数:显示所有 runner 状态
status_all() {
echo "All Runners Status:"
echo "-------------------------------------------"
supervisorctl status | grep "^runner-" || echo "No runners running."
echo ""
}
# 主菜单
show_menu() {
echo "Choose an action:"
echo " 1) List all runners"
echo " 2) Show runner details"
echo " 3) Add new runner"
echo " 4) Delete runner"
echo " 5) Start runner"
echo " 6) Stop runner"
echo " 7) Restart runner"
echo " 8) View runner logs"
echo " 9) Follow runner logs (real-time)"
echo " 10) Show all runners status"
echo " 0) Exit"
echo ""
}
# 主程序
if [ $# -eq 0 ]; then
# 交互模式
while true; do
show_menu
read -p "Enter your choice: " choice
echo ""
case $choice in
1)
list_runners
;;
2)
read -p "Enter runner name: " runner_name
show_runner "$runner_name"
;;
3)
echo "Starting registration process..."
/data/register.sh
;;
4)
read -p "Enter runner name to delete: " runner_name
delete_runner "$runner_name"
;;
5)
read -p "Enter runner name to start: " runner_name
control_runner start "$runner_name"
;;
6)
read -p "Enter runner name to stop: " runner_name
control_runner stop "$runner_name"
;;
7)
read -p "Enter runner name to restart: " runner_name
control_runner restart "$runner_name"
;;
8)
read -p "Enter runner name: " runner_name
read -p "Number of lines (default 50): " lines
logs_runner "$runner_name" "${lines:-50}"
;;
9)
read -p "Enter runner name: " runner_name
follow_logs "$runner_name"
;;
10)
status_all
;;
0)
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid choice!"
;;
esac
echo ""
read -p "Press Enter to continue..."
clear
done
else
# 命令行模式
case $1 in
list|ls)
list_runners
;;
show|info)
show_runner "$2"
;;
add|register)
/data/register.sh
;;
delete|rm|remove)
delete_runner "$2"
;;
start)
control_runner start "$2"
;;
stop)
control_runner stop "$2"
;;
restart)
control_runner restart "$2"
;;
logs)
logs_runner "$2" "${3:-50}"
;;
follow)
follow_logs "$2"
;;
status)
status_all
;;
*)
echo "Usage: $0 [command] [runner_name]"
echo ""
echo "Commands:"
echo " list - List all runners"
echo " show <name> - Show runner details"
echo " add - Add new runner"
echo " delete <name> - Delete a runner"
echo " start <name> - Start a runner"
echo " stop <name> - Stop a runner"
echo " restart <name> - Restart a runner"
echo " logs <name> [lines] - View runner logs"
echo " follow <name> - Follow runner logs (real-time)"
echo " status - Show all runners status"
echo ""
echo "Or run without arguments for interactive mode."
exit 1
;;
esac
fi

View File

@ -1,141 +0,0 @@
#!/bin/bash
echo "=========================================="
echo " Gitea Runner Installation Script "
echo "=========================================="
echo ""
# 持久化安装路径
INSTALL_PATH="/data/bin/act_runner"
SYSTEM_PATH="/usr/local/bin/act_runner"
# 创建目录
mkdir -p /data/bin
# 检查是否已安装
if [ -f "$INSTALL_PATH" ]; then
CURRENT_VERSION=$($INSTALL_PATH --version 2>/dev/null | grep -oP 'version \K[0-9.]+' || echo "unknown")
echo "⚠ act_runner already installed (version: $CURRENT_VERSION)"
echo " Location: $INSTALL_PATH"
echo ""
read -p "Do you want to reinstall/upgrade? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Installation cancelled."
exit 0
fi
rm -f "$INSTALL_PATH" "$SYSTEM_PATH"
fi
# 获取要安装的版本
echo "Available versions: https://dl.gitea.com/act_runner/"
echo ""
read -p "Enter version to install (default: 0.2.13): " RUNNER_VERSION
RUNNER_VERSION=${RUNNER_VERSION:-0.2.13}
ARCH=$(uname -m)
case "$ARCH" in
x86_64)
RUNNER_ARCH="amd64"
;;
aarch64|arm64)
RUNNER_ARCH="arm64"
;;
armv7l)
RUNNER_ARCH="arm-7"
;;
*)
echo "⚠ Unknown architecture: $ARCH"
RUNNER_ARCH="arm64"
;;
esac
# 确认架构
echo ""
echo "Detected architecture: $ARCH -> $RUNNER_ARCH"
read -p "Is this correct? (Y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo ""
echo "Available architectures:"
echo " 1. amd64 (x86_64)"
echo " 2. arm64 (aarch64)"
echo " 3. arm-7 (armv7l)"
read -p "Select architecture (1-3): " ARCH_CHOICE
case "$ARCH_CHOICE" in
1) RUNNER_ARCH="amd64" ;;
2) RUNNER_ARCH="arm64" ;;
3) RUNNER_ARCH="arm-7" ;;
*)
echo "Invalid choice. Exiting."
exit 1
;;
esac
fi
DOWNLOAD_URL="https://dl.gitea.com/act_runner/${RUNNER_VERSION}/act_runner-${RUNNER_VERSION}-linux-${RUNNER_ARCH}"
echo ""
echo "Download Configuration:"
echo " Version: $RUNNER_VERSION"
echo " Architecture: $RUNNER_ARCH"
echo " URL: $DOWNLOAD_URL"
echo " Install Location: $INSTALL_PATH (persistent)"
echo ""
read -p "Proceed with download? (Y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo "Installation cancelled."
exit 0
fi
echo ""
echo "Downloading act_runner..."
echo ""
# 下载到持久化目录
if curl -L "$DOWNLOAD_URL" -o "$INSTALL_PATH"; then
chmod +x "$INSTALL_PATH"
# 同时创建软链接到系统路径
ln -sf "$INSTALL_PATH" "$SYSTEM_PATH"
# 验证安装
if $INSTALL_PATH --version; then
echo ""
echo "=========================================="
echo "✓ act_runner installed successfully!"
echo "=========================================="
echo ""
echo "Version: $($INSTALL_PATH --version)"
echo "Location: $INSTALL_PATH (persistent storage)"
echo ""
echo "Next steps:"
echo "1. Register the runner:"
echo " docker-compose exec gitea-runner /data/register.sh"
echo ""
echo "2. Restart the container:"
echo " docker-compose restart"
echo ""
echo "Note: act_runner is saved in persistent storage"
echo " and will survive container restarts."
echo ""
else
echo ""
echo "✗ Installation verification failed!"
rm -f "$INSTALL_PATH" "$SYSTEM_PATH"
exit 1
fi
else
echo ""
echo "✗ Download failed!"
echo "Please check:"
echo " - Internet connection"
echo " - Version number is correct: $RUNNER_VERSION"
echo " - Architecture is correct: $RUNNER_ARCH"
echo " - URL is accessible: $DOWNLOAD_URL"
echo ""
echo "You can check available versions at:"
echo " https://dl.gitea.com/act_runner/"
exit 1
fi