Files
common-skills/skills/gitea-deploy/SKILL.md
T
Team f20bc770f5 feat: add gitea-deploy skill, tools, and sdlc foreground service rule
- skills/gitea-deploy/: new skill for Gitea deployment automation
- tools/: shared utility scripts
- skills/sdlc/SKILL.md: add Foreground Service Rule for long-running
  processes (background start + readiness polling pattern)
2026-04-25 14:11:58 +08:00

5.1 KiB

name, description, metadata, compatibility
name description metadata compatibility
gitea-deploy Automates deploying a self-hosted Gitea Git server on a VPS using Docker, then pushes the current project to it. Use when the user wants to self-host a Git server, set up Gitea on a VPS, push a project to a private Git server, or migrate away from GitHub/GitLab. Triggers on phrases like "deploy gitea", "self-host git", "setup git server", "push to my vps", "host my own git", "搭建git服务器", "自托管git", "部署gitea", "推送到vps".
author version
common-skills 1.0
tools requirements
execute_bash
SSH access to a VPS (Linux)
Docker available or installable on VPS
git initialized in the local project

Gitea Deploy

Automate deploying a self-hosted Gitea instance on a VPS and pushing the current project to it.

Inputs

Collect from the user before starting:

Field Example
VPS host 123.45.67.89 or git.example.com
SSH user root or ubuntu
SSH private key path ~/.ssh/id_rsa
Gitea admin username admin
Gitea admin password (user provides, never log it)
Gitea web port 3000 (default)
SSH port for Gitea 2222 (default)
Repository name defaults to current directory name

If any field is missing, ask for it. Never guess credentials.

Workflow

1. Validate Local Prerequisites

git rev-parse --is-inside-work-tree   # confirm we're in a git repo
git status --short                    # show current state

If not a git repo, run git init && git add -A && git commit -m "chore: initial commit" after confirming with the user.

2. Test SSH Connectivity

ssh -i <key_path> -o StrictHostKeyChecking=no -o ConnectTimeout=10 <user>@<host> "echo OK"

If this fails, stop and report the error. Do not proceed.

3. Check / Install Docker on VPS

ssh -i <key_path> <user>@<host> "docker --version 2>/dev/null || (curl -fsSL https://get.docker.com | sh)"

Report the Docker version found or installed.

4. Deploy Gitea via Docker Compose

Upload and run a docker-compose.yml on the VPS:

ssh -i <key_path> <user>@<host> "mkdir -p ~/gitea"

cat <<'EOF' | ssh -i <key_path> <user>@<host> "cat > ~/gitea/docker-compose.yml"
services:
  gitea:
    image: gitea/gitea:latest
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
    ports:
      - "<web_port>:3000"
      - "<ssh_port>:22"
    volumes:
      - ./data:/data
EOF

ssh -i <key_path> <user>@<host> "cd ~/gitea && docker compose up -d"

5. Wait for Gitea to Be Ready

Poll until the health endpoint responds (max 60 seconds):

ssh -i <key_path> <user>@<host> \
  "for i in \$(seq 1 12); do curl -sf http://localhost:<web_port>/api/healthz && break || sleep 5; done"

If not ready after 60 s, show the container logs:

ssh -i <key_path> <user>@<host> "docker logs gitea-gitea-1 --tail 30"

6. Initialize Gitea via API

Create the admin user and the target repository using the Gitea API:

# Create admin user (first-time setup)
ssh -i <key_path> <user>@<host> \
  "docker exec gitea-gitea-1 gitea admin user create \
    --username <admin_user> --password '<admin_pass>' \
    --email admin@localhost --admin --must-change-password=false"

# Create repository
curl -sf -X POST "http://<host>:<web_port>/api/v1/user/repos" \
  -u "<admin_user>:<admin_pass>" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"<repo_name>\",\"private\":true,\"auto_init\":false}"

If the admin user already exists, skip creation (exit code 1 is acceptable).

7. Configure Local Git Remote and Push

# Add or update remote
git remote remove gitea 2>/dev/null || true
git remote add gitea "ssh://git@<host>:<ssh_port>/<admin_user>/<repo_name>.git"

# Push all branches
git push -u gitea --all
git push gitea --tags

If push fails due to host key, add -o StrictHostKeyChecking=no to the SSH command used by git:

GIT_SSH_COMMAND="ssh -i <key_path> -o StrictHostKeyChecking=no" git push -u gitea --all

8. Verify and Report

curl -sf "http://<host>:<web_port>/api/v1/repos/<admin_user>/<repo_name>" \
  -u "<admin_user>:<admin_pass>" | python3 -m json.tool

Report to the user:

  • Gitea web URL: http://<host>:<web_port>
  • Repository URL: http://<host>:<web_port>/<admin_user>/<repo_name>
  • SSH clone URL: ssh://git@<host>:<ssh_port>/<admin_user>/<repo_name>.git

Edge Cases

  • Docker already installed: Step 3 detects and skips installation.
  • Gitea already running: Step 4 docker compose up -d is idempotent; existing containers are reused.
  • Admin user already exists: Step 6 catches the error and continues.
  • Remote gitea already exists: Step 7 removes and re-adds it.
  • No commits yet: Step 1 detects and offers to create an initial commit.

Security Notes

  • Never print the admin password in command output. Reference it as <admin_pass>.
  • Use -o StrictHostKeyChecking=no only for the initial setup; advise the user to remove it afterward.
  • Recommend the user change the admin password after first login.
  • For production use, suggest adding Nginx + Let's Encrypt for HTTPS.