1. Pengenalan Railway
Railway adalah Platform as a Service (PaaS) modern yang memungkinkan developer meng-deploy aplikasi, databases, dan infrastruktur lengkap dengan cara yang sangat sederhana. Dikenal karena developer experience (DX) yang luar biasa — Railway menghilangkan kompleksitas DevOps dan membiarkan developer fokus pada kode.
Railway mendukung hampir semua bahasa dan framework — Node.js, Python, Go, Rust, Java, Ruby, PHP, Elixir, dan lainnya. Platform ini mendeteksi bahasa secara otomatis dari repository dan melakukan build yang sesuai. Yang membuat Railway berbeda dari PaaS lainnya adalah kemampuannya untuk men-deploy tidak hanya aplikasi tetapi juga databases dan infrastructure services dalam satu project yang terintegrasi.
Mengapa Railway?
| Keunggulan | Penjelasan |
|---|---|
| Zero Config Deploy | Push ke Git, Railway auto-detect bahasa dan build |
| Integrated Databases | PostgreSQL, MySQL, Redis, MongoDB — satu klik untuk deploy |
| Private Networking | Services berkomunikasi via private network tanpa exposed ports |
| Instant Rollback | Rollback ke deployment sebelumnya dalam satu klik |
| Templates | Deploy stack lengkap (app + DB + cache) dari template siap pakai |
| CLI Powerful | Railway CLI untuk deploy, logs, variables, dan manage dari terminal |
| Monorepo Support | Deploy multiple services dari satu monorepo |
| Scaling | Horizontal dan vertical scaling dengan mudah |
| Observability | Logs, metrics, dan monitoring built-in |
┌──────────────────────────────────────────────────────────────┐ │ RAILWAY PROJECT │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Private Network (10.x.x.x) │ │ │ │ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ │ │ App │ │ Worker │ │ Scheduler │ │ │ │ │ │ Service │ │ Service │ │ Service │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Node.js │ │ Python │ │ Cron │ │ │ │ │ │ Express │ │ Celery │ │ Jobs │ │ │ │ │ └─────┬──────┘ └─────┬──────┘ └────────────┘ │ │ │ │ │ │ │ │ │ │ ┌─────┴───────────────┴──────────────────────────┐ │ │ │ │ │ Private Network Communication │ │ │ │ │ └─────┬───────────────┬───────────────┬──────────┘ │ │ │ │ │ │ │ │ │ │ │ ┌─────▼──────┐ ┌─────▼──────┐ ┌─────▼──────┐ │ │ │ │ │ PostgreSQL │ │ Redis │ │ MySQL │ │ │ │ │ │ (Managed) │ │ (Cache) │ │ (Managed) │ │ │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ │ Features: │ │ - Git push → auto deploy │ │ - Automatic SSL/HTTPS │ │ - Custom domains │ │ - Environment variables per service │ │ - Horizontal/vertical scaling │ │ - Build logs & runtime logs │ └──────────────────────────────────────────────────────────────┘
Perbandingan Railway dengan Alternatif
| Fitur | Railway | Render | Fly.io | Heroku |
|---|---|---|---|---|
| Database Managed | ✅ PostgreSQL, MySQL, Redis, MongoDB | ✅ PostgreSQL, Redis | ✅ PostgreSQL | ✅ PostgreSQL, Redis |
| Auto-detect Build | ✅ Ya | ✅ Ya | ❌ Dockerfile | ✅ Ya (buildpacks) |
| Private Networking | ✅ Built-in | ✅ Internal URLs | ✅ WireGuard | ❌ Private Spaces ($$) |
| Pricing Model | Pay per usage | Free tier + paid | Pay per usage | Monthly dyno pricing |
| DX Rating | 🟢 Excellent | 🟢 Good | 🟡 Intermediate | 🟡 Good |
2. Memulai dengan Railway
Install Railway CLI
# Install Railway CLI (macOS/Linux/Windows via npm) npm install -g @railway/cli # Atau gunakan npx npx @railway/cli --version # Install via Homebrew (macOS) brew install railway # Install via script (Linux/macOS) curl -fsSL https://railway.app/install.sh | sh # Login ke Railway railway login # Atau login via token (untuk CI/CD) railway login --token "my-railway-token" # Verifikasi login railway whoami # Inisialisasi project baru railway init # Link ke project yang sudah ada railway link
Buat Project Baru
# Buat project baru dari CLI railway init # Atau buat dari template railway init --template "express-postgres" # Deploy langsung railway up # Cek status railway status # Lihat logs railway logs # Buka di browser railway open
3. Deploy dari Git Repository
Cara Deploy via Git
- Buat repository di GitHub/GitLab/Bitbucket
- Push kode Anda
- Buka Railway Dashboard → New Project → Deploy from GitHub
- Pilih repository
- Railway otomatis detect bahasa, build, dan deploy
- Dapatkan URL publik
Deploy Node.js App
// server.js — Simple Express app
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({
message: 'Hello from Railway!',
env: process.env.NODE_ENV || 'development',
timestamp: new Date().toISOString(),
});
});
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);
});
{
"name": "my-railway-app",
"version": "1.0.0",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"dependencies": {
"express": "^4.18.2",
"pg": "^8.12.0"
},
"engines": {
"node": ">=18.0.0"
}
}
Deploy Python App
# app.py — Flask app
import os
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return jsonify({
'message': 'Hello from Railway!',
'python_version': os.sys.version,
'env': os.environ.get('FLASK_ENV', 'development'),
})
@app.route('/health')
def health():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
# requirements.txt flask==3.0.0 gunicorn==21.2.0 psycopg2-binary==2.9.9 # Procfile (opsional — Railway detect dari start script) # web: gunicorn app:app --bind 0.0.0.0:$PORT
Auto-detect Logic
| Bahasa/Framework | Detect Dari | Build Command | Start Command |
|---|---|---|---|
| Node.js | package.json | npm install | npm start |
| Python | requirements.txt / pyproject.toml | pip install | Procfile atau gunicorn |
| Go | go.mod | go build | ./main |
| Rust | Cargo.toml | cargo build --release | ./target/release/app |
| Java | pom.xml / build.gradle | mvn package | java -jar target/*.jar |
| PHP | composer.json | composer install | php artisan serve |
| Ruby | Gemfile | bundle install | ruby app.rb |
4. Deploy dengan Dockerfile
Untuk kontrol lebih penuh, Anda bisa menggunakan Dockerfile. Railway akan mendeteksi Dockerfile di root project dan menggunakannya untuk build.
# Dockerfile untuk Railway
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist
ENV NODE_ENV=production
EXPOSE ${PORT:-3000}
# Railway akan set PORT secara otomatis
CMD ["node", "dist/server.js"]
Multi-Service Dockerfile
# railway.toml — Konfigurasi Railway (opsional) [build] builder = "DOCKERFILE" dockerfilePath = "Dockerfile" [deploy] startCommand = "node dist/server.js" healthcheckPath = "/health" healthcheckTimeout = 300 restartPolicyType = "ON_FAILURE" restartPolicyMaxRetries = 3
5. Managed Databases
Salah satu fitur terbaik Railway adalah managed databases yang terintegrasi. Anda bisa men-deploy database dalam satu klik dan langsung terkoneksi ke aplikasi via private networking. Railway menangani backup, scaling, dan maintenance.
Database yang Tersedia
| Database | Fitur | Use Case |
|---|---|---|
| PostgreSQL | Relational, ACID, extensions | Aplikasi web umum, data terstruktur |
| MySQL | Relational, wide adoption | Legacy apps, CMS (WordPress, dll) |
| Redis | In-memory, caching, pub/sub | Session, cache, queue, real-time |
| MongoDB | Document store, flexible schema | Content management, IoT, analytics |
Deploy Database
# === DEPLOY DATABASE VIA CLI === # Deploy PostgreSQL railway add --database postgres # Deploy MySQL railway add --database mysql # Deploy Redis railway add --database redis # Deploy MongoDB railway add --database mongodb # Railway akan otomatis: # 1. Provision database # 2. Set environment variables: # - DATABASE_URL (untuk PostgreSQL) # - MYSQL_URL (untuk MySQL) # - REDIS_URL (untuk Redis) # - MONGO_URL (untuk MongoDB) # 3. Buat private networking antara services # Connect ke database via Railway CLI railway connect postgres # Lihat environment variables yang ter-set railway variables
Menggunakan Database di Aplikasi
// Koneksi PostgreSQL di Node.js
const { Pool } = require('pg');
// Railway otomatis set DATABASE_URL
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production'
? { rejectUnauthorized: false }
: false,
});
// Contoh penggunaan
async function getUsers() {
const result = await pool.query('SELECT * FROM users');
return result.rows;
}
async function createUser(name, email) {
const result = await pool.query(
'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
[name, email]
);
return result.rows[0];
}
// Koneksi Redis
const Redis = require('ioredis');
const redis = new Redis(process.env.REDIS_URL);
async function getCachedUser(id) {
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await getUserFromDB(id);
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600);
return user;
}
Railway otomatis meng-inject database connection strings sebagai environment variables. Jangan pernah hardcode credentials — selalu gunakan environment variables. Database di Railway memiliki automatic daily backups (Pro plan) dan bisa di-scale vertikal dari dashboard.
6. Environment Variables
Manage Variables
# === ENVIRONMENT VARIABLES VIA CLI === # Set variabel untuk service saat ini railway variables set NODE_ENV=production railway variables set API_KEY=my-secret-key railway variables set CORS_ORIGIN=https://mydomain.com # Set beberapa sekaligus railway variables set \ NODE_ENV=production \ LOG_LEVEL=info \ SESSION_SECRET=my-session-secret # List semua variabel railway variables # Get nilai variabel spesifik railway variables get NODE_ENV # Delete variabel railway variables delete API_KEY # Set variabel untuk service tertentu (jika multi-service) railway variables set REDIS_URL=redis://... --service my-redis-service # Import dari .env file railway variables set --from-dotenv .env.production # Set variabel sebagai secret (tidak terlihat di dashboard) railway variables set DATABASE_URL="postgres://..."
Variable Scoping
| Scope | Penjelasan |
|---|---|
| Service-level | Variable yang hanya tersedia untuk satu service |
| Project-level | Variable shared ke semua service dalam project |
| Environment-level | Variable untuk environment tertentu (production, staging) |
Private Networking Variables
# Railway otomatis membuat variabel untuk setiap service: # PRIVATE_URL — URL internal (tidak exposed ke internet) # PUBLIC_URL — URL publik (jika service punya public domain) # Contoh environment variables otomatis: # DATABASE_URL=postgres://postgres:password@postgres.railway.internal:5432/railway # REDIS_URL=redis://default:password@redis.railway.internal:6379 # SERVICE_PRIVATE_URL=http://my-app.railway.internal:8080 # Menggunakan private URL di kode: # PostgreSQL → process.env.DATABASE_URL # Redis → process.env.REDIS_URL # Variabel Railway yang tersedia otomatis: # RAILWAY_STATIC_URL — Static URL # RAILWAY_PUBLIC_DOMAIN — Custom domain (jika diset) # RAILWAY_GIT_COMMIT_SHA — Commit hash # RAILWAY_GIT_BRANCH — Branch name # RAILWAY_ENVIRONMENT_NAME — Nama environment # RAILWAY_PROJECT_NAME — Nama project # RAILWAY_SERVICE_NAME — Nama service
7. Railway Templates
Railway Templates adalah konfigurasi siap pakai yang bisa di-deploy dalam satu klik. Template mencakup stack lengkap — aplikasi, databases, dan konfigurasi yang diperlukan.
Template Populer
| Template | Stack | Use Case |
|---|---|---|
| Express + PostgreSQL | Node.js, Express, PostgreSQL | REST API |
| Next.js + PostgreSQL | Next.js, Prisma, PostgreSQL | Full-stack web app |
| Django + PostgreSQL | Python, Django, PostgreSQL | Web application |
| Go + PostgreSQL | Go, PostgreSQL | High-performance API |
| Strapi CMS | Strapi, PostgreSQL, S3 | Headless CMS |
| WordPress | WordPress, MySQL | Blog / CMS |
| Plausible Analytics | Plausible, PostgreSQL, Clickhouse | Web analytics |
| Uptime Kuma | Uptime Kuma | Uptime monitoring |
# Deploy template via CLI railway init --template "express-postgres" # Atau deploy template tertentu railway init --template "strapi" # Di Railway Dashboard: # 1. Klik "New Project" # 2. Pilih "Templates" # 3. Cari template yang diinginkan # 4. Klik "Deploy" # 5. Railway akan deploy semua services
Membuat Template Sendiri
{
"$schema": "https://railway.app/template.schema.json",
"name": "My Full Stack App",
"description": "Full stack app dengan Next.js dan PostgreSQL",
"keywords": ["nextjs", "postgres", "prisma"],
"services": {
"web": {
"source": {
"repo": "github.com/myuser/my-app"
},
"variables": {
"NODE_ENV": "production",
"DATABASE_URL": "${{Postgres.DATABASE_URL}}"
},
"startCommand": "npm start",
"healthcheckPath": "/api/health"
},
"postgres": {
"source": {
"image": "postgres:16"
},
"variables": {
"POSTGRES_PASSWORD": "${{generate(32)}}",
"POSTGRES_DB": "myapp"
}
}
}
}
8. Scaling dan Resource
Vertical Scaling
Anda bisa mengubah resource (CPU dan RAM) untuk setiap service langsung dari dashboard Railway.
| Plan | CPU | RAM | Disk |
|---|---|---|---|
| Hobby | 1 vCPU | 512 MB - 8 GB | 1 GB - 50 GB |
| Pro | 1-8 vCPU | 256 MB - 32 GB | 1 GB - 500 GB |
| Team | Custom | Custom | Custom |
Horizontal Scaling
# Railway mendukung horizontal scaling (replicas) # Di Railway Dashboard: # Service → Settings → Scaling → Replicas # Set replicas via railway.toml [deploy] numReplicas = 3 # Atau di Railway Dashboard: # Service → Settings → Horizontal Scaling → Instances: 3 # Railway akan: # 1. Menjalankan 3 instances dari service Anda # 2. Load balance traffic antar instances # 3. Setiap instance mendapatkan environment variables yang sama
Restart Policy
# railway.toml — Restart Policy [deploy] # Restart jika crash restartPolicyType = "ON_FAILURE" restartPolicyMaxRetries = 5 # Atau selalu restart # restartPolicyType = "ALWAYS" # Jangan restart (manual) # restartPolicyType = "NEVER"
9. Custom Domains
# Tambah custom domain via Railway Dashboard: # Service → Settings → Domains → Custom Domain # Masukkan domain: myapp.example.com # DNS Configuration: # Type | Name | Value # CNAME | myapp | my-service-production.up.railway.app # Atau untuk apex domain (root domain): # Type | Name | Value # A | @ | (IP dari Railway — lihat dashboard) # AAAA | @ | (IPv6 dari Railway) # Atau gunakan railway domain (otomatis) # Format: my-service-production.up.railway.app # Atau generate random domain # Service → Settings → Domains → Generate Domain # HTTPS otomatis dikonfigurasi oleh Railway # Let's Encrypt certificate di-provision otomatis
10. Monorepo & Multi-service
Railway mendukung monorepo — beberapa services dalam satu repository. Setiap service bisa di-build dan deploy secara terpisah dengan konfigurasi yang berbeda.
Struktur Monorepo: ├── apps/ │ ├── web/ ← Frontend (Next.js) │ │ ├── package.json │ │ └── Dockerfile │ ├── api/ ← Backend (Express) │ │ ├── package.json │ │ └── Dockerfile │ └── worker/ ← Background Worker │ ├── package.json │ └── Dockerfile ├── packages/ │ └── shared/ ← Shared library ├── railway.toml └── package.json (root) # Railway Configuration untuk monorepo: # Di Railway Dashboard, set "Root Directory" untuk setiap service: # Service "web" → Root Directory: apps/web # Service "api" → Root Directory: apps/api # Service "worker" → Root Directory: apps/worker
# Deploy monorepo services via CLI # Link ke service tertentu railway link --service web railway up # Switch ke service lain railway link --service api railway up # Atau deploy dari subdirectory cd apps/api && railway up
11. Best Practices
| Best Practice | Detail |
|---|---|
| Gunakan Private Networking | Antar services gunakan PRIVATE_URL, bukan PUBLIC_URL — lebih cepat dan aman |
| Health Checks | Set healthcheckPath agar Railway tahu kapan service sehat |
| Environment Separation | Gunakan Railway Environments (production, staging, preview) untuk isolasi |
| Database Backups | Gunakan Pro plan untuk automatic daily backups. Export manual di Hobby plan |
| Graceful Shutdown | Handle SIGTERM untuk cleanup sebelum container dihentikan |
| Logging | Output logs ke stdout/stderr. Railway mengumpulkan dan menampilkan di dashboard |
| Pinning Versions | Pin database versions (misal PostgreSQL 16) untuk menghindari breaking changes |
| Cost Monitoring | Pantau usage di dashboard. Set billing alerts untuk menghindari tagihan tak terduga |
| Dockerfile Multi-stage | Gunakan multi-stage build untuk image lebih kecil dan deploy lebih cepat |
| Restart Policy | Gunakan ON_FAILURE untuk production, max 3-5 retries |
Railway menyediakan Hobby Plan dengan $5 credit per bulan — cukup untuk project personal kecil. Pro Plan ($20/bln) menambah fitur seperti automatic backups, team collaboration, dan priority support. Selalu pantau usage di dashboard untuk menghindari biaya tak terduga.
12. Quiz Pemahaman
📝 Quiz: Pemahaman Railway
1. Apa yang dilakukan Railway saat Anda push kode ke Git?
2. Bagaimana cara Railway berkomunikasi antar services?
3. Database apa saja yang tersedia di Railway?
4. Apa yang terjadi saat service di Railway crash?
5. Apa keuntungan menggunakan private URL dibanding public URL?