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

168 lines
5.1 KiB
Markdown

---
name: gitea-deploy
description: 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".
metadata:
author: common-skills
version: "1.0"
compatibility:
tools:
- execute_bash
requirements:
- 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
```bash
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
```bash
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
```bash
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:
```bash
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):
```bash
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:
```bash
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:
```bash
# 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
```bash
# 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:
```bash
GIT_SSH_COMMAND="ssh -i <key_path> -o StrictHostKeyChecking=no" git push -u gitea --all
```
### 8. Verify and Report
```bash
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.