f20bc770f5
- 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)
168 lines
5.1 KiB
Markdown
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.
|