🚀 Deploy Workflow A-Z

Hướng dẫn từ register → deploy app thật → bind domain → troubleshoot. 5 phút đọc.

Updated 2026-05-08 · Zeni Cloud v121

📌 Đọc trước: Trang này dành cho dev muốn deploy app (web/api/worker) từ source code lên Zeni Cloud. Thay thế Vercel + Supabase + Auth0 + OpenAI API + Zapier — 1 account, 6 lớp hạ tầng.

1.Hiểu workflow trước khi click

Zeni Cloud deploy mỗi project = 1 service Cloud Run độc lập. Để deploy app của bạn, cần 1 image Docker. Có 3 cách lấy image:

📦

① Upload ZIP source

Bạn upload file zip code → Zeni tự build Docker image. Phù hợp Next.js/Vite/FastAPI/Express với Dockerfile chuẩn.

POST /api/v1/upload/source
🏭

② Build Farm (native)

Build Tauri/Rust/Electron/Go/Flutter/.NET trên cloud. Khách KHÔNG cần cài rustc/MSVC/Xcode local.

POST /api/v1/build-farm/jobs
🐳

③ Image có sẵn Docker Hub

Dùng image public hoặc private đã build sẵn, push lên Docker Hub / Artifact Registry.

docker.io/yourname/app:v1

2.5 bước deploy

  1. Đăng ký + Login

    Vào zenicloud.io → click "Đăng ký" → nhập email + password (mạnh ≥8 ký tự). Sau khi register, hệ thống tự tạo personal workspace cho bạn (tên = email slug).

    ⚠️ Token JWT hết hạn sau 1 giờ. Nếu thấy "Phiên đăng nhập hết hạn" → login lại (Zeni tự redirect).
  2. Click "+ Project mới"

    Trên dashboard, button góc trên-phải. Mở wizard 4 bước:

    BướcChọn gì
    1Loại: Web App / API / Worker / AI Agent
    2Tên project (3-48 ký tự, lowercase + dash) + region (mặc định asia-southeast1 Singapore — nhanh nhất cho VN)
    3Runtime + Size: Node 20 / Python 3.12 / Go / Static; Size XS-Large + GPU
    4Confirm — đọc kỹ "💡 Lưu ý quan trọng" về image mặc định
  3. Chọn cách đặt image (CHÍNH YẾU)

    Khi confirm Step 4, image mặc định là us-docker.pkg.dev/cloudrun/container/hello — placeholder Google. Nếu bạn click Tạo & Deploy ngay, project sẽ chạy trang "Hello World" của Google, KHÔNG phải code của bạn.

    ✅ Để deploy CODE THẬT, sau khi project tạo, làm 1 trong 3 cách:
    ① Upload ZIP
    ② Build Farm
    ③ Docker Hub

    Phù hợp: Next.js, React Vite, Vue, FastAPI, Express, Static HTML.

    # Zip thư mục code (loại trừ node_modules, .git, .env)
    zip -r my-app.zip . -x "node_modules/*" ".git/*" ".env*"
    
    # Upload qua API
    curl -X POST 'https://zenicloud.io/api/v1/upload/source?ws=YOUR_WS&framework=auto' \
      -H "Authorization: Bearer $ZENI_TOKEN" \
      -F "file=@my-app.zip" \
      -F "project_name=my-app"
    
    # Zeni tự detect framework + generate Dockerfile + build + deploy
    # Trả về upload_id, poll status:
    curl 'https://zenicloud.io/api/v1/upload/source/{upload_id}?ws=YOUR_WS' \
      -H "Authorization: Bearer $ZENI_TOKEN"

    Hoặc dùng CLI npm install -g @zenicloud/cli rồi zeni deploy.

    Phù hợp: Tauri (.exe / .dmg / .AppImage), Rust binary, Electron app, Go static, Flutter mobile, .NET 8.

    curl -X POST 'https://zenicloud.io/api/v1/build-farm/jobs?ws=YOUR_WS' \
      -H "Authorization: Bearer $ZENI_TOKEN" \
      -d '{
        "toolchain": "tauri-latest",
        "source_type": "github",
        "source_ref": "github://thienmocduc/my-tauri-app@main",
        "target_platforms": ["windows-x64", "linux-x64"]
      }'
    
    # Returns job_id. Poll until status="success":
    curl 'https://zenicloud.io/api/v1/build-farm/jobs/{job_id}?ws=YOUR_WS' \
      -H "Authorization: Bearer $ZENI_TOKEN"
    
    # Artifact URL trả về sau build success — download .exe / .dmg / .AppImage

    Hỗ trợ 6 toolchain: tauri-latest, rust-stable, electron-builder, go-modules, flutter-stable, dotnet-8.

    Phù hợp: Bạn đã có Docker image build sẵn, push lên Docker Hub / Artifact Registry.

    # Build + push lên Docker Hub
    docker build -t yourname/my-app:v1 .
    docker push yourname/my-app:v1
    
    # Update project image qua API
    curl -X PATCH 'https://zenicloud.io/api/v1/projects/{project_id}/image?ws=YOUR_WS' \
      -H "Authorization: Bearer $ZENI_TOKEN" \
      -d '{"image": "docker.io/yourname/my-app:v1"}'
    
    # Hoặc tạo project mới với image này từ đầu (Step 4 wizard có field "Image")
    Tip: Public Docker Hub OK ngay. Private cần wire credentials qua /identity/secrets.
  4. Deploy + Poll status

    Sau khi click "Tạo & Deploy" hoặc gọi API, status chuyển: deployingrunning (~30-60s). Cloud Run service tạo ra với URL dạng https://zeni-{ws}-{project}-xxx.a.run.app.

    curl 'https://zenicloud.io/api/v1/projects/{project_id}?ws=YOUR_WS' \
      -H "Authorization: Bearer $ZENI_TOKEN"
    
    # Response:
    {
      "id": "...",
      "status": "running",
      "domain": "https://zeni-myws-myapp-lijavjpb2a-as.a.run.app",
      "version": "rev-myws-myapp-00001-abc"
    }
  5. Bind custom domain

    Nếu bạn muốn URL riêng (vd: app.example.com):

    curl -X POST 'https://zenicloud.io/api/v1/projects/{project_id}/domain?ws=YOUR_WS' \
      -H "Authorization: Bearer $ZENI_TOKEN" \
      -d '{"domain": "app.example.com"}'
    
    # Response trả CNAME records cần add vào DNS:
    {
      "status": "pending_dns",
      "dns_records": [
        {"type": "CNAME", "name": "app", "value": "ghs.googlehosted.com"}
      ]
    }

    Add CNAME vào Namecheap/Cloudflare DNS → đợi 5-15 phút → SSL auto-issue. Domain LIVE.

3.Troubleshoot lỗi thường gặp

❌ "missing bearer token" (HTTP 401)

Nguyên nhân: Token JWT trong localStorage browser hết hạn (TTL 1h) hoặc bị clear.

Fix: Logout → Login lại. Sau v121, frontend tự redirect login khi detect token expire.

❌ "Image 'X' không tồn tại trong registry" (HTTP 422)

Nguyên nhân: Bạn submit image ref (vd: gcr.io/project/app:v1) nhưng chưa build/push image lên registry.

Fix: Build image trước (1 trong 3 cách trên), HOẶC dùng Docker Hub public (docker.io/library/nginx:alpine).

❌ "Container failed to start on PORT=3000"

Nguyên nhân: App của bạn không listen đúng port. Cloud Run truyền env PORT, app phải listen port đó (default 8080).

Fix: Sửa code app: app.listen(process.env.PORT || 8080). Hoặc khi tạo project, chỉnh field port đúng với app của bạn.

❌ "Workspace access denied" (HTTP 403)

Nguyên nhân: Bạn login OK nhưng không có quyền vào workspace đó.

Fix: Liên hệ Owner workspace để invite bạn qua tab Members. Hoặc tạo workspace riêng.

❌ Build Farm fail "image not found"

Nguyên nhân: Toolchain image gcr.io/zeni-cloud-core/build-farm/tauri:2 chưa build (Phase 2 pending).

Workaround: Tạm dùng GitHub Actions hoặc local build → push image lên Docker Hub → deploy ZeniCloud qua cách ③.

📚 Tiếp theo nên đọc