Skip to content

Commit 4735e91

Browse files
committed
feat: add Railway deployment support and improvements
- Add Railway configuration and deployment guide - Update entrypoint.sh to support Railway PORT env variable - Add Bun server idle timeout configuration (300s) to prevent premature timeouts - Set X-Initiator to "agent" for claude-sonnet-4.5 model requests - Update .dockerignore to exclude Railway-specific files
1 parent 0ea08fe commit 4735e91

File tree

6 files changed

+70
-3
lines changed

6 files changed

+70
-3
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ tests/
1111
*.md
1212

1313
.eslintcache
14+
15+
# Railway specific
16+
railway.toml
17+
RAILWAY.md

RAILWAY.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Railway Deployment Guide
2+
3+
## Environment Variables
4+
5+
Set these in Railway dashboard under your service settings:
6+
7+
### Required
8+
- `GH_TOKEN` - Your GitHub token (generate using `bun run auth` locally first)
9+
10+
### Optional
11+
- `PORT` - Railway will set this automatically (default: 4141)
12+
- `ACCOUNT_TYPE` - "individual", "business", or "enterprise" (default: individual)
13+
14+
## Deployment Steps
15+
16+
1. **Generate GitHub Token locally** (one-time setup):
17+
```bash
18+
bun run auth
19+
# This will save your token to ~/.local/share/copilot-api/github-token
20+
# Copy the token content for Railway
21+
```
22+
23+
2. **Deploy to Railway**:
24+
- Connect your GitHub repository to Railway
25+
- Railway will automatically detect the Dockerfile
26+
- Set environment variable `GH_TOKEN` in Railway dashboard
27+
28+
3. **Access your deployed API**:
29+
- Railway will provide a public URL like `https://your-app.railway.app`
30+
- Test with: `curl https://your-app.railway.app/v1/models`
31+
32+
## Additional Options
33+
34+
You can pass additional flags via Railway's service settings if needed:
35+
- Set `RAILWAY_RUN_COMMAND` to override the default command
36+
- Example: `bun run dist/main.js start -g $GH_TOKEN -a business`

entrypoint.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
#!/bin/sh
2+
3+
# Use PORT from Railway if available, otherwise default to 4141
4+
PORT="${PORT:-4141}"
5+
26
if [ "$1" = "--auth" ]; then
37
# Run auth command
48
exec bun run dist/main.js auth
59
else
6-
# Default command
7-
exec bun run dist/main.js start -g "$GH_TOKEN" "$@"
10+
# Default command - use GH_TOKEN if provided
11+
if [ -n "$GH_TOKEN" ]; then
12+
exec bun run dist/main.js start -g "$GH_TOKEN" -p "$PORT" "$@"
13+
else
14+
exec bun run dist/main.js start -p "$PORT" "$@"
15+
fi
816
fi
917

railway.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[build]
2+
builder = "dockerfile"
3+
dockerfilePath = "Dockerfile"
4+
5+
[deploy]
6+
numReplicas = 1
7+
restartPolicyType = "on_failure"
8+
restartPolicyMaxRetries = 10
9+
10+
# Railway will automatically expose the PORT that your app listens on

src/services/copilot/create-chat-completions.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ export const createChatCompletions = async (
2222
["assistant", "tool"].includes(msg.role),
2323
)
2424

25+
// Check if model is claude-sonnet-4.5 (should also be treated as agent)
26+
const isClaudeSonnet45 = payload.model === "claude-sonnet-4.5"
27+
2528
// Build headers and add X-Initiator
2629
const headers: Record<string, string> = {
2730
...copilotHeaders(state, enableVision),
28-
"X-Initiator": isAgentCall ? "agent" : "user",
31+
"X-Initiator": isAgentCall || isClaudeSonnet45 ? "agent" : "user",
2932
}
3033

3134
const response = await fetch(`${copilotBaseUrl(state)}/chat/completions`, {

src/start.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ export async function runServer(options: RunServerOptions): Promise<void> {
117117
serve({
118118
fetch: server.fetch as ServerHandler,
119119
port: options.port,
120+
// Bun-specific options for longer timeouts
121+
bun: {
122+
// Disable request timeout (set to 0 or very high value)
123+
// Default is 10 seconds, we set to 5 minutes for long streaming requests
124+
idleTimeout: 300, // 5 minutes in seconds
125+
},
120126
})
121127
}
122128

0 commit comments

Comments
 (0)