feat(deploy): add gitea actions deployment pipeline
This commit is contained in:
155
README.md
155
README.md
@@ -235,6 +235,161 @@ Stop everything:
|
||||
docker compose down
|
||||
```
|
||||
|
||||
## CI/CD with Gitea Actions
|
||||
|
||||
This repository now ships with a Gitea Actions deployment workflow in:
|
||||
|
||||
- `.gitea/workflows/deploy.yml`
|
||||
|
||||
The backend and frontend repositories each ship with their own workflow files:
|
||||
|
||||
- backend: `.gitea/workflows/backend.yml`
|
||||
- frontend: `.gitea/workflows/frontend.yml`
|
||||
|
||||
Deployment behavior:
|
||||
|
||||
- backend repo push to `main`: runs backend CI, then updates the backend checkout on the server and rebuilds `backend`, `celery`, and `celery-beat`
|
||||
- frontend repo push to `main`: runs frontend lint/build, then updates the frontend checkout on the server and rebuilds `frontend`
|
||||
- deployment repo push to `main`: validates deployment files, then updates the deployment checkout on the server and rebuilds `nginx` plus the app services
|
||||
|
||||
The remote deploy entrypoint is:
|
||||
|
||||
- `./scripts/deploy.sh`
|
||||
|
||||
### One-Time Server Bootstrap
|
||||
|
||||
Before Actions can deploy automatically, make sure the server is prepared once.
|
||||
|
||||
1. Clone all three repositories on the server into the expected layout:
|
||||
|
||||
```text
|
||||
~/qlockify-deployment
|
||||
~/qlockify-deployment/backend/qlockify-backend-deployment
|
||||
~/qlockify-deployment/frontend/qlockify-frontend-deployment
|
||||
```
|
||||
|
||||
2. Make sure the server can `git fetch` all three repositories non-interactively.
|
||||
|
||||
Recommended approach:
|
||||
|
||||
- add a deploy SSH key on the server
|
||||
- add the public key to Gitea as a deploy key or a machine-user SSH key
|
||||
- switch the server-side git remotes to SSH URLs
|
||||
|
||||
3. Pull the latest deployment repo once so the server has `scripts/deploy.sh`.
|
||||
|
||||
4. Make the deploy script executable:
|
||||
|
||||
```bash
|
||||
chmod +x ~/qlockify-deployment/scripts/deploy.sh
|
||||
```
|
||||
|
||||
5. Make sure the deploy user can run Docker Compose on the server.
|
||||
|
||||
### Gitea Runner Setup
|
||||
|
||||
Gitea Actions requires a trusted runner. Gitea's official docs describe the runner and label model here:
|
||||
|
||||
- Actions overview: `https://docs.gitea.com/usage/actions/overview`
|
||||
- Act Runner: `https://docs.gitea.com/usage/actions/act-runner`
|
||||
|
||||
Recommended label setup for this project:
|
||||
|
||||
```text
|
||||
qlockify-python:docker://python:3.14-bookworm
|
||||
qlockify-node:docker://node:22-bookworm
|
||||
qlockify-deploy:docker://ubuntu:24.04
|
||||
```
|
||||
|
||||
Example non-interactive runner registration:
|
||||
|
||||
```bash
|
||||
./act_runner register \
|
||||
--no-interactive \
|
||||
--instance https://git.amiirkhl.ir \
|
||||
--token <runner_registration_token> \
|
||||
--name qlockify-runner \
|
||||
--labels "qlockify-python:docker://python:3.14-bookworm,qlockify-node:docker://node:22-bookworm,qlockify-deploy:docker://ubuntu:24.04"
|
||||
```
|
||||
|
||||
Then start the runner daemon:
|
||||
|
||||
```bash
|
||||
./act_runner daemon
|
||||
```
|
||||
|
||||
### Gitea Secrets
|
||||
|
||||
Create these Actions secrets either at the `Qlockify` organization level or per repository.
|
||||
|
||||
- `SSH_PRIVATE_KEY`
|
||||
- private key used by the workflow to SSH into the deployment server
|
||||
- `SSH_KNOWN_HOSTS`
|
||||
- output of:
|
||||
|
||||
```bash
|
||||
ssh-keyscan -H <your-server-hostname-or-ip>
|
||||
```
|
||||
|
||||
Do not create `GITEA_TOKEN` manually. Gitea provides a built-in job token and exposes it as `${{ secrets.GITEA_TOKEN }}`. See:
|
||||
|
||||
- `https://docs.gitea.com/usage/actions/token-permissions`
|
||||
|
||||
### Gitea Variables
|
||||
|
||||
Create these Actions variables in the Gitea UI:
|
||||
|
||||
- `DEPLOY_HOST`
|
||||
- `DEPLOY_PORT`
|
||||
- `DEPLOY_USER`
|
||||
- `DEPLOY_PATH`
|
||||
- `DEPLOY_BRANCH`
|
||||
- `BACKEND_BRANCH`
|
||||
- `FRONTEND_BRANCH`
|
||||
|
||||
Suggested values for your current server layout:
|
||||
|
||||
```text
|
||||
DEPLOY_HOST=h9arjloaye
|
||||
DEPLOY_PORT=22
|
||||
DEPLOY_USER=ubuntu
|
||||
DEPLOY_PATH=/home/ubuntu/qlockify-deployment
|
||||
DEPLOY_BRANCH=main
|
||||
BACKEND_BRANCH=main
|
||||
FRONTEND_BRANCH=main
|
||||
```
|
||||
|
||||
Gitea variables are available in workflows through `${{ vars.NAME }}`. Gitea documents that here:
|
||||
|
||||
- `https://docs.gitea.com/usage/actions/actions-variables`
|
||||
|
||||
### Recommended UI Setup
|
||||
|
||||
If all three repositories live under the same `Qlockify` organization, the cleanest setup is:
|
||||
|
||||
1. Add one organization-level runner to `Qlockify`
|
||||
2. Add organization-level variables for the shared deploy target
|
||||
3. Add organization-level secrets for the SSH key and known hosts
|
||||
|
||||
This keeps the three repositories consistent and avoids copying the same values three times.
|
||||
|
||||
### First Deploy Check
|
||||
|
||||
After creating the runner, variables, and secrets:
|
||||
|
||||
1. push the deployment repository first
|
||||
2. confirm the deployment workflow succeeds
|
||||
3. then push backend or frontend changes and confirm their repo-specific workflows deploy only the affected services
|
||||
|
||||
If a workflow fails on the server step, first check:
|
||||
|
||||
- runner logs
|
||||
- repository Actions logs
|
||||
- `docker compose logs -f backend`
|
||||
- `docker compose logs -f frontend`
|
||||
- `docker compose logs -f celery`
|
||||
- `docker compose logs -f celery-beat`
|
||||
|
||||
## Scope Boundary
|
||||
|
||||
This repo should document:
|
||||
|
||||
Reference in New Issue
Block a user