- 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)
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". |
|
|
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 -dis idempotent; existing containers are reused. - Admin user already exists: Step 6 catches the error and continues.
- Remote
giteaalready 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=noonly 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.