Cách Mình Deploy

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

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

ComponentMục đích
GitHubSource code và version control
GitHub ActionsCI/CD automation (tests, builds, deploy triggers)
RailwayApplication hosting (PaaS)
CloudflareDomain management, DNS, CDN
SupabaseDatabase (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ì
ProjectTập hợp services cho một ứng dụng
ServiceĐơn vị deploy đơn lẻ (web app, API, worker)
EnvironmentInstance cách ly (production, staging)
VariablesEnvironment 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:

ContextSecrets nằm ở
Local.env file (không committed)
RailwayDashboard -> Service -> Variables
CI/CDGitHub 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:

ServiceTechnologyMục đích
webNextJSFrontend, user-facing
apiFastAPIBackend, ML processing
(database)SupabaseData 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:

ServiceVariables chính
webNEXT_PUBLIC_API_URL, SUPABASE_ANON_KEY
apiSUPABASE_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

ModeBảo mậtDùng khi
FlexibleKémKhông bao giờ
FullTốtLựa chọn mặc định
Full (Strict)Tốt nhấtKhi 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

TriggerChạy gì
Khi PRLint, type check, tests
Khi merge vào mainTất cả trên + deploy
Theo lịchHealth 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ì

MetricTại sao
Health check statusApp có đang chạy không?
Response timesCó hoạt động tốt không?
Error ratesCó gì đang hỏng không?
Resource usageSắ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