-
-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathrailway.ts
More file actions
235 lines (189 loc) · 6.12 KB
/
railway.ts
File metadata and controls
235 lines (189 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
import process from 'node:process'
import { styleText } from 'node:util'
import { ensureMinimumNodeEngine, logError, logInfo, logSuccess, logWarn } from './utils'
function updatePackageJsonForRailway(cwd: string) {
const packageJsonPath = join(cwd, 'package.json')
if (!existsSync(packageJsonPath)) {
logError('No package.json found. Please run this command from your project root.')
process.exit(1)
}
try {
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
packageJson.scripts = packageJson.scripts || {}
if (packageJson.scripts.start && packageJson.scripts.start !== 'rari start') {
logWarn(`Existing start script found: "${packageJson.scripts.start}"`)
logWarn('Backing up to start:original and replacing with "rari start"')
packageJson.scripts['start:original'] = packageJson.scripts.start
}
packageJson.scripts.start = 'rari start'
packageJson.scripts['start:local'] = 'rari start'
packageJson.scripts['deploy:railway'] = 'echo "Push to GitHub and connect to Railway to deploy"'
ensureMinimumNodeEngine(packageJson)
if (!packageJson.dependencies || !packageJson.dependencies.rari) {
logInfo('Adding rari dependency...')
packageJson.dependencies = packageJson.dependencies || {}
packageJson.dependencies.rari = '^0.1.0'
}
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`)
logSuccess('Updated package.json for Railway deployment')
}
catch (error) {
logError(`Failed to update package.json: ${error instanceof Error ? error.message : 'Unknown error'}`)
process.exit(1)
}
}
export async function createRailwayDeployment() {
const cwd = process.cwd()
logInfo('Creating Railway deployment configuration...')
updatePackageJsonForRailway(cwd)
createRailwayToml(cwd)
updateGitignoreForRailway(cwd)
updateReadmeForRailway(cwd)
printRailwaySuccessMessage()
}
function createRailwayToml(cwd: string) {
const railwayConfig = `[build]
builder = "RAILPACK"
[deploy]
startCommand = "npm start"
healthcheckPath = "/"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 3
`
const railwayTomlPath = join(cwd, 'railway.toml')
if (existsSync(railwayTomlPath)) {
logWarn('railway.toml already exists, backing up to railway.toml.backup')
const existingConfig = readFileSync(railwayTomlPath, 'utf-8')
writeFileSync(join(cwd, 'railway.toml.backup'), existingConfig)
}
writeFileSync(railwayTomlPath, railwayConfig)
logSuccess('Created railway.toml configuration')
}
function updateGitignoreForRailway(cwd: string) {
const gitignorePath = join(cwd, '.gitignore')
const railwayGitignoreEntries = [
'',
'# Railway',
'.railway/',
'',
].join('\n')
if (existsSync(gitignorePath)) {
const gitignoreContent = readFileSync(gitignorePath, 'utf-8')
if (!gitignoreContent.includes('.railway/')) {
writeFileSync(gitignorePath, gitignoreContent + railwayGitignoreEntries)
logSuccess('Updated .gitignore with Railway entries')
}
}
else {
const defaultGitignore = `# Dependencies
node_modules/
.pnpm-store/
# Build outputs
dist/
# Environment variables
.env
.env.local
.env.production
# Railway
.railway/
# Logs
*.log
npm-debug.log*
pnpm-debug.log*
# OS files
.DS_Store
Thumbs.db
# IDE files
.vscode/
.idea/
*.swp
*.swo
*~
# Temporary files
.tmp/
tmp/
`
writeFileSync(gitignorePath, defaultGitignore)
logSuccess('Created .gitignore with Railway entries')
}
}
function updateReadmeForRailway(cwd: string) {
const readmePath = join(cwd, 'README.md')
const railwayReadmeSection = `
## 🚂 Deploy to Railway
This rari application is configured for Railway deployment.
### Quick Deploy
1. **Push to GitHub**:
\`\`\`bash
git add .
git commit -m "Add Railway deployment"
git push origin main
\`\`\`
2. **Deploy to Railway**:
- Go to [railway.app](https://railway.app)
- Create new project → "Deploy from GitHub repo"
- Select your repository
- Click "Deploy Now"
3. **Generate Domain**:
- In Railway dashboard → Settings → Networking
- Click "Generate Domain"
- Your app will be live! 🎉
### Local Development
\`\`\`bash
# Development server
npm run start:local
# Production simulation
npm start
\`\`\`
### Environment Variables
Railway automatically provides:
- \`PORT\` - Server port (Railway assigns this)
- \`NODE_ENV=production\` - Production mode
Optional variables you can set:
- \`RUST_LOG=debug\` - Rust logging level
---
`
if (existsSync(readmePath)) {
const readmeContent = readFileSync(readmePath, 'utf-8')
if (!readmeContent.includes('Deploy to Railway')) {
writeFileSync(readmePath, readmeContent + railwayReadmeSection)
logSuccess('Updated README.md with Railway deployment instructions')
}
}
else {
const defaultReadme = `# My rari App
A high-performance React Server Components application powered by rari.
${railwayReadmeSection}
## Getting Started
\`\`\`bash
npm install
npm start
\`\`\`
Visit [http://localhost:3000](http://localhost:3000) to see your app.
`
writeFileSync(readmePath, defaultReadme)
logSuccess('Created README.md with Railway deployment instructions')
}
}
function printRailwaySuccessMessage() {
console.warn('')
logSuccess('Railway deployment setup complete! 🎉')
console.warn('')
logInfo('Next steps:')
console.warn(` 1. ${styleText('cyan', 'git add .')}`)
console.warn(` 2. ${styleText('cyan', 'git commit -m "Add Railway deployment"')}`)
console.warn(` 3. ${styleText('cyan', 'git push origin main')}`)
console.warn(` 4. Go to ${styleText('cyan', 'https://railway.app')} and deploy from GitHub`)
console.warn('')
logInfo('Your rari app will automatically:')
console.warn(' ✅ Detect Railway environment')
console.warn(' ✅ Bind to 0.0.0.0 (Railway requirement)')
console.warn(' ✅ Use Railway\'s PORT environment variable')
console.warn(' ✅ Run in production mode')
console.warn(' ✅ Download platform-specific rari binary')
console.warn('')
logSuccess('Ready for deployment! 🚀')
}