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.exampledocument 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)
- Thêm domain vào Cloudflare: update nameservers tại registrar
- Lấy Railway domain: copy
xxx.railway.apptừ Railway - Tạo CNAME: trỏ domain tới Railway domain
- 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
- Checkout code
- Install dependencies
- Lint
- Type check
- Tests
- Build
- Deploy (nếu trên main branch)
Secrets cho CI/CD
Lưu trong GitHub -> Settings -> Secrets -> Actions:
RAILWAY_TOKENcho 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
- Push tới main branch
- GitHub Actions chạy tests
- Tests pass -> Railway deploys
- Railway chạy health check
- Healthy -> deploy hoàn tất
- 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
- Vào Railway dashboard
- Navigate tới Service -> Deployments
- Tìm deployment hoạt động cuối
- Click Redeploy
- Verify health check passes
Domain Setup Checklist
- Domain đã thêm vào Cloudflare
- Nameservers đã update tại registrar
- Railway domain đã lấy
- CNAME record đã tạo
- SSL mode set thành Full
- Custom domain đã thêm trong Railway