Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
SUPABASE_URL="YOUR_SUPABASE_URL"
SUPABASE_KEY="YOUR_SUPABASE_ANON_KEY"
SUPABASE_DB_URL="postgresql://postgres:postgres@supabase:5432/postgres"
REDIS_URL="redis://redis:6379/0"
STORAGE_BUCKET="documents"
# MySQL
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_USER=docuser
MYSQL_PASSWORD=docpass123
MYSQL_DATABASE=doc_automation

# Redis
REDIS_URL=redis://redis:6379/0

# Storage
STORAGE_BUCKET=documents

# Auth
JWT_SECRET_KEY=doc_auto_jwt_secret_2026_xK9mN3pQ
API_KEY=Test_apikey_doc_automation_2026
54 changes: 54 additions & 0 deletions .github/workflows/deploy-dokku.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Deploy to Dokku (staging)

on:
push:
branches: [ develop ]
workflow_dispatch:
inputs:
trigger:
description: 'Manual trigger for staging deploy'
required: false

jobs:
deploy-staging:
name: Deploy → Staging
runs-on: ubuntu-latest
environment: stag
env:
DOKKU_HOST: ${{ secrets.DOKKU_HOST_STAG }}
DOKKU_APP: ${{ secrets.DOKKU_APP_STAG }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY_STAG }}
DB_URL: ${{ secrets.DB_URL_STAG }}
API_KEY: ${{ secrets.API_KEY_STAG }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Start SSH agent and add key
uses: webfactory/ssh-agent@v0.5.4
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_STAG }}

- name: Add Dokku host to known_hosts
run: |
mkdir -p ~/.ssh
ssh-keyscan -H ${{ secrets.DOKKU_HOST_STAG }} >> ~/.ssh/known_hosts

- name: Push to Dokku remote (staging)
run: |
git remote add dokku dokku@${{ secrets.DOKKU_HOST_STAG }}:${{ secrets.DOKKU_APP_STAG }} || true
git push dokku HEAD:master --force

- name: Set Dokku config from secrets (staging)
run: |
CMD=""
if [ -n "${DB_URL}" ]; then CMD="$CMD DATABASE_URL='${DB_URL}'"; fi
if [ -n "${API_KEY}" ]; then CMD="$CMD API_KEY='${API_KEY}'"; fi
if [ -n "$CMD" ]; then
ssh dokku@${{ secrets.DOKKU_HOST_STAG }} "dokku config:set ${{ secrets.DOKKU_APP_STAG }} $CMD"
else
echo "No env secrets provided to set on Dokku"
fi
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.env
__pycache__
storage
storage
deploy_key
deploy_key.pub
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: uvicorn app.main:app --host 0.0.0.0 --port $PORT
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,35 @@ Chi tiết API và ví dụ curl xem tại file api-docs.html hoặc truy cập
- Trang landing: `/landing.html`
- Swagger UI: `/docs`
- Cấu hình Docker: app.Dockerfile, `docker-compose.yml`

## CI/CD — Deploy to Dokku (staging)

This repository includes an optional GitHub Actions workflow to deploy to a Dokku host when code is pushed to `main`.

Required GitHub secrets:
- `SSH_PRIVATE_KEY` — private SSH key for deployment (add its public key to the Dokku server)
- `DOKKU_HOST` — Dokku server hostname (for example `stag.devhub.ai.vn`)
- `DOKKU_APP` — Dokku app name (for example `flowpdf-staging`)

Quick setup:

1. Generate a deploy key locally:

```bash
ssh-keygen -t ed25519 -C "github-actions@your-repo" -f deploy_key -N ""
```

2. Add the public key to Dokku (on the Dokku host):

```bash
# copy the public key contents and on the dokku host run:
ssh dokku@stag.devhub.ai.vn "dokku ssh-keys:add github-actions '$(cat deploy_key.pub)'"
```

3. In your GitHub repository settings, add the private key (`deploy_key`) as the `SSH_PRIVATE_KEY` secret. Also add `DOKKU_HOST` and `DOKKU_APP` secrets.

4. The workflow `.github/workflows/deploy-dokku.yml` will run on pushes to `main` and push the repository to the Dokku remote. Dokku will build and deploy the app.

Notes:
- Make sure the Dokku app exists: `ssh dokku@${DOKKU_HOST} dokku apps:create ${DOKKU_APP}`
- If you prefer image-based deploys, adapt the workflow to build and push a Docker image and have Dokku deploy that image.
60 changes: 60 additions & 0 deletions docker/docker-compose-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
version: "3.9"
services:
mysql:
image: mysql:8.0
container_name: doc_mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass123
MYSQL_DATABASE: doc_automation
MYSQL_USER: docuser
MYSQL_PASSWORD: docpass123
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

phpmyadmin:
image: phpmyadmin:5
container_name: doc_phpmyadmin
restart: unless-stopped
depends_on:
- mysql
ports:
- "8080:80"
environment:
PMA_HOST: mysql
PMA_PORT: 3306

app:
build:
context: ..
dockerfile: docker/app.Dockerfile
container_name: doc_app
restart: unless-stopped
depends_on:
- mysql
- redis
environment:
- DB_HOST=mysql
- DB_PORT=3306
- DB_USER=docuser
- DB_PASSWORD=docpass123
- DB_NAME=doc_automation
- REDIS_HOST=redis
- REDIS_PORT=6379
ports:
- "8000:8000"
volumes:
- ../:/app
redis:
image: redis:7-alpine
container_name: doc_redis
restart: unless-stopped
ports:
- "6379:6379"

volumes:
mysql_data:
4 changes: 1 addition & 3 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ services:
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_USER: root
PMA_PASSWORD: rootpass123

app:
build:
Expand All @@ -48,7 +46,7 @@ services:
- REDIS_HOST=redis
- REDIS_PORT=6379
ports:
- "8000:8000"
- "8888:8000"
volumes:
- ../:/app
redis:
Expand Down
7 changes: 5 additions & 2 deletions frontend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,8 @@ let directTempId = null;

async function loadRenderView() {
try {
const templates = await apiGet("/list");
const templatesResp = await apiGet("/list");
const templates = Array.isArray(templatesResp) ? templatesResp : (templatesResp.templates || []);
const list = document.getElementById("render-template-list");
const published = templates.filter(t => t.status === "published");
if (!published.length) {
Expand All @@ -850,7 +851,9 @@ async function loadRenderView() {
<div class="render-template-name">${esc(t.name)}</div>
</div>`
).join("");
} catch (e) { showToast("Failed to load templates", "error"); }
} catch (e) { showToast("Failed to load templates", "error");
console.error("[loadRenderView] Error loading templates:", e);
}
}

function openRender(tid) { navigateTo("render"); setTimeout(() => selectRenderTemplate(tid), 300); }
Expand Down
Loading