Compare commits
3 Commits
5ef7f18f77
...
e015f01cd6
| Author | SHA1 | Date | |
|---|---|---|---|
| e015f01cd6 | |||
| e190825135 | |||
| 9a764fafb4 |
85
.gitea/workflows/deploy.yml
Normal file
85
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
name: Deployment CI/CD
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: qlockify-deploy
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends bash ca-certificates git python3 python3-yaml
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
env:
|
||||||
|
REPO_URL: ${{ gitea.server_url }}/${{ gitea.repository }}.git
|
||||||
|
REPO_SHA: ${{ gitea.sha }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
WORKSPACE: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
mkdir -p "$WORKSPACE"
|
||||||
|
cd "$WORKSPACE"
|
||||||
|
git init
|
||||||
|
git remote add origin "$REPO_URL"
|
||||||
|
git -c http.extraHeader="Authorization: Bearer $GITEA_TOKEN" fetch --depth 1 origin "$REPO_SHA"
|
||||||
|
git checkout --detach FETCH_HEAD
|
||||||
|
|
||||||
|
- name: Validate deployment script
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: bash -n scripts/deploy.sh
|
||||||
|
|
||||||
|
- name: Validate docker-compose.yml syntax
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
python3 - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
path = Path("docker-compose.yml")
|
||||||
|
data = yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||||
|
assert isinstance(data, dict), "docker-compose.yml must contain a mapping at the top level"
|
||||||
|
assert "services" in data, "docker-compose.yml must define services"
|
||||||
|
PY
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
if: github.event_name == 'push' && github.ref_name == 'main'
|
||||||
|
needs:
|
||||||
|
- validate
|
||||||
|
runs-on: qlockify-deploy
|
||||||
|
steps:
|
||||||
|
- name: Install SSH client
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends bash openssh-client
|
||||||
|
|
||||||
|
- name: Configure SSH
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||||
|
run: |
|
||||||
|
install -m 700 -d ~/.ssh
|
||||||
|
printf '%s\n' "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
|
||||||
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
|
printf '%s\n' "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||||
|
chmod 644 ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Deploy updated infrastructure
|
||||||
|
env:
|
||||||
|
DEPLOY_HOST: ${{ vars.DEPLOY_HOST }}
|
||||||
|
DEPLOY_PORT: ${{ vars.DEPLOY_PORT }}
|
||||||
|
DEPLOY_USER: ${{ vars.DEPLOY_USER }}
|
||||||
|
DEPLOY_PATH: ${{ vars.DEPLOY_PATH }}
|
||||||
|
DEPLOY_BRANCH: ${{ vars.DEPLOY_BRANCH }}
|
||||||
|
BACKEND_BRANCH: ${{ vars.BACKEND_BRANCH }}
|
||||||
|
FRONTEND_BRANCH: ${{ vars.FRONTEND_BRANCH }}
|
||||||
|
run: |
|
||||||
|
ssh -p "${DEPLOY_PORT:-22}" "${DEPLOY_USER}@${DEPLOY_HOST}" \
|
||||||
|
"DEPLOY_ROOT='${DEPLOY_PATH}' DEPLOY_BRANCH='${DEPLOY_BRANCH}' BACKEND_BRANCH='${BACKEND_BRANCH}' FRONTEND_BRANCH='${FRONTEND_BRANCH}' bash '${DEPLOY_PATH}/scripts/deploy.sh' deployment"
|
||||||
155
README.md
155
README.md
@@ -235,6 +235,161 @@ Stop everything:
|
|||||||
docker compose down
|
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
|
## Scope Boundary
|
||||||
|
|
||||||
This repo should document:
|
This repo should document:
|
||||||
|
|||||||
@@ -2,21 +2,24 @@
|
|||||||
ENVIRONMENT=development
|
ENVIRONMENT=development
|
||||||
DEBUG=True
|
DEBUG=True
|
||||||
|
|
||||||
# Django Core
|
# Django Core
|
||||||
DJANGO_SETTINGS_MODULE=config.settings
|
DJANGO_SETTINGS_MODULE=config.settings
|
||||||
DJANGO_SECRET_KEY=
|
DJANGO_SECRET_KEY=
|
||||||
DJANGO_ALLOWED_HOSTS=api.qlockify.ir,qlockify.ir,www.qlockify.ir
|
DJANGO_ALLOWED_HOSTS=api.qlockify.ir,qlockify.ir,www.qlockify.ir
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
POSTGRES_DB=app_db
|
POSTGRES_DB=app_db
|
||||||
POSTGRES_USER=app_user
|
POSTGRES_USER=app_user
|
||||||
POSTGRES_PASSWORD=app_password
|
POSTGRES_PASSWORD=app_password
|
||||||
POSTGRES_HOST=db
|
POSTGRES_HOST=db
|
||||||
POSTGRES_PORT=5432
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
# CORS / CSRF
|
# CORS / CSRF
|
||||||
CORS_ALLOWED_ORIGINS=https://qlockify.ir,https://www.qlockify.ir
|
CORS_ALLOWED_ORIGINS=https://qlockify.ir,https://www.qlockify.ir
|
||||||
CSRF_TRUSTED_ORIGINS=https://api.qlockify.ir,https://qlockify.ir,https://www.qlockify.ir
|
CSRF_TRUSTED_ORIGINS=https://api.qlockify.ir,https://qlockify.ir,https://www.qlockify.ir
|
||||||
|
|
||||||
|
DJANGO_CORS_ALLOWED_ORIGINS=https://qlockify.ir,https://www.qlockify.ir
|
||||||
|
DJANGO_CSRF_TRUSTED_ORIGINS=https://api.qlockify.ir,https://qlockify.ir,https://www.qlockify.ir
|
||||||
|
|
||||||
# JWT
|
# JWT
|
||||||
ACCESS_TOKEN_LIFETIME=5
|
ACCESS_TOKEN_LIFETIME=5
|
||||||
@@ -30,15 +33,19 @@ JWT_ALGORITHM=HS256
|
|||||||
|
|
||||||
# Redis / Celery
|
# Redis / Celery
|
||||||
REDIS_URL=redis://redis:6379/0
|
REDIS_URL=redis://redis:6379/0
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_PASSWORD=
|
REDIS_PASSWORD=
|
||||||
CELERY_BROKER_URL=redis://redis:6379/0
|
CELERY_BROKER_URL=redis://redis:6379/0
|
||||||
CELERY_RESULT_BACKEND=redis://redis:6379/0
|
CELERY_RESULT_BACKEND=redis://redis:6379/0
|
||||||
|
|
||||||
# Timzone / Language
|
# Timzone / Language
|
||||||
LANGUAGE_CODE=en-us
|
LANGUAGE_CODE=en-us
|
||||||
TIME_ZONE=Asia/Tehran
|
TIME_ZONE=Asia/Tehran
|
||||||
|
|
||||||
SMS_APIKEY=
|
SMS_APIKEY=
|
||||||
BASE_URL=https://api.qlockify.ir
|
BASE_URL=https://api.qlockify.ir
|
||||||
|
GOOGLE_OAUTH_CLIENT_ID=
|
||||||
|
GOOGLE_OAUTH_CLIENT_SECRET=
|
||||||
|
GOOGLE_OAUTH_REDIRECT_URI=https://qlockify.ir/api/users/oauth/google/callback/
|
||||||
|
GOOGLE_OAUTH_FRONTEND_CALLBACK_URL=https://qlockify.ir/auth/google/callback
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
VITE_API_BASE_URL=https://api.qlockify.ir
|
VITE_API_BASE_URL=https://qlockify.ir
|
||||||
|
|||||||
@@ -5,13 +5,6 @@ server {
|
|||||||
return 301 https://qlockify.ir$request_uri;
|
return 301 https://qlockify.ir$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name api.qlockify.ir;
|
|
||||||
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
http2 on;
|
http2 on;
|
||||||
@@ -42,58 +35,7 @@ server {
|
|||||||
client_max_body_size 100M;
|
client_max_body_size 100M;
|
||||||
sendfile on;
|
sendfile on;
|
||||||
|
|
||||||
location /api/ {
|
# Static and Media files
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /admin/ {
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /docs {
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /redoc {
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /openapi.json {
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /static/ {
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /media/ {
|
|
||||||
return 301 https://api.qlockify.ir$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://frontend:80;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
http2 on;
|
|
||||||
server_name api.qlockify.ir;
|
|
||||||
|
|
||||||
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
ssl_session_timeout 1d;
|
|
||||||
ssl_session_cache shared:SSL:10m;
|
|
||||||
|
|
||||||
client_max_body_size 100M;
|
|
||||||
sendfile on;
|
|
||||||
|
|
||||||
location /static/ {
|
location /static/ {
|
||||||
alias /usr/share/nginx/html/static/;
|
alias /usr/share/nginx/html/static/;
|
||||||
expires 30d;
|
expires 30d;
|
||||||
@@ -106,6 +48,7 @@ server {
|
|||||||
access_log off;
|
access_log off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Protect API Documentation with Basic Auth
|
||||||
location ~ ^/(docs|redoc|openapi.json|api/docs|api/redoc|api/openapi.json|api/v1/docs) {
|
location ~ ^/(docs|redoc|openapi.json|api/docs|api/redoc|api/openapi.json|api/v1/docs) {
|
||||||
auth_basic "Restricted API Documentation";
|
auth_basic "Restricted API Documentation";
|
||||||
auth_basic_user_file /etc/nginx/.htpasswd;
|
auth_basic_user_file /etc/nginx/.htpasswd;
|
||||||
@@ -147,4 +90,12 @@ server {
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://frontend:80;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
scripts/deploy.sh
Normal file
92
scripts/deploy.sh
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
deploy.sh <component>
|
||||||
|
|
||||||
|
Components:
|
||||||
|
deployment Update the deployment repo and rebuild nginx + app services
|
||||||
|
backend Update the backend repo and rebuild backend + celery services
|
||||||
|
frontend Update the frontend repo and rebuild frontend
|
||||||
|
full Update all three repos and rebuild all app services
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf '[deploy] %s\n' "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_git_repo() {
|
||||||
|
local path="$1"
|
||||||
|
if [[ ! -d "$path/.git" ]]; then
|
||||||
|
printf 'Expected git repository at %s\n' "$path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_repo() {
|
||||||
|
local path="$1"
|
||||||
|
local branch="$2"
|
||||||
|
|
||||||
|
require_git_repo "$path"
|
||||||
|
log "Syncing $path -> origin/$branch"
|
||||||
|
git -C "$path" fetch --prune origin
|
||||||
|
git -C "$path" checkout "$branch"
|
||||||
|
git -C "$path" reset --hard "origin/$branch"
|
||||||
|
}
|
||||||
|
|
||||||
|
compose() {
|
||||||
|
docker compose -f "$DEPLOY_ROOT/docker-compose.yml" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPONENT="${1:-}"
|
||||||
|
if [[ -z "$COMPONENT" ]]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEPLOY_ROOT="${DEPLOY_ROOT:-$HOME/qlockify-deployment}"
|
||||||
|
DEPLOY_BRANCH="${DEPLOY_BRANCH:-main}"
|
||||||
|
BACKEND_BRANCH="${BACKEND_BRANCH:-main}"
|
||||||
|
FRONTEND_BRANCH="${FRONTEND_BRANCH:-main}"
|
||||||
|
|
||||||
|
DEPLOY_REPO_PATH="$DEPLOY_ROOT"
|
||||||
|
BACKEND_REPO_PATH="$DEPLOY_ROOT/backend/qlockify-backend-deployment"
|
||||||
|
FRONTEND_REPO_PATH="$DEPLOY_ROOT/frontend/qlockify-frontend-deployment"
|
||||||
|
|
||||||
|
cd "$DEPLOY_ROOT"
|
||||||
|
|
||||||
|
case "$COMPONENT" in
|
||||||
|
deployment)
|
||||||
|
sync_repo "$DEPLOY_REPO_PATH" "$DEPLOY_BRANCH"
|
||||||
|
compose config -q
|
||||||
|
compose up -d --build nginx backend frontend celery celery-beat
|
||||||
|
;;
|
||||||
|
backend)
|
||||||
|
sync_repo "$DEPLOY_REPO_PATH" "$DEPLOY_BRANCH"
|
||||||
|
sync_repo "$BACKEND_REPO_PATH" "$BACKEND_BRANCH"
|
||||||
|
compose config -q
|
||||||
|
compose up -d --build backend celery celery-beat
|
||||||
|
;;
|
||||||
|
frontend)
|
||||||
|
sync_repo "$DEPLOY_REPO_PATH" "$DEPLOY_BRANCH"
|
||||||
|
sync_repo "$FRONTEND_REPO_PATH" "$FRONTEND_BRANCH"
|
||||||
|
compose config -q
|
||||||
|
compose up -d --build frontend
|
||||||
|
;;
|
||||||
|
full)
|
||||||
|
sync_repo "$DEPLOY_REPO_PATH" "$DEPLOY_BRANCH"
|
||||||
|
sync_repo "$BACKEND_REPO_PATH" "$BACKEND_BRANCH"
|
||||||
|
sync_repo "$FRONTEND_REPO_PATH" "$FRONTEND_BRANCH"
|
||||||
|
compose config -q
|
||||||
|
compose up -d --build nginx backend frontend celery celery-beat
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
compose ps
|
||||||
Reference in New Issue
Block a user