Cách Mình Deploy

Railway deployment, Cloudflare domains, và CI/CD với GitHub Actions

Deployment stack của mình gồm:

Component Mục đích
GitHub Source code và version control
GitHub Actions CI/CD automation (tests, builds, deploy triggers)
Railway Application hosting (PaaS)
Cloudflare Domain management, DNS, CDN
Supabase Database (tách biệt khỏi app hosting)

Nguyên tắc cốt lõi: Deploy sớm, deploy thường xuyên. Thay đổi nhỏ dễ debug hơn big releases.

Railway là gì và tại sao dùng

Railway là PaaS -- push code lên, nó tự detect framework và deploy. Không cần lo server, Docker config, hay infrastructure.

Thuật ngữ cần biết

Thuật ngữ Là gì
Project Tập hợp services cho một ứng dụng
Service Đơn vị deploy đơn lẻ (web app, API, worker)
Environment Instance cách ly (production, staging)
Variables Environment variables cho secrets/config

Ưu và nhược

Ưu: auto-detect framework (NextJS, FastAPI, etc.), auto-deploy khi git push, built-in environment management, scaling đơn giản.

Nhược: ít control hơn raw infrastructure, pricing scales theo usage, vendor lock-in cho Railway-specific features.

Với team nhỏ và product đang giai đoạn đầu thì trade-off này chấp nhận được. Không cần hire DevOps engineer chỉ để deploy một cái Next.js app.

Nguyên tắc deployment

Tự động hóa hết

Deploy thủ công qua SSH hay dashboard clicks thì sớm muộn sẽ quên bước nào đó. Mỗi lần deploy khác nhau một chút. Lỗi không reproduce được.

Mọi deploy trigger bởi git push. Tests chạy tự động. Deploy tự động nếu tests pass. Con người không cần làm gì ngoài push code.

Health check là bắt buộc

Deploy "succeeds" nhưng app crash ngay sau đó -- chuyện này xảy ra hoài nếu không có health check.

Mọi service cần health check endpoint. Railway verify app đang respond trước khi coi deploy thành công. Health check nên kiểm tra:

  • App có respond requests không?
  • Connect được database không?
  • Critical dependencies có available không?

Không có health check thì deploy xong cầu nguyện -- không ổn chút nào.

Environments phải giống nhau

Development, staging, production -- cùng environment variables (khác values), cùng dependencies, cùng runtime.

Cách đạt được:

  • .env.example document tất cả variables
  • Staging environment giống hệt production
  • Test ở staging trước, production sau

"Works on my machine" không phải là QA =))

Secrets không bao giờ trong code

Tất cả secrets đặt trong environment variables. Secrets nằm ở đâu tùy context:

Context Secrets nằm ở
Local .env file (không committed)
Railway Dashboard -> Service -> Variables
CI/CD GitHub Secrets

Rollback phải nhanh

Deploy hỏng mà mất 30 phút mới fix thì user chịu ảnh hưởng 30 phút. Phải rollback về version hoạt động cuối cùng trong dưới 2 phút.

Trong Railway: Deployments -> Tìm bản hoạt động cuối -> Redeploy. Đơn giản vậy thôi.

Kiến trúc Multi-Service

Khi frontend và backend là services riêng biệt:

Service Technology Mục đích
web NextJS Frontend, user-facing
api FastAPI Backend, ML processing
(database) Supabase Data storage (external)

Communication:

  • External calls: Frontend -> Public API URL
  • Internal calls: dùng private networking của Railway khi services cùng project

Environment Variables -- mỗi service có variables riêng:

Service Variables chính
web NEXT_PUBLIC_API_URL, SUPABASE_ANON_KEY
api SUPABASE_SERVICE_KEY, ANTHROPIC_API_KEY

Setup Domain (Cloudflare + Railway)

  1. Thêm domain vào Cloudflare: update nameservers tại registrar
  2. Lấy Railway domain: copy xxx.railway.app từ Railway
  3. Tạo CNAME: trỏ domain tới Railway domain
  4. Configure SSL: dùng mode "Full" trong Cloudflare

SSL Modes

Mode Bảo mật Dùng khi
Flexible Kém Không bao giờ
Full Tốt Lựa chọn mặc định
Full (Strict) Tốt nhất Khi có valid cert

Luôn chọn Full trở lên. Flexible thì bỏ qua luôn -- nó tạo cảm giác an toàn giả.

CI/CD với GitHub Actions

Pipeline chạy gì, chạy khi nào

Trigger Chạy gì
Khi PR Lint, type check, tests
Khi merge vào main Tất cả trên + deploy
Theo lịch Health checks, dependency updates

Thứ tự pipeline

  1. Checkout code
  2. Install dependencies
  3. Lint
  4. Type check
  5. Tests
  6. Build
  7. Deploy (nếu trên main branch)

Secrets cho CI/CD

Lưu trong GitHub -> Settings -> Secrets -> Actions:

  • RAILWAY_TOKEN cho deploys
  • Bất kỳ secrets nào cần cho tests

Monitoring và Logging

Cần monitor gì

Metric Tại sao
Health check status App có đang chạy không?
Response times Có hoạt động tốt không?
Error rates Có gì đang hỏng không?
Resource usage Sắp hết giới hạn chưa?

Log cái gì, không log cái gì

Log: events quan trọng (user actions, processing starts/ends), errors với context (cái gì fail, relevant IDs), performance data (timing, counts).

Không log: sensitive data (passwords, tokens), mọi request (quá nhiễu), debug statements trong production.

External Monitoring

Dùng uptime services (UptimeRobot, Better Uptime) trỏ vào health check endpoint. App down mà mình biết sau user thì muộn rồi.

Những lỗi hay mắc

Quên environment variables -- app crash với "undefined" errors sau deploy. Duy trì .env.example và kiểm tra Railway dashboard trước khi deploy.

Không có staging -- bugs chỉ phát hiện ở production, lúc user đang dùng. Tạo staging environment, deploy và verify ở đó trước.

Build trong production -- deploys chậm, memory cao lúc build, ảnh hưởng app đang chạy. Build trong CI, deploy pre-built artifacts.

Không có health check -- deploys "succeed" nhưng app bị down mà không ai biết. Thêm health check endpoint, configure trong Railway settings.

Manual deploys -- "quên deploy rồi", process mỗi lần mỗi khác. Auto-deploy khi git push, loại bỏ con người khỏi quy trình.

Checklist đánh giá

Đang tốt nếu:

  • Push tới main auto-deploy
  • Deploys hoàn thành trong < 5 phút
  • Health checks pass sau deploy
  • Logs accessible và hữu ích
  • Rollback trong dưới 2 phút
  • Staging mirror production

Cần cải thiện nếu:

  • Cần manual deploys
  • Deploys thường fail
  • Không biết app có healthy không
  • Không có logs hoặc visibility
  • Rollback process không rõ
  • Chỉ phát hiện bugs ở production

Tham khảo nhanh

Deployment Flow

  1. Push tới main branch
  2. GitHub Actions chạy tests
  3. Tests pass -> Railway deploys
  4. Railway chạy health check
  5. Healthy -> deploy hoàn tất
  6. Unhealthy -> rollback về bản trước

Trước khi deploy, verify variables đã set

  • Database connection (Supabase URL, keys)
  • API keys (Anthropic, OpenAI, DataForSEO)
  • Auth secrets (JWT secrets, OAuth credentials)
  • App configuration (URLs, feature flags)

Rollback

  1. Vào Railway dashboard
  2. Navigate tới Service -> Deployments
  3. Tìm deployment hoạt động cuối
  4. Click Redeploy
  5. Verify health check passes

Domain Setup Checklist

  1. Domain đã thêm vào Cloudflare
  2. Nameservers đã update tại registrar
  3. Railway domain đã lấy
  4. CNAME record đã tạo
  5. SSL mode set thành Full
  6. Custom domain đã thêm trong Railway