From 2187cc4bea1bcda8dc489cd5cb9dab81b29fb2bb Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 21 Jan 2026 19:35:14 +0000 Subject: [PATCH 1/4] Add Railway deployment configuration for direct repository deployment Add comprehensive Railway configuration to enable deployment directly from the repository without using pre-built templates or container images. Changes: - Add railway.toml for each service (agent, UI, desktop) with Docker build configs - Add root railway.json for project-level configuration - Enhance .env.example files with Railway-specific guidance and internal URLs - Update server defaults for production Railway deployment: - UI server: Auto-bind to 0.0.0.0 in production for load balancer compatibility - Desktop: Use PORT environment variable (default 9990) - Add RAILWAY_DEPLOYMENT.md: Comprehensive 200+ line deployment guide covering: - Step-by-step service setup - Environment variable configuration - Railway internal networking (service.railway.internal) - Troubleshooting common issues - Cost optimization and security best practices - Add RAILWAY_QUICKSTART.md: 15-minute quick-start checklist Configuration ensures deterministic builds using: - Existing Dockerfiles with proper build context (packages/) - Service discovery via Railway's internal DNS - Environment variable defaults with Railway reference variables - Proper resource allocation recommendations All changes maintain existing application behavior - only deployment configuration and sensible production defaults added. --- RAILWAY_DEPLOYMENT.md | 302 ++++++++++++++++++++++++++++ RAILWAY_QUICKSTART.md | 149 ++++++++++++++ packages/bytebot-agent/.env.example | 22 ++ packages/bytebot-agent/railway.toml | 38 ++++ packages/bytebot-ui/.env.example | 21 ++ packages/bytebot-ui/railway.toml | 44 ++++ packages/bytebot-ui/server.ts | 3 +- packages/bytebotd/.env.example | 36 ++++ packages/bytebotd/railway.toml | 32 +++ packages/bytebotd/src/main.ts | 2 +- railway.json | 12 ++ 11 files changed, 659 insertions(+), 2 deletions(-) create mode 100644 RAILWAY_DEPLOYMENT.md create mode 100644 RAILWAY_QUICKSTART.md create mode 100644 packages/bytebot-agent/railway.toml create mode 100644 packages/bytebot-ui/railway.toml create mode 100644 packages/bytebotd/.env.example create mode 100644 packages/bytebotd/railway.toml create mode 100644 railway.json diff --git a/RAILWAY_DEPLOYMENT.md b/RAILWAY_DEPLOYMENT.md new file mode 100644 index 000000000..d2592bfe6 --- /dev/null +++ b/RAILWAY_DEPLOYMENT.md @@ -0,0 +1,302 @@ +# Railway Deployment Guide + +This guide shows how to deploy Bytebot on Railway **directly from this repository** without using pre-built templates or container images. + +## Overview + +Bytebot consists of four services that work together: + +1. **PostgreSQL** - Database for tasks, messages, and summaries +2. **bytebot-agent** - NestJS backend for task orchestration and LLM integration +3. **bytebot-ui** - Next.js frontend with Express server for proxying +4. **bytebot-desktop** - Ubuntu desktop environment with XFCE, VNC, and automation tools + +## Prerequisites + +- Railway account ([sign up here](https://railway.app/)) +- At least one AI provider API key: + - [Anthropic Claude](https://console.anthropic.com/) + - [OpenAI](https://platform.openai.com/api-keys) + - [Google Gemini](https://aistudio.google.com/app/apikey) +- Recommended Railway plan: **Pro or higher** (desktop service requires significant resources) + +## Deployment Steps + +### 1. Create a New Railway Project + +1. Go to [railway.app](https://railway.app/) and sign in +2. Click **"New Project"** +3. Select **"Deploy from GitHub repo"** +4. Connect your GitHub account and select this repository +5. Choose the branch you want to deploy (e.g., `main` or `development`) + +### 2. Add PostgreSQL Database + +1. In your Railway project, click **"New"** +2. Select **"Database"** → **"Add PostgreSQL"** +3. Railway will automatically provision a PostgreSQL instance +4. The `DATABASE_URL` environment variable will be available as `${{Postgres.DATABASE_URL}}` + +### 3. Deploy bytebot-agent Service + +1. Click **"New"** → **"GitHub Repo"** (or use existing deployment) +2. Select **"Add Service"** +3. Configure the service: + - **Name:** `bytebot-agent` + - **Root Directory:** `packages/bytebot-agent` + - **Build Method:** Dockerfile + - **Dockerfile Path:** `packages/bytebot-agent/Dockerfile` + +4. Add environment variables: + ``` + DATABASE_URL=${{Postgres.DATABASE_URL}} + BYTEBOT_DESKTOP_BASE_URL=http://bytebot-desktop.railway.internal:9990 + ANTHROPIC_API_KEY=your-anthropic-api-key-here + ``` + + Optional variables: + ``` + OPENAI_API_KEY=your-openai-api-key-here + GEMINI_API_KEY=your-gemini-api-key-here + PORT=9991 + ``` + +5. Click **"Deploy"** + +### 4. Deploy bytebot-desktop Service + +1. Click **"New"** → **"Service"** +2. Configure the service: + - **Name:** `bytebot-desktop` (must match the name used in agent config) + - **Root Directory:** `packages/bytebotd` + - **Build Method:** Dockerfile + - **Dockerfile Path:** `packages/bytebotd/Dockerfile` + +3. Add environment variables: + ``` + DISPLAY=:0 + PORT=9990 + ``` + +4. Configure resources (click on service → Settings → Resources): + - **Memory:** 2GB minimum (4GB recommended) + - **CPU:** 2 vCPU minimum + - **Disk:** 2GB minimum + +5. Click **"Deploy"** + + **Note:** This service takes 5-10 minutes for initial build due to the Ubuntu desktop environment. + +### 5. Deploy bytebot-ui Service + +1. Click **"New"** → **"Service"** +2. Configure the service: + - **Name:** `bytebot-ui` + - **Root Directory:** `packages/bytebot-ui` + - **Build Method:** Dockerfile + - **Dockerfile Path:** `packages/bytebot-ui/Dockerfile` + +3. Add build arguments (Settings → Build): + ``` + BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 + BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify + ``` + +4. Add environment variables: + ``` + BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 + BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify + NEXT_PUBLIC_API_URL=http://bytebot-agent.railway.internal:9991 + NODE_ENV=production + HOSTNAME=0.0.0.0 + PORT=9992 + ``` + +5. Enable public networking (Settings → Networking): + - Toggle **"Public Networking"** ON + - Railway will assign a public URL (e.g., `https://bytebot-ui-production.up.railway.app`) + +6. Click **"Deploy"** + +### 6. Verify Deployment + +1. Wait for all services to show **"Active"** status +2. Click on the **bytebot-ui** service to get the public URL +3. Open the URL in your browser +4. You should see the Bytebot task interface +5. Try creating a task to verify the full stack is working + +## Railway Service Discovery + +Railway provides automatic service discovery via internal DNS: + +- Format: `.railway.internal:` +- Examples: + - `bytebot-agent.railway.internal:9991` + - `bytebot-desktop.railway.internal:9990` + - `postgres.railway.internal:5432` + +Services communicate internally using these URLs, and only the UI is exposed publicly. + +## Configuration Files + +This repository includes Railway-specific configuration: + +- `railway.json` - Root project configuration +- `packages/bytebot-agent/railway.toml` - Agent service configuration +- `packages/bytebot-ui/railway.toml` - UI service configuration +- `packages/bytebotd/railway.toml` - Desktop service configuration +- `.env.example` files in each package directory + +## Troubleshooting + +### Service won't start + +- **Check logs:** Click on the service → "Deployments" → Select latest deployment → "View Logs" +- **Verify environment variables:** Ensure all required variables are set correctly +- **Check service names:** Internal URLs must match the exact service names in Railway + +### Desktop service build timeout + +- The desktop service takes 5-10 minutes to build initially +- If build fails, check the Railway plan limits (free tier may have build time restrictions) +- Upgrade to Pro plan for longer build times and better resources + +### Agent can't connect to desktop + +- Verify `BYTEBOT_DESKTOP_BASE_URL` uses the correct internal URL +- Ensure desktop service is deployed and active before agent starts +- Check that service name matches exactly (case-sensitive) + +### UI shows "connecting..." indefinitely + +- Verify all services are active and healthy +- Check UI environment variables match internal service URLs +- Open browser console (F12) to check for WebSocket connection errors +- Verify desktop service is fully started (check logs for "supervisord started") + +### Database connection errors + +- Ensure PostgreSQL service is active +- Verify `DATABASE_URL` is set correctly in agent service +- Check database service logs for connection issues +- For first deployment, wait for Prisma migrations to complete + +### Out of memory errors + +- Desktop service requires minimum 2GB RAM +- Upgrade Railway plan if on free tier +- Check resource usage in Railway dashboard +- Consider reducing desktop applications if needed + +## Cost Optimization + +Railway charges based on resource usage. To optimize costs: + +1. **Use appropriate plan:** + - Free trial: Limited resources, good for testing + - Pro: $20/month + usage, recommended for production + +2. **Scale resources appropriately:** + - Agent: 512MB RAM, 0.5 vCPU sufficient + - UI: 512MB RAM, 0.5 vCPU sufficient + - Desktop: 2GB RAM, 2 vCPU minimum + - Database: Use default settings + +3. **Monitor usage:** + - Check Railway dashboard regularly + - Set up usage alerts + - Review deployment logs for errors that cause restarts + +## Security Considerations + +1. **Environment Variables:** + - Never commit API keys to version control + - Use Railway's environment variable system + - Rotate API keys regularly + +2. **Network Security:** + - Only UI service should be publicly accessible + - All internal services use private Railway networking + - Add authentication to UI if exposing to internet + +3. **Database Security:** + - Railway PostgreSQL uses encrypted connections by default + - Database is only accessible via private network + - Regular backups are recommended + +## Advanced Configuration + +### Custom Domain + +1. Go to UI service → Settings → Networking +2. Click "Add Custom Domain" +3. Follow Railway's DNS configuration instructions +4. Optional: Enable Cloudflare integration for CDN/WAF + +### Environment-Specific Configuration + +Deploy to different Railway projects for different environments: + +- **Development:** Use `development` branch, lower resources +- **Staging:** Use `staging` branch, production-like resources +- **Production:** Use `main` branch, full resources + +### Adding LLM Proxy (Optional) + +If you want to use the optional LiteLLM proxy: + +1. Click **"New"** → **"Service"** +2. Configure: + - **Name:** `bytebot-llm-proxy` + - **Root Directory:** `packages/bytebot-llm-proxy` + - **Dockerfile Path:** `packages/bytebot-llm-proxy/Dockerfile` +3. Add environment variables (your AI provider keys) +4. Update agent service: + ``` + BYTEBOT_LLM_PROXY_URL=http://bytebot-llm-proxy.railway.internal:4000 + ``` + +## Monitoring and Maintenance + +### View Logs + +- Click on any service → "Deployments" → "View Logs" +- Logs are real-time and searchable +- Use logs to debug issues and monitor performance + +### Restart Service + +- Click on service → Settings → "Restart" +- Or trigger redeploy by pushing to GitHub + +### Database Migrations + +- Prisma migrations run automatically on agent startup +- Check agent logs for migration status +- For manual migrations, use Railway CLI or database GUI + +### Scaling + +Railway auto-scales within configured resource limits. To adjust: + +1. Click service → Settings → Resources +2. Adjust Memory, CPU, and Replicas +3. Click "Save" +4. Service will restart with new resources + +## Support + +- **Railway Documentation:** https://docs.railway.app/ +- **Bytebot Issues:** https://github.com/bytebot-ai/bytebot/issues +- **Railway Community:** https://discord.gg/railway +- **Bytebot Discord:** https://discord.com/invite/d9ewZkWPTP + +## Next Steps + +After deployment: + +1. Explore the REST APIs at `/api/tasks`, `/api/messages`, etc. +2. Review the [API documentation](/docs/api-reference/introduction) +3. Join the Bytebot community on Discord +4. Share your automation workflows! diff --git a/RAILWAY_QUICKSTART.md b/RAILWAY_QUICKSTART.md new file mode 100644 index 000000000..00dcbc272 --- /dev/null +++ b/RAILWAY_QUICKSTART.md @@ -0,0 +1,149 @@ +# Railway Quick Start Guide + +Deploy Bytebot to Railway from this repository in under 15 minutes. + +## Prerequisites + +- Railway account with credit card (Pro plan recommended for desktop service) +- One AI API key: [Anthropic](https://console.anthropic.com/) | [OpenAI](https://platform.openai.com/api-keys) | [Gemini](https://aistudio.google.com/app/apikey) + +## Quick Deploy Checklist + +### 1. Create Railway Project (2 min) + +- [ ] Go to [railway.app](https://railway.app/) → New Project +- [ ] Deploy from GitHub repo → Select this repository +- [ ] Choose branch (e.g., `main`) + +### 2. Add PostgreSQL (1 min) + +- [ ] Click **New** → **Database** → **PostgreSQL** +- [ ] Wait for provisioning (auto-completes in ~30 seconds) + +### 3. Deploy bytebot-desktop (10 min) + +**Name:** `bytebot-desktop` (exact name matters!) + +**Settings:** +- Root Directory: `packages/bytebotd` +- Dockerfile Path: `packages/bytebotd/Dockerfile` + +**Environment Variables:** +```bash +DISPLAY=:0 +``` + +**Resources** (Settings → Resources): +- Memory: 2048 MB (minimum) +- CPU: 2 vCPU (minimum) + +**Deploy** → Wait 5-10 minutes for Ubuntu desktop build + +### 4. Deploy bytebot-agent (3 min) + +**Name:** `bytebot-agent` + +**Settings:** +- Root Directory: `packages/bytebot-agent` +- Dockerfile Path: `packages/bytebot-agent/Dockerfile` + +**Environment Variables** (Required): +```bash +DATABASE_URL=${{Postgres.DATABASE_URL}} +BYTEBOT_DESKTOP_BASE_URL=http://bytebot-desktop.railway.internal:9990 +ANTHROPIC_API_KEY=sk-ant-xxxxx +``` + +Optional (add more AI providers): +```bash +OPENAI_API_KEY=sk-xxxxx +GEMINI_API_KEY=xxxxx +``` + +**Deploy** + +### 5. Deploy bytebot-ui (3 min) + +**Name:** `bytebot-ui` + +**Settings:** +- Root Directory: `packages/bytebot-ui` +- Dockerfile Path: `packages/bytebot-ui/Dockerfile` + +**Build Args** (Settings → Variables → Build): +```bash +BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 +BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify +``` + +**Environment Variables:** +```bash +BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 +BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify +NEXT_PUBLIC_API_URL=http://bytebot-agent.railway.internal:9991 +NODE_ENV=production +HOSTNAME=0.0.0.0 +``` + +**Networking:** +- Enable **Public Networking** (Settings → Networking) +- Copy the generated public URL + +**Deploy** + +### 6. Test (1 min) + +- [ ] Wait for all services to show **Active** status +- [ ] Open the bytebot-ui public URL +- [ ] Create a test task (e.g., "Open Firefox and search for Railway") +- [ ] Watch the desktop stream execute the task + +## Service Names Matter! + +Railway's internal DNS uses exact service names. If you used different names, update these environment variables: + +```bash +# In bytebot-agent: +BYTEBOT_DESKTOP_BASE_URL=http://YOUR-DESKTOP-SERVICE-NAME.railway.internal:9990 + +# In bytebot-ui: +BYTEBOT_AGENT_BASE_URL=http://YOUR-AGENT-SERVICE-NAME.railway.internal:9991 +BYTEBOT_DESKTOP_VNC_URL=ws://YOUR-DESKTOP-SERVICE-NAME.railway.internal:9990/websockify +``` + +## Troubleshooting + +| Problem | Solution | +|---------|----------| +| Desktop build timeout | Use Pro plan (free tier has build time limits) | +| Agent can't connect | Check service names match exactly | +| UI shows "connecting..." | Wait for desktop to fully start (check logs) | +| Out of memory | Increase desktop RAM to 4GB | + +## Cost Estimate (Pro Plan) + +- **Plan:** $20/month +- **Usage:** ~$30-60/month for moderate use + - Desktop: ~$20-40/month (2GB RAM, always-on) + - Agent + UI: ~$5-10/month + - Database: ~$5-10/month +- **Total:** ~$50-80/month + +Optimize costs by: +- Stopping desktop service when not in use +- Using Hobby plan for testing ($5/month) +- Monitoring usage in Railway dashboard + +## Next Steps + +- [ ] Add custom domain (Settings → Networking → Custom Domain) +- [ ] Set up environment-specific deployments (dev/staging/prod) +- [ ] Configure monitoring and alerts +- [ ] Review [full deployment guide](RAILWAY_DEPLOYMENT.md) + +## Support + +- 📚 [Full Guide](RAILWAY_DEPLOYMENT.md) +- 🚂 [Railway Docs](https://docs.railway.app/) +- 💬 [Railway Discord](https://discord.gg/railway) +- 🤖 [Bytebot Discord](https://discord.com/invite/d9ewZkWPTP) diff --git a/packages/bytebot-agent/.env.example b/packages/bytebot-agent/.env.example index 713c70043..5a116cb50 100644 --- a/packages/bytebot-agent/.env.example +++ b/packages/bytebot-agent/.env.example @@ -1,4 +1,26 @@ +# Database connection string (Required) +# Local: postgresql://postgres:postgres@postgres:5432/bytebotdb +# Railway: Automatically set via ${{Postgres.DATABASE_URL}} reference variable DATABASE_URL=postgresql://postgres:postgres@postgres:5432/bytebotdb + +# AI Provider API Keys (At least one required) +# Get Anthropic key at: https://console.anthropic.com/ ANTHROPIC_API_KEY= +# Get OpenAI key at: https://platform.openai.com/api-keys +OPENAI_API_KEY= +# Get Gemini key at: https://aistudio.google.com/app/apikey +GEMINI_API_KEY= + +# Desktop service URL (Required) +# Local: http://localhost:9990 +# Railway: http://bytebot-desktop.railway.internal:9990 BYTEBOT_DESKTOP_BASE_URL=http://localhost:9990 + +# Optional: LLM Proxy URL (if using bytebot-llm-proxy service) +# BYTEBOT_LLM_PROXY_URL=http://localhost:4000 + +# Optional: Analytics endpoint BYTEBOT_ANALYTICS_ENDPOINT= + +# Optional: Port override (default: 9991) +# PORT=9991 diff --git a/packages/bytebot-agent/railway.toml b/packages/bytebot-agent/railway.toml new file mode 100644 index 000000000..e12b35898 --- /dev/null +++ b/packages/bytebot-agent/railway.toml @@ -0,0 +1,38 @@ +[build] +builder = "DOCKERFILE" +dockerfilePath = "packages/bytebot-agent/Dockerfile" +dockerContext = "packages" + +[deploy] +startCommand = "npm run start:prod" +restartPolicyType = "ON_FAILURE" +restartPolicyMaxRetries = 10 + +# Service runs on internal port 9991 +[deploy.healthcheck] +path = "/" +timeout = 300 +interval = 60 + +[deploy.environmentVariables] +# Database connection string - automatically set by Railway when PostgreSQL is added +# Format: postgresql://user:password@host:port/database +# DATABASE_URL = "${POSTGRESQL_URL}" + +# Desktop service URL - set to Railway's internal networking URL +# Default assumes service is named "bytebot-desktop" in Railway +# BYTEBOT_DESKTOP_BASE_URL = "http://bytebot-desktop.railway.internal:9990" + +# AI Provider API Keys - at least one required +# ANTHROPIC_API_KEY = "" +# OPENAI_API_KEY = "" +# GEMINI_API_KEY = "" + +# Optional: LLM Proxy URL if using bytebot-llm-proxy service +# BYTEBOT_LLM_PROXY_URL = "http://bytebot-llm-proxy.railway.internal:4000" + +# Optional: Analytics endpoint +# BYTEBOT_ANALYTICS_ENDPOINT = "" + +# Port configuration (defaults to 9991 if not set) +# PORT = "9991" diff --git a/packages/bytebot-ui/.env.example b/packages/bytebot-ui/.env.example index a458a6bec..51ee82591 100644 --- a/packages/bytebot-ui/.env.example +++ b/packages/bytebot-ui/.env.example @@ -1,3 +1,24 @@ +# Agent service URL (Required) +# Local: http://localhost:9991 +# Railway: http://bytebot-agent.railway.internal:9991 BYTEBOT_AGENT_BASE_URL=http://localhost:9991 + +# Desktop VNC WebSocket URL (Required) +# Local: ws://localhost:9990/websockify +# Railway: ws://bytebot-desktop.railway.internal:9990/websockify BYTEBOT_DESKTOP_VNC_URL=ws://localhost:9990/websockify + +# Public API URL for browser (Required) +# Local: http://localhost:9991 +# Railway: Use internal URL, Express server proxies requests NEXT_PUBLIC_API_URL=http://localhost:9991 + +# Node environment (development | production) +# Railway: Set to production automatically +NODE_ENV=development + +# Optional: Port override (default: 9992) +# PORT=9992 + +# Optional: Hostname (default: localhost, Railway: 0.0.0.0) +# HOSTNAME=0.0.0.0 diff --git a/packages/bytebot-ui/railway.toml b/packages/bytebot-ui/railway.toml new file mode 100644 index 000000000..0a942d04f --- /dev/null +++ b/packages/bytebot-ui/railway.toml @@ -0,0 +1,44 @@ +[build] +builder = "DOCKERFILE" +dockerfilePath = "packages/bytebot-ui/Dockerfile" +dockerContext = "packages" + +# Pass build args for internal service URLs +[build.buildArgs] +# These are used during the Next.js build process +# Railway's internal networking format: .railway.internal: +BYTEBOT_AGENT_BASE_URL = "http://bytebot-agent.railway.internal:9991" +BYTEBOT_DESKTOP_VNC_URL = "ws://bytebot-desktop.railway.internal:9990/websockify" + +[deploy] +startCommand = "npm run start" +restartPolicyType = "ON_FAILURE" +restartPolicyMaxRetries = 10 + +# This service should be publicly accessible +[deploy.healthcheck] +path = "/" +timeout = 300 +interval = 60 + +[deploy.environmentVariables] +# Runtime environment variables for the Express server and Next.js app +# These should match the build args above for consistency + +# Backend service URLs - Railway internal networking +# BYTEBOT_AGENT_BASE_URL = "http://bytebot-agent.railway.internal:9991" +# BYTEBOT_DESKTOP_VNC_URL = "ws://bytebot-desktop.railway.internal:9990/websockify" + +# Next.js public environment variable (exposed to browser) +# This should point to the agent service via internal networking +# The UI will proxy requests from the browser through its Express server +# NEXT_PUBLIC_API_URL = "http://bytebot-agent.railway.internal:9991" + +# Node environment +NODE_ENV = "production" + +# Port configuration (defaults to 9992 if not set) +# PORT = "9992" + +# Hostname +# HOSTNAME = "0.0.0.0" diff --git a/packages/bytebot-ui/server.ts b/packages/bytebot-ui/server.ts index c942f7799..b7c1be4b8 100644 --- a/packages/bytebot-ui/server.ts +++ b/packages/bytebot-ui/server.ts @@ -9,7 +9,8 @@ import dotenv from "dotenv"; dotenv.config(); const dev = process.env.NODE_ENV !== "production"; -const hostname = process.env.HOSTNAME || "localhost"; +// In production, bind to 0.0.0.0 to accept connections from load balancers (Railway, etc.) +const hostname = process.env.HOSTNAME || (dev ? "localhost" : "0.0.0.0"); const port = parseInt(process.env.PORT || "9992", 10); // Backend URLs diff --git a/packages/bytebotd/.env.example b/packages/bytebotd/.env.example new file mode 100644 index 000000000..7602f88a2 --- /dev/null +++ b/packages/bytebotd/.env.example @@ -0,0 +1,36 @@ +# Bytebot Desktop (bytebotd) Environment Variables +# Copy this file to .env and fill in the values + +# ============================================================================ +# X11 DISPLAY (Required for Desktop Environment) +# ============================================================================ +# X11 display number for the virtual desktop +# Default: :0 (first display) +DISPLAY=:0 + +# ============================================================================ +# SERVER CONFIGURATION +# ============================================================================ +# Server port (default: 9990) +# Serves both bytebotd API and noVNC websocket endpoint +# PORT=9990 + +# ============================================================================ +# RESOURCE NOTES +# ============================================================================ +# This service runs a full Ubuntu desktop environment including: +# - XFCE desktop +# - X11 server (Xvfb) +# - VNC server (x11vnc) +# - noVNC web client +# - Firefox ESR +# - VS Code +# - 1Password +# - Node.js 20 +# +# Recommended resources: +# - Memory: 2GB minimum, 4GB recommended +# - CPU: 2 vCPU minimum +# - Disk: 2GB minimum +# +# Railway Plan Recommendation: Pro or higher for optimal performance diff --git a/packages/bytebotd/railway.toml b/packages/bytebotd/railway.toml new file mode 100644 index 000000000..8262e1a61 --- /dev/null +++ b/packages/bytebotd/railway.toml @@ -0,0 +1,32 @@ +[build] +builder = "DOCKERFILE" +dockerfilePath = "packages/bytebotd/Dockerfile" +dockerContext = "packages" + +[deploy] +# Bytebotd uses supervisord to manage multiple processes (X11, VNC, noVNC, desktop) +# The CMD in the Dockerfile starts supervisord +restartPolicyType = "ON_FAILURE" +restartPolicyMaxRetries = 10 + +# Desktop environment requires more resources +# Recommended: 2GB RAM, 2 vCPU +# Railway will use defaults if not specified in the UI + +# Health check on the bytebotd HTTP endpoint +[deploy.healthcheck] +path = "/" +timeout = 300 +interval = 60 + +[deploy.environmentVariables] +# X11 Display configuration (required for desktop environment) +DISPLAY = ":0" + +# Port configuration (defaults to 9990 if not set) +# This port serves both the bytebotd API and noVNC websocket endpoint +# PORT = "9990" + +# Note: This service requires significant resources due to the full desktop environment +# including XFCE, Firefox, VS Code, and VNC server +# Recommended Railway plan: Pro or higher for optimal performance diff --git a/packages/bytebotd/src/main.ts b/packages/bytebotd/src/main.ts index 3999c8eb4..5dcf93706 100644 --- a/packages/bytebotd/src/main.ts +++ b/packages/bytebotd/src/main.ts @@ -25,7 +25,7 @@ async function bootstrap() { pathRewrite: { '^/websockify': '/' }, }); app.use('/websockify', express.raw({ type: '*/*' }), wsProxy); - const server = await app.listen(9990); + const server = await app.listen(process.env.PORT ?? 9990); // Selective upgrade routing server.on('upgrade', (req, socket, head) => { diff --git a/railway.json b/railway.json new file mode 100644 index 000000000..aa8114ce4 --- /dev/null +++ b/railway.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://railway.app/railway.schema.json", + "build": { + "builder": "DOCKERFILE", + "dockerContext": "packages" + }, + "deploy": { + "numReplicas": 1, + "restartPolicyType": "ON_FAILURE", + "restartPolicyMaxRetries": 10 + } +} From abe4c9522da24661e017a6c9a636910b7aae0d9f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 21 Jan 2026 19:41:45 +0000 Subject: [PATCH 2/4] Fix Railway build configuration - use repository root as build context Railway doesn't support custom dockerContext in railway.toml. The build context is automatically set based on the Dockerfile location. For monorepo support, the cleanest approach is to use the repository root as the build context for all services. Changes: - Remove invalid 'dockerContext' field from railway.toml files - Remove conflicting railway.json at repository root - Update all Dockerfiles to copy from 'packages/' paths (repo root context) - Update docker-compose files to use repo root context for consistency - Update documentation to clarify Railway auto-detects from railway.toml - Remove manual Root Directory configuration from deployment guides Docker build context changed from: Old: context = packages/, COPY ./shared, COPY ./SERVICE New: context = repo root, COPY packages/shared, COPY packages/SERVICE This ensures consistent behavior across: - Railway deployments (uses railway.toml) - Docker Compose deployments (uses docker-compose.yml) - GitHub Actions CI/CD (builds from repo root) All builds now use repository root as the Docker build context. --- RAILWAY_DEPLOYMENT.md | 15 ++++++--------- RAILWAY_QUICKSTART.md | 12 ++++++------ docker/docker-compose-claude-code.yml | 12 ++++++------ docker/docker-compose.core.yml | 4 ++-- docker/docker-compose.development.yml | 4 ++-- docker/docker-compose.proxy.yml | 16 ++++++++-------- docker/docker-compose.yml | 12 ++++++------ packages/bytebot-agent/Dockerfile | 8 ++++---- packages/bytebot-agent/railway.toml | 1 - packages/bytebot-ui/Dockerfile | 7 ++++--- packages/bytebot-ui/railway.toml | 1 - packages/bytebotd/Dockerfile | 6 ++++-- packages/bytebotd/railway.toml | 1 - railway.json | 12 ------------ 14 files changed, 48 insertions(+), 63 deletions(-) delete mode 100644 railway.json diff --git a/RAILWAY_DEPLOYMENT.md b/RAILWAY_DEPLOYMENT.md index d2592bfe6..281680915 100644 --- a/RAILWAY_DEPLOYMENT.md +++ b/RAILWAY_DEPLOYMENT.md @@ -43,9 +43,8 @@ Bytebot consists of four services that work together: 2. Select **"Add Service"** 3. Configure the service: - **Name:** `bytebot-agent` - - **Root Directory:** `packages/bytebot-agent` - - **Build Method:** Dockerfile - - **Dockerfile Path:** `packages/bytebot-agent/Dockerfile` + - **Root Directory:** (leave empty - Railway will use repository root) + - Railway will auto-detect build configuration from `packages/bytebot-agent/railway.toml` 4. Add environment variables: ``` @@ -68,9 +67,8 @@ Bytebot consists of four services that work together: 1. Click **"New"** → **"Service"** 2. Configure the service: - **Name:** `bytebot-desktop` (must match the name used in agent config) - - **Root Directory:** `packages/bytebotd` - - **Build Method:** Dockerfile - - **Dockerfile Path:** `packages/bytebotd/Dockerfile` + - **Root Directory:** (leave empty - Railway will use repository root) + - Railway will auto-detect build configuration from `packages/bytebotd/railway.toml` 3. Add environment variables: ``` @@ -92,9 +90,8 @@ Bytebot consists of four services that work together: 1. Click **"New"** → **"Service"** 2. Configure the service: - **Name:** `bytebot-ui` - - **Root Directory:** `packages/bytebot-ui` - - **Build Method:** Dockerfile - - **Dockerfile Path:** `packages/bytebot-ui/Dockerfile` + - **Root Directory:** (leave empty - Railway will use repository root) + - Railway will auto-detect build configuration from `packages/bytebot-ui/railway.toml` 3. Add build arguments (Settings → Build): ``` diff --git a/RAILWAY_QUICKSTART.md b/RAILWAY_QUICKSTART.md index 00dcbc272..dbddbf074 100644 --- a/RAILWAY_QUICKSTART.md +++ b/RAILWAY_QUICKSTART.md @@ -25,8 +25,8 @@ Deploy Bytebot to Railway from this repository in under 15 minutes. **Name:** `bytebot-desktop` (exact name matters!) **Settings:** -- Root Directory: `packages/bytebotd` -- Dockerfile Path: `packages/bytebotd/Dockerfile` +- Root Directory: (leave empty - use repository root) +- Railway will auto-detect configuration from `packages/bytebotd/railway.toml` **Environment Variables:** ```bash @@ -44,8 +44,8 @@ DISPLAY=:0 **Name:** `bytebot-agent` **Settings:** -- Root Directory: `packages/bytebot-agent` -- Dockerfile Path: `packages/bytebot-agent/Dockerfile` +- Root Directory: (leave empty - use repository root) +- Railway will auto-detect configuration from `packages/bytebot-agent/railway.toml` **Environment Variables** (Required): ```bash @@ -67,8 +67,8 @@ GEMINI_API_KEY=xxxxx **Name:** `bytebot-ui` **Settings:** -- Root Directory: `packages/bytebot-ui` -- Dockerfile Path: `packages/bytebot-ui/Dockerfile` +- Root Directory: (leave empty - use repository root) +- Railway will auto-detect configuration from `packages/bytebot-ui/railway.toml` **Build Args** (Settings → Variables → Build): ```bash diff --git a/docker/docker-compose-claude-code.yml b/docker/docker-compose-claude-code.yml index 3b714c5ab..cb329df39 100644 --- a/docker/docker-compose-claude-code.yml +++ b/docker/docker-compose-claude-code.yml @@ -4,8 +4,8 @@ services: bytebot-desktop: # Build from source build: - context: ../packages/ - dockerfile: bytebotd/Dockerfile + context: ../ + dockerfile: packages/bytebotd/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-desktop:edge shm_size: "2g" @@ -37,8 +37,8 @@ services: bytebot-agent-cc: build: - context: ../packages/ - dockerfile: bytebot-agent-cc/Dockerfile + context: ../ + dockerfile: packages/bytebot-agent-cc/Dockerfile container_name: bytebot-agent-cc restart: unless-stopped ports: @@ -54,8 +54,8 @@ services: bytebot-ui: build: - context: ../packages/ - dockerfile: bytebot-ui/Dockerfile + context: ../ + dockerfile: packages/bytebot-ui/Dockerfile args: - BYTEBOT_AGENT_BASE_URL=${BYTEBOT_AGENT_BASE_URL:-http://bytebot-agent-cc:9991} - BYTEBOT_DESKTOP_VNC_URL=${BYTEBOT_DESKTOP_VNC_URL:-http://bytebot-desktop:9990/websockify} diff --git a/docker/docker-compose.core.yml b/docker/docker-compose.core.yml index dee5e736c..6048d30b9 100644 --- a/docker/docker-compose.core.yml +++ b/docker/docker-compose.core.yml @@ -4,8 +4,8 @@ services: bytebot-desktop: # Build from source build: - context: ../packages/ - dockerfile: bytebotd/Dockerfile + context: ../ + dockerfile: packages/bytebotd/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-desktop:edge shm_size: "2g" diff --git a/docker/docker-compose.development.yml b/docker/docker-compose.development.yml index 4d7bc5ef9..2a2269ac3 100644 --- a/docker/docker-compose.development.yml +++ b/docker/docker-compose.development.yml @@ -9,8 +9,8 @@ services: bytebot-desktop: # Build from source build: - context: ../packages/ - dockerfile: bytebotd/Dockerfile + context: ../ + dockerfile: packages/bytebotd/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-desktop:edge shm_size: "2g" diff --git a/docker/docker-compose.proxy.yml b/docker/docker-compose.proxy.yml index 2a68a6303..b39d940b3 100644 --- a/docker/docker-compose.proxy.yml +++ b/docker/docker-compose.proxy.yml @@ -4,8 +4,8 @@ services: bytebot-desktop: # Build from source build: - context: ../packages/ - dockerfile: bytebotd/Dockerfile + context: ../ + dockerfile: packages/bytebotd/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-desktop:edge shm_size: "2g" @@ -37,8 +37,8 @@ services: bytebot-agent: build: - context: ../packages/ - dockerfile: bytebot-agent/Dockerfile + context: ../ + dockerfile: packages/bytebot-agent/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-agent:edge container_name: bytebot-agent @@ -56,8 +56,8 @@ services: bytebot-llm-proxy: build: - context: ../packages/ - dockerfile: bytebot-llm-proxy/Dockerfile + context: ../ + dockerfile: packages/bytebot-llm-proxy/Dockerfile ports: - "4000:4000" environment: @@ -69,8 +69,8 @@ services: bytebot-ui: build: - context: ../packages/ - dockerfile: bytebot-ui/Dockerfile + context: ../ + dockerfile: packages/bytebot-ui/Dockerfile args: - BYTEBOT_AGENT_BASE_URL=${BYTEBOT_AGENT_BASE_URL:-http://bytebot-agent:9991} - BYTEBOT_DESKTOP_VNC_URL=${BYTEBOT_DESKTOP_VNC_URL:-http://bytebot-desktop:9990/websockify} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 7d4c1e1dc..f62b1f418 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -4,8 +4,8 @@ services: bytebot-desktop: # Build from source build: - context: ../packages/ - dockerfile: bytebotd/Dockerfile + context: ../ + dockerfile: packages/bytebotd/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-desktop:edge shm_size: "2g" @@ -37,8 +37,8 @@ services: bytebot-agent: build: - context: ../packages/ - dockerfile: bytebot-agent/Dockerfile + context: ../ + dockerfile: packages/bytebot-agent/Dockerfile # Use pre-built image image: ghcr.io/bytebot-ai/bytebot-agent:edge container_name: bytebot-agent @@ -58,8 +58,8 @@ services: bytebot-ui: build: - context: ../packages/ - dockerfile: bytebot-ui/Dockerfile + context: ../ + dockerfile: packages/bytebot-ui/Dockerfile args: - BYTEBOT_AGENT_BASE_URL=${BYTEBOT_AGENT_BASE_URL:-http://bytebot-agent:9991} - BYTEBOT_DESKTOP_VNC_URL=${BYTEBOT_DESKTOP_VNC_URL:-http://bytebot-desktop:9990/websockify} diff --git a/packages/bytebot-agent/Dockerfile b/packages/bytebot-agent/Dockerfile index 1192007c9..025fd31f8 100644 --- a/packages/bytebot-agent/Dockerfile +++ b/packages/bytebot-agent/Dockerfile @@ -4,16 +4,16 @@ FROM node:20-alpine # Create app directory WORKDIR /app -# Copy app source -COPY ./shared ./shared -COPY ./bytebot-agent/ ./bytebot-agent/ +# Copy app source from repository root +# Note: Build context is the repository root for Railway +COPY packages/shared ./shared +COPY packages/bytebot-agent ./bytebot-agent WORKDIR /app/bytebot-agent # Install dependencies RUN npm install - RUN npm run build # Run the application diff --git a/packages/bytebot-agent/railway.toml b/packages/bytebot-agent/railway.toml index e12b35898..bcbe733f9 100644 --- a/packages/bytebot-agent/railway.toml +++ b/packages/bytebot-agent/railway.toml @@ -1,7 +1,6 @@ [build] builder = "DOCKERFILE" dockerfilePath = "packages/bytebot-agent/Dockerfile" -dockerContext = "packages" [deploy] startCommand = "npm run start:prod" diff --git a/packages/bytebot-ui/Dockerfile b/packages/bytebot-ui/Dockerfile index c2a71e8d7..d3cb0a739 100644 --- a/packages/bytebot-ui/Dockerfile +++ b/packages/bytebot-ui/Dockerfile @@ -12,9 +12,10 @@ ENV BYTEBOT_DESKTOP_VNC_URL=${BYTEBOT_DESKTOP_VNC_URL} # Create app directory WORKDIR /app -# Copy app source -COPY ./shared ./shared -COPY ./bytebot-ui/ ./bytebot-ui +# Copy app source from repository root +# Note: Build context is the repository root for Railway +COPY packages/shared ./shared +COPY packages/bytebot-ui ./bytebot-ui WORKDIR /app/bytebot-ui diff --git a/packages/bytebot-ui/railway.toml b/packages/bytebot-ui/railway.toml index 0a942d04f..75db3e078 100644 --- a/packages/bytebot-ui/railway.toml +++ b/packages/bytebot-ui/railway.toml @@ -1,7 +1,6 @@ [build] builder = "DOCKERFILE" dockerfilePath = "packages/bytebot-ui/Dockerfile" -dockerContext = "packages" # Pass build args for internal service URLs [build.buildArgs] diff --git a/packages/bytebotd/Dockerfile b/packages/bytebotd/Dockerfile index f8a893bc8..3b450f752 100644 --- a/packages/bytebotd/Dockerfile +++ b/packages/bytebotd/Dockerfile @@ -174,8 +174,10 @@ RUN apt-get update && \ git build-essential && \ rm -rf /var/lib/apt/lists/* -COPY ./shared/ /bytebot/shared/ -COPY ./bytebotd/ /bytebot/bytebotd/ +# Copy app source from repository root +# Note: Build context is the repository root for Railway +COPY packages/shared /bytebot/shared/ +COPY packages/bytebotd /bytebot/bytebotd/ WORKDIR /bytebot/bytebotd RUN npm install --build-from-source RUN npm rebuild uiohook-napi --build-from-source diff --git a/packages/bytebotd/railway.toml b/packages/bytebotd/railway.toml index 8262e1a61..44a685142 100644 --- a/packages/bytebotd/railway.toml +++ b/packages/bytebotd/railway.toml @@ -1,7 +1,6 @@ [build] builder = "DOCKERFILE" dockerfilePath = "packages/bytebotd/Dockerfile" -dockerContext = "packages" [deploy] # Bytebotd uses supervisord to manage multiple processes (X11, VNC, noVNC, desktop) diff --git a/railway.json b/railway.json deleted file mode 100644 index aa8114ce4..000000000 --- a/railway.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://railway.app/railway.schema.json", - "build": { - "builder": "DOCKERFILE", - "dockerContext": "packages" - }, - "deploy": { - "numReplicas": 1, - "restartPolicyType": "ON_FAILURE", - "restartPolicyMaxRetries": 10 - } -} From 908617d128a137e8af3ae483d3163f4eaf75ed37 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 21 Jan 2026 20:28:43 +0000 Subject: [PATCH 3/4] Fix Railway monorepo deployment - use UI configuration instead of railway.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Railway's auto-detection doesn't work with railway.toml files in subdirectories of a monorepo. For monorepos, Railway requires explicit UI configuration for each service. Changes: - Remove service-specific railway.toml files (caused "build plan" errors) - Add documentation-only railway.toml at root with configuration reference - Update deployment guides to use Railway UI configuration: - Create Empty Project first - Add each service manually from GitHub repo - Configure Dockerfile Path in Settings → Build - Add Watch Paths to trigger builds only for relevant changes - Configure all environment variables via UI - Clarify deployment order (desktop first, then agent, then UI) - Add warning about manual configuration requirement for monorepos Railway Configuration Method: - No auto-detection - Manual service creation via UI - Explicit Dockerfile path for each service - Watch paths for optimized builds (only rebuild when service changes) This approach ensures Railway builds each service correctly without confusion from multiple configuration files. --- RAILWAY_DEPLOYMENT.md | 96 +++++++++++++++-------------- RAILWAY_QUICKSTART.md | 48 ++++++++------- packages/bytebot-agent/railway.toml | 37 ----------- packages/bytebot-ui/railway.toml | 43 ------------- packages/bytebotd/railway.toml | 31 ---------- railway.toml | 20 ++++++ 6 files changed, 98 insertions(+), 177 deletions(-) delete mode 100644 packages/bytebot-agent/railway.toml delete mode 100644 packages/bytebot-ui/railway.toml delete mode 100644 packages/bytebotd/railway.toml create mode 100644 railway.toml diff --git a/RAILWAY_DEPLOYMENT.md b/RAILWAY_DEPLOYMENT.md index 281680915..bd821da5b 100644 --- a/RAILWAY_DEPLOYMENT.md +++ b/RAILWAY_DEPLOYMENT.md @@ -6,6 +6,8 @@ This guide shows how to deploy Bytebot on Railway **directly from this repositor Bytebot consists of four services that work together: +**Important:** This is a monorepo deployment. Railway requires **manual configuration via the UI** for each service. Do not rely on auto-detection - follow the step-by-step instructions below to configure each service explicitly. + 1. **PostgreSQL** - Database for tasks, messages, and summaries 2. **bytebot-agent** - NestJS backend for task orchestration and LLM integration 3. **bytebot-ui** - Next.js frontend with Express server for proxying @@ -26,9 +28,8 @@ Bytebot consists of four services that work together: 1. Go to [railway.app](https://railway.app/) and sign in 2. Click **"New Project"** -3. Select **"Deploy from GitHub repo"** -4. Connect your GitHub account and select this repository -5. Choose the branch you want to deploy (e.g., `main` or `development`) +3. Select **"Empty Project"** (we'll manually configure each service) +4. Name your project (e.g., "Bytebot Production") ### 2. Add PostgreSQL Database @@ -37,16 +38,44 @@ Bytebot consists of four services that work together: 3. Railway will automatically provision a PostgreSQL instance 4. The `DATABASE_URL` environment variable will be available as `${{Postgres.DATABASE_URL}}` -### 3. Deploy bytebot-agent Service +### 3. Deploy bytebot-desktop Service + +⚠️ **Deploy this first** - other services depend on it. + +1. Click **"New"** → **"GitHub Repo"** +2. Connect your GitHub account and select this repository +3. Name the service: `bytebot-desktop` (exact name matters for internal DNS) + +4. Configure build settings (Settings → Build): + - **Builder:** Dockerfile + - **Dockerfile Path:** `packages/bytebotd/Dockerfile` + - **Watch Paths:** `packages/bytebotd/**,packages/shared/**` + +5. Add environment variables (Variables tab): + ``` + DISPLAY=:0 + ``` + +6. Configure resources (Settings → Resources): + - **Memory:** 2GB minimum (4GB recommended) + - **CPU:** 2 vCPU minimum + - **Disk:** 2GB minimum + +7. Click **"Deploy"** + + **Note:** This service takes 5-10 minutes for initial build due to the Ubuntu desktop environment. Wait for it to be fully active before proceeding. + +### 4. Deploy bytebot-agent Service + +1. Click **"New"** → **"GitHub Repo"** → Select this repository +2. Name the service: `bytebot-agent` -1. Click **"New"** → **"GitHub Repo"** (or use existing deployment) -2. Select **"Add Service"** -3. Configure the service: - - **Name:** `bytebot-agent` - - **Root Directory:** (leave empty - Railway will use repository root) - - Railway will auto-detect build configuration from `packages/bytebot-agent/railway.toml` +3. Configure build settings (Settings → Build): + - **Builder:** Dockerfile + - **Dockerfile Path:** `packages/bytebot-agent/Dockerfile` + - **Watch Paths:** `packages/bytebot-agent/**,packages/shared/**` -4. Add environment variables: +4. Add environment variables (Variables tab): ``` DATABASE_URL=${{Postgres.DATABASE_URL}} BYTEBOT_DESKTOP_BASE_URL=http://bytebot-desktop.railway.internal:9990 @@ -57,63 +86,40 @@ Bytebot consists of four services that work together: ``` OPENAI_API_KEY=your-openai-api-key-here GEMINI_API_KEY=your-gemini-api-key-here - PORT=9991 ``` 5. Click **"Deploy"** -### 4. Deploy bytebot-desktop Service - -1. Click **"New"** → **"Service"** -2. Configure the service: - - **Name:** `bytebot-desktop` (must match the name used in agent config) - - **Root Directory:** (leave empty - Railway will use repository root) - - Railway will auto-detect build configuration from `packages/bytebotd/railway.toml` - -3. Add environment variables: - ``` - DISPLAY=:0 - PORT=9990 - ``` - -4. Configure resources (click on service → Settings → Resources): - - **Memory:** 2GB minimum (4GB recommended) - - **CPU:** 2 vCPU minimum - - **Disk:** 2GB minimum - -5. Click **"Deploy"** - - **Note:** This service takes 5-10 minutes for initial build due to the Ubuntu desktop environment. - ### 5. Deploy bytebot-ui Service -1. Click **"New"** → **"Service"** -2. Configure the service: - - **Name:** `bytebot-ui` - - **Root Directory:** (leave empty - Railway will use repository root) - - Railway will auto-detect build configuration from `packages/bytebot-ui/railway.toml` +1. Click **"New"** → **"GitHub Repo"** → Select this repository +2. Name the service: `bytebot-ui` + +3. Configure build settings (Settings → Build): + - **Builder:** Dockerfile + - **Dockerfile Path:** `packages/bytebot-ui/Dockerfile` + - **Watch Paths:** `packages/bytebot-ui/**,packages/shared/**` -3. Add build arguments (Settings → Build): +4. Add build variables (Settings → Variables → Add Variable → Check "Build Variable"): ``` BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify ``` -4. Add environment variables: +5. Add runtime environment variables (Variables tab): ``` BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify NEXT_PUBLIC_API_URL=http://bytebot-agent.railway.internal:9991 NODE_ENV=production HOSTNAME=0.0.0.0 - PORT=9992 ``` -5. Enable public networking (Settings → Networking): +6. Enable public networking (Settings → Networking): - Toggle **"Public Networking"** ON - Railway will assign a public URL (e.g., `https://bytebot-ui-production.up.railway.app`) -6. Click **"Deploy"** +7. Click **"Deploy"** ### 6. Verify Deployment diff --git a/RAILWAY_QUICKSTART.md b/RAILWAY_QUICKSTART.md index dbddbf074..bad90f59c 100644 --- a/RAILWAY_QUICKSTART.md +++ b/RAILWAY_QUICKSTART.md @@ -12,8 +12,8 @@ Deploy Bytebot to Railway from this repository in under 15 minutes. ### 1. Create Railway Project (2 min) - [ ] Go to [railway.app](https://railway.app/) → New Project -- [ ] Deploy from GitHub repo → Select this repository -- [ ] Choose branch (e.g., `main`) +- [ ] Select **Empty Project** (don't use GitHub auto-deploy yet) +- [ ] Name your project (e.g., "Bytebot") ### 2. Add PostgreSQL (1 min) @@ -22,32 +22,36 @@ Deploy Bytebot to Railway from this repository in under 15 minutes. ### 3. Deploy bytebot-desktop (10 min) -**Name:** `bytebot-desktop` (exact name matters!) +- [ ] Click **New** → **GitHub Repo** → Select this repository +- [ ] **Service Name:** `bytebot-desktop` (exact name matters!) -**Settings:** -- Root Directory: (leave empty - use repository root) -- Railway will auto-detect configuration from `packages/bytebotd/railway.toml` +**Configure Build (Settings → Build):** +- **Builder:** Dockerfile +- **Dockerfile Path:** `packages/bytebotd/Dockerfile` +- **Watch Paths:** `packages/bytebotd/**,packages/shared/**` -**Environment Variables:** +**Environment Variables (Variables tab):** ```bash DISPLAY=:0 ``` -**Resources** (Settings → Resources): +**Resources (Settings → Resources):** - Memory: 2048 MB (minimum) - CPU: 2 vCPU (minimum) -**Deploy** → Wait 5-10 minutes for Ubuntu desktop build +- [ ] Click **Deploy** → Wait 5-10 minutes for Ubuntu desktop build ### 4. Deploy bytebot-agent (3 min) -**Name:** `bytebot-agent` +- [ ] Click **New** → **GitHub Repo** → Select this repository +- [ ] **Service Name:** `bytebot-agent` -**Settings:** -- Root Directory: (leave empty - use repository root) -- Railway will auto-detect configuration from `packages/bytebot-agent/railway.toml` +**Configure Build (Settings → Build):** +- **Builder:** Dockerfile +- **Dockerfile Path:** `packages/bytebot-agent/Dockerfile` +- **Watch Paths:** `packages/bytebot-agent/**,packages/shared/**` -**Environment Variables** (Required): +**Environment Variables (Variables tab):** ```bash DATABASE_URL=${{Postgres.DATABASE_URL}} BYTEBOT_DESKTOP_BASE_URL=http://bytebot-desktop.railway.internal:9990 @@ -60,17 +64,19 @@ OPENAI_API_KEY=sk-xxxxx GEMINI_API_KEY=xxxxx ``` -**Deploy** +- [ ] Click **Deploy** ### 5. Deploy bytebot-ui (3 min) -**Name:** `bytebot-ui` +- [ ] Click **New** → **GitHub Repo** → Select this repository +- [ ] **Service Name:** `bytebot-ui` -**Settings:** -- Root Directory: (leave empty - use repository root) -- Railway will auto-detect configuration from `packages/bytebot-ui/railway.toml` +**Configure Build (Settings → Build):** +- **Builder:** Dockerfile +- **Dockerfile Path:** `packages/bytebot-ui/Dockerfile` +- **Watch Paths:** `packages/bytebot-ui/**,packages/shared/**` -**Build Args** (Settings → Variables → Build): +**Build Variables (Settings → Variables → Add Variable → Make Build Variable):** ```bash BYTEBOT_AGENT_BASE_URL=http://bytebot-agent.railway.internal:9991 BYTEBOT_DESKTOP_VNC_URL=ws://bytebot-desktop.railway.internal:9990/websockify @@ -89,7 +95,7 @@ HOSTNAME=0.0.0.0 - Enable **Public Networking** (Settings → Networking) - Copy the generated public URL -**Deploy** +- [ ] Click **Deploy** ### 6. Test (1 min) diff --git a/packages/bytebot-agent/railway.toml b/packages/bytebot-agent/railway.toml deleted file mode 100644 index bcbe733f9..000000000 --- a/packages/bytebot-agent/railway.toml +++ /dev/null @@ -1,37 +0,0 @@ -[build] -builder = "DOCKERFILE" -dockerfilePath = "packages/bytebot-agent/Dockerfile" - -[deploy] -startCommand = "npm run start:prod" -restartPolicyType = "ON_FAILURE" -restartPolicyMaxRetries = 10 - -# Service runs on internal port 9991 -[deploy.healthcheck] -path = "/" -timeout = 300 -interval = 60 - -[deploy.environmentVariables] -# Database connection string - automatically set by Railway when PostgreSQL is added -# Format: postgresql://user:password@host:port/database -# DATABASE_URL = "${POSTGRESQL_URL}" - -# Desktop service URL - set to Railway's internal networking URL -# Default assumes service is named "bytebot-desktop" in Railway -# BYTEBOT_DESKTOP_BASE_URL = "http://bytebot-desktop.railway.internal:9990" - -# AI Provider API Keys - at least one required -# ANTHROPIC_API_KEY = "" -# OPENAI_API_KEY = "" -# GEMINI_API_KEY = "" - -# Optional: LLM Proxy URL if using bytebot-llm-proxy service -# BYTEBOT_LLM_PROXY_URL = "http://bytebot-llm-proxy.railway.internal:4000" - -# Optional: Analytics endpoint -# BYTEBOT_ANALYTICS_ENDPOINT = "" - -# Port configuration (defaults to 9991 if not set) -# PORT = "9991" diff --git a/packages/bytebot-ui/railway.toml b/packages/bytebot-ui/railway.toml deleted file mode 100644 index 75db3e078..000000000 --- a/packages/bytebot-ui/railway.toml +++ /dev/null @@ -1,43 +0,0 @@ -[build] -builder = "DOCKERFILE" -dockerfilePath = "packages/bytebot-ui/Dockerfile" - -# Pass build args for internal service URLs -[build.buildArgs] -# These are used during the Next.js build process -# Railway's internal networking format: .railway.internal: -BYTEBOT_AGENT_BASE_URL = "http://bytebot-agent.railway.internal:9991" -BYTEBOT_DESKTOP_VNC_URL = "ws://bytebot-desktop.railway.internal:9990/websockify" - -[deploy] -startCommand = "npm run start" -restartPolicyType = "ON_FAILURE" -restartPolicyMaxRetries = 10 - -# This service should be publicly accessible -[deploy.healthcheck] -path = "/" -timeout = 300 -interval = 60 - -[deploy.environmentVariables] -# Runtime environment variables for the Express server and Next.js app -# These should match the build args above for consistency - -# Backend service URLs - Railway internal networking -# BYTEBOT_AGENT_BASE_URL = "http://bytebot-agent.railway.internal:9991" -# BYTEBOT_DESKTOP_VNC_URL = "ws://bytebot-desktop.railway.internal:9990/websockify" - -# Next.js public environment variable (exposed to browser) -# This should point to the agent service via internal networking -# The UI will proxy requests from the browser through its Express server -# NEXT_PUBLIC_API_URL = "http://bytebot-agent.railway.internal:9991" - -# Node environment -NODE_ENV = "production" - -# Port configuration (defaults to 9992 if not set) -# PORT = "9992" - -# Hostname -# HOSTNAME = "0.0.0.0" diff --git a/packages/bytebotd/railway.toml b/packages/bytebotd/railway.toml deleted file mode 100644 index 44a685142..000000000 --- a/packages/bytebotd/railway.toml +++ /dev/null @@ -1,31 +0,0 @@ -[build] -builder = "DOCKERFILE" -dockerfilePath = "packages/bytebotd/Dockerfile" - -[deploy] -# Bytebotd uses supervisord to manage multiple processes (X11, VNC, noVNC, desktop) -# The CMD in the Dockerfile starts supervisord -restartPolicyType = "ON_FAILURE" -restartPolicyMaxRetries = 10 - -# Desktop environment requires more resources -# Recommended: 2GB RAM, 2 vCPU -# Railway will use defaults if not specified in the UI - -# Health check on the bytebotd HTTP endpoint -[deploy.healthcheck] -path = "/" -timeout = 300 -interval = 60 - -[deploy.environmentVariables] -# X11 Display configuration (required for desktop environment) -DISPLAY = ":0" - -# Port configuration (defaults to 9990 if not set) -# This port serves both the bytebotd API and noVNC websocket endpoint -# PORT = "9990" - -# Note: This service requires significant resources due to the full desktop environment -# including XFCE, Firefox, VS Code, and VNC server -# Recommended Railway plan: Pro or higher for optimal performance diff --git a/railway.toml b/railway.toml new file mode 100644 index 000000000..f3c49a4b4 --- /dev/null +++ b/railway.toml @@ -0,0 +1,20 @@ +# Railway Configuration for Bytebot Monorepo +# +# IMPORTANT: This file is for documentation only. +# Railway requires manual service configuration for monorepos. +# +# For each service, configure in Railway UI: +# +# Service: bytebot-agent +# - Dockerfile Path: packages/bytebot-agent/Dockerfile +# - Watch Paths: packages/bytebot-agent/**, packages/shared/** +# +# Service: bytebot-ui +# - Dockerfile Path: packages/bytebot-ui/Dockerfile +# - Watch Paths: packages/bytebot-ui/**, packages/shared/** +# +# Service: bytebot-desktop +# - Dockerfile Path: packages/bytebotd/Dockerfile +# - Watch Paths: packages/bytebotd/**, packages/shared/** +# +# All services use repository root as build context. From 2a8afd84df6df1abcb1f0a40f0e64458dcc91dd8 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 21 Jan 2026 20:39:06 +0000 Subject: [PATCH 4/4] Fix Railway build - add root-level Dockerfiles with correct build context Railway sets the build context to the directory containing the Dockerfile. When Dockerfile path is packages/SERVICE/Dockerfile, context becomes packages/SERVICE/, causing COPY packages/shared to fail. Solution: Create Dockerfiles at repository root (Dockerfile.agent, Dockerfile.ui, Dockerfile.desktop) that Railway can use with repo root as the build context. Changes: - Add Dockerfile.agent - Agent service with repo root context - Add Dockerfile.ui - UI service with repo root context - Add Dockerfile.desktop - Desktop service with repo root context - Update RAILWAY_QUICKSTART.md to use root-level Dockerfiles - Update RAILWAY_DEPLOYMENT.md to use root-level Dockerfiles - Update railway.toml documentation Railway Configuration Now: - Dockerfile Path: Dockerfile.agent (not packages/bytebot-agent/Dockerfile) - Dockerfile Path: Dockerfile.ui (not packages/bytebot-ui/Dockerfile) - Dockerfile Path: Dockerfile.desktop (not packages/bytebotd/Dockerfile) - Build context: Repository root (automatic when Dockerfile is at root) - All COPY commands work correctly This fixes the "Error creating build plan" issue. --- Dockerfile.agent | 22 ++++ Dockerfile.desktop | 252 ++++++++++++++++++++++++++++++++++++++++++ Dockerfile.ui | 29 +++++ RAILWAY_DEPLOYMENT.md | 6 +- RAILWAY_QUICKSTART.md | 6 +- railway.toml | 11 +- 6 files changed, 316 insertions(+), 10 deletions(-) create mode 100644 Dockerfile.agent create mode 100644 Dockerfile.desktop create mode 100644 Dockerfile.ui diff --git a/Dockerfile.agent b/Dockerfile.agent new file mode 100644 index 000000000..46159d3d7 --- /dev/null +++ b/Dockerfile.agent @@ -0,0 +1,22 @@ +# Railway Deployment Dockerfile for bytebot-agent +# Build context: repository root +FROM node:20-alpine + +WORKDIR /app + +# Copy shared package +COPY packages/shared ./shared + +# Copy agent package +COPY packages/bytebot-agent ./bytebot-agent + +WORKDIR /app/bytebot-agent + +# Install dependencies +RUN npm install + +# Build the application +RUN npm run build + +# Start the application +CMD ["npm", "run", "start:prod"] diff --git a/Dockerfile.desktop b/Dockerfile.desktop new file mode 100644 index 000000000..3b450f752 --- /dev/null +++ b/Dockerfile.desktop @@ -0,0 +1,252 @@ +# ----------------------------------------------------------------------------- +# Bytebot Dockerfile - Virtual Desktop Environment +# ----------------------------------------------------------------------------- + +# Base image +FROM ubuntu:22.04 + +# ----------------------------------------------------------------------------- +# 1. Environment setup +# ----------------------------------------------------------------------------- +# Set non-interactive installation +ARG DEBIAN_FRONTEND=noninteractive +# Configure display for X11 applications +ENV DISPLAY=:0 + +# ----------------------------------------------------------------------------- +# 2. System dependencies installation +# ----------------------------------------------------------------------------- +RUN apt-get update && apt-get install -y \ + # X11 / VNC + xvfb x11vnc xauth x11-xserver-utils \ + x11-apps sudo software-properties-common \ + # Desktop environment + xfce4 xfce4-goodies dbus wmctrl \ + # Display manager with autologin capability + lightdm \ + # Development tools + python3 python3-pip curl wget git vim \ + # Utilities + supervisor netcat-openbsd \ + # Applications + xpdf gedit xpaint \ + # Libraries + libxtst-dev \ + # Remove unneeded dependencies + && apt-get remove -y light-locker xfce4-screensaver xfce4-power-manager || true \ + # Clean up to reduce image size + && apt-get clean && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /run/dbus && \ + # Generate a machine-id so dbus-daemon doesn't complain + dbus-uuidgen --ensure=/etc/machine-id + +# ----------------------------------------------------------------------------- +# 3. Additional software installation +# ----------------------------------------------------------------------------- +# Install Firefox +RUN apt-get update && apt-get install -y \ + # Install necessary for adding PPA + software-properties-common apt-transport-https wget gnupg \ + # Install Additional Graphics Libraries + mesa-utils \ + libgl1-mesa-dri \ + libgl1-mesa-glx \ + # Install Sandbox Capabilities + libcap2-bin \ + # Install Fonts + fontconfig \ + fonts-dejavu \ + fonts-liberation \ + fonts-freefont-ttf \ + && add-apt-repository -y ppa:mozillateam/ppa \ + && apt-get update \ + && apt-get install -y firefox-esr thunderbird \ + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + # Set Firefox as default browser system-wide + && update-alternatives --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox-esr 200 \ + && update-alternatives --set x-www-browser /usr/bin/firefox-esr \ + && fc-cache -f -v + + +# Install 1Password based on architecture +RUN ARCH=$(dpkg --print-architecture) && \ + if [ "$ARCH" = "amd64" ]; then \ + # Install from APT repository for AMD64 + curl -sS https://downloads.1password.com/linux/keys/1password.asc | \ + gpg --dearmor --output /usr/share/keyrings/1password-archive-keyring.gpg && \ + echo "deb [arch=amd64 signed-by=/usr/share/keyrings/1password-archive-keyring.gpg] https://downloads.1password.com/linux/debian/amd64 stable main" | \ + tee /etc/apt/sources.list.d/1password.list && \ + mkdir -p /etc/debsig/policies/AC2D62742012EA22/ && \ + curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol | \ + tee /etc/debsig/policies/AC2D62742012EA22/1password.pol && \ + mkdir -p /usr/share/debsig/keyrings/AC2D62742012EA22 && \ + curl -sS https://downloads.1password.com/linux/keys/1password.asc | \ + gpg --dearmor --output /usr/share/debsig/keyrings/AC2D62742012EA22/debsig.gpg && \ + apt-get update && apt-get install -y 1password && \ + apt-get clean && rm -rf /var/lib/apt/lists/*; \ + elif [ "$ARCH" = "arm64" ]; then \ + # Install from tar.gz for ARM64 + apt-get update && apt-get install -y \ + libgtk-3-0 libnotify4 libnss3 libxss1 libxtst6 xdg-utils \ + libatspi2.0-0 libdrm2 libgbm1 libxcb-dri3-0 libxkbcommon0 \ + libsecret-1-0 && \ + apt-get clean && rm -rf /var/lib/apt/lists/* && \ + curl -sSL https://downloads.1password.com/linux/tar/beta/aarch64/1password-latest.tar.gz -o /tmp/1password.tar.gz && \ + # Extract the full 1Password bundle so libraries like libffmpeg.so remain in their expected relative paths + mkdir -p /opt/1password && \ + tar -xzf /tmp/1password.tar.gz -C /opt/1password --strip-components=1 && \ + # Link the main executable into the global PATH + ln -sf /opt/1password/1password /usr/bin/1password && \ + chmod +x /opt/1password/1password && \ + # Copy icons to standard locations + mkdir -p /usr/share/pixmaps /usr/share/icons/hicolor/512x512/apps /usr/share/icons/hicolor/256x256/apps && \ + find /opt/1password -name "*1password*.png" -o -name "*1password*.svg" | while read icon; do \ + if [[ "$icon" == *"512"* ]]; then \ + cp "$icon" /usr/share/icons/hicolor/512x512/apps/1password.png 2>/dev/null || true; \ + elif [[ "$icon" == *"256"* ]]; then \ + cp "$icon" /usr/share/icons/hicolor/256x256/apps/1password.png 2>/dev/null || true; \ + fi; \ + cp "$icon" /usr/share/pixmaps/1password.png 2>/dev/null || true; \ + done && \ + # Clean up temporary files + rm -rf /tmp/1password.tar.gz && \ + # Update icon cache + gtk-update-icon-cache -f -t /usr/share/icons/hicolor 2>/dev/null || true; \ + else \ + echo "1Password is not available for $ARCH architecture."; \ + fi + +# Install Visual Studio Code +RUN ARCH=$(dpkg --print-architecture) && \ + if [ "$ARCH" = "amd64" ]; then \ + apt-get update && apt-get install -y wget gpg apt-transport-https software-properties-common && \ + wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/ms_vscode.gpg && \ + echo "deb [arch=amd64 signed-by=/usr/share/keyrings/ms_vscode.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list && \ + apt-get update && apt-get install -y code && \ + apt-get clean && rm -rf /var/lib/apt/lists/* ; \ + elif [ "$ARCH" = "arm64" ]; then \ + apt-get update && apt-get install -y wget gpg && \ + wget -qO /tmp/code_arm64.deb https://update.code.visualstudio.com/latest/linux-deb-arm64/stable && \ + apt-get install -y /tmp/code_arm64.deb && \ + rm -f /tmp/code_arm64.deb && \ + apt-get clean && rm -rf /var/lib/apt/lists/* ; \ + else \ + echo "VSCode is not available for $ARCH architecture."; \ + fi + +# Install Node.js +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get update \ + && apt-get install -y nodejs \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Upgrade pip +RUN pip3 install --upgrade pip + +# ----------------------------------------------------------------------------- +# 4. VNC and remote access setup +# ----------------------------------------------------------------------------- +# Install noVNC and websockify +RUN git clone https://github.com/novnc/noVNC.git /opt/noVNC \ + && git clone https://github.com/novnc/websockify.git /opt/websockify \ + && cd /opt/websockify \ + && pip3 install --break-system-packages . + +# ----------------------------------------------------------------------------- +# 5. Application setup (bytebotd) +# ----------------------------------------------------------------------------- +# Copy package files first to leverage Docker cache + +# Install dependencies required to build libnut-core and uiohook-napi +RUN apt-get update && \ + apt-get install -y \ + cmake \ + libx11-dev \ + libxtst-dev \ + libxinerama-dev \ + libxi-dev \ + libxt-dev \ + libxrandr-dev \ + libxkbcommon-dev \ + libxkbcommon-x11-dev \ + xclip \ + git build-essential && \ + rm -rf /var/lib/apt/lists/* + +# Copy app source from repository root +# Note: Build context is the repository root for Railway +COPY packages/shared /bytebot/shared/ +COPY packages/bytebotd /bytebot/bytebotd/ +WORKDIR /bytebot/bytebotd +RUN npm install --build-from-source +RUN npm rebuild uiohook-napi --build-from-source + +RUN npm run build + +WORKDIR /compile + +RUN git clone https://github.com/ZachJW34/libnut-core.git && \ + cd libnut-core && \ + npm install && \ + npm run build:release + +# replace /bytebotd/node_modules/@nut-tree-fork/libnut-linux/build/Release/libnut.node with /compile/libnut-core/build/Release/libnut.node +RUN rm -f /bytebot/bytebotd/node_modules/@nut-tree-fork/libnut-linux/build/Release/libnut.node && \ + cp /compile/libnut-core/build/Release/libnut.node /bytebot/bytebotd/node_modules/@nut-tree-fork/libnut-linux/build/Release/libnut.node + +RUN rm -rf /compile + +WORKDIR /bytebot/bytebotd + +# ----------------------------------------------------------------------------- +# 7. User setup and autologin configuration +# ----------------------------------------------------------------------------- +# Create non-root user +RUN useradd -ms /bin/bash user && echo "user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers + +RUN mkdir -p /var/run/dbus && \ + chmod 755 /var/run/dbus && \ + chown user:user /var/run/dbus + +RUN mkdir -p /tmp/bytebot-screenshots && \ + chown -R user:user /tmp/bytebot-screenshots + +# ----------------------------------------------------------------------------- +# Copy staged system files and keep sane permissions +# ----------------------------------------------------------------------------- +# 1. Ensure everything under /bytebotd/root is owned by root (files + dirs) +# 2. Set *files* to 0644 and *directories* to 0755 so that applications can +# traverse directories (execute bit!) while keeping the contents read-only. +# 3. Copy the tree to / +RUN chown -R root:root /bytebot/bytebotd/root && \ + find /bytebot/bytebotd/root -type f -exec chmod 644 {} + && \ + find /bytebot/bytebotd/root -type d -exec chmod 755 {} + && \ + find /bytebot/bytebotd/root -type f -executable -exec chmod +x {} + && \ + cp -a /bytebot/bytebotd/root/. / + +RUN chown -R user:user /home/user +RUN chmod -R 755 /home/user + +RUN mkdir -p /home/user/Desktop && \ + cp -f /usr/share/applications/firefox.desktop /home/user/Desktop/ && \ + cp -f /usr/share/applications/thunderbird.desktop /home/user/Desktop/ && \ + cp -f /usr/share/applications/1password.desktop /home/user/Desktop/ && \ + cp -f /usr/share/applications/code.desktop /home/user/Desktop/ && \ + cp -f /usr/share/applications/terminal.desktop /home/user/Desktop/ && \ + chmod +x /home/user/Desktop/*.desktop && \ + chown user:user /home/user/Desktop/*.desktop + +RUN mkdir -p /home/user/.config /home/user/.local/share /home/user/.cache \ + && chown -R user:user /home/user/.config /home/user/.local /home/user/.cache + +WORKDIR /home/user + +# ----------------------------------------------------------------------------- +# 8. Port configuration and runtime +# ----------------------------------------------------------------------------- +# - Port 9990: bytebotd and external noVNC websocket +EXPOSE 9990 + +# Start supervisor to manage all services +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf", "-n"] \ No newline at end of file diff --git a/Dockerfile.ui b/Dockerfile.ui new file mode 100644 index 000000000..ad205d96f --- /dev/null +++ b/Dockerfile.ui @@ -0,0 +1,29 @@ +# Railway Deployment Dockerfile for bytebot-ui +# Build context: repository root +FROM node:20-alpine + +# Build arguments for Next.js +ARG BYTEBOT_AGENT_BASE_URL +ARG BYTEBOT_DESKTOP_VNC_URL + +ENV BYTEBOT_AGENT_BASE_URL=${BYTEBOT_AGENT_BASE_URL} +ENV BYTEBOT_DESKTOP_VNC_URL=${BYTEBOT_DESKTOP_VNC_URL} + +WORKDIR /app + +# Copy shared package +COPY packages/shared ./shared + +# Copy UI package +COPY packages/bytebot-ui ./bytebot-ui + +WORKDIR /app/bytebot-ui + +# Install dependencies +RUN npm install + +# Build the application +RUN npm run build + +# Start the application +CMD ["npm", "run", "start"] diff --git a/RAILWAY_DEPLOYMENT.md b/RAILWAY_DEPLOYMENT.md index bd821da5b..afcd81b11 100644 --- a/RAILWAY_DEPLOYMENT.md +++ b/RAILWAY_DEPLOYMENT.md @@ -48,7 +48,7 @@ Bytebot consists of four services that work together: 4. Configure build settings (Settings → Build): - **Builder:** Dockerfile - - **Dockerfile Path:** `packages/bytebotd/Dockerfile` + - **Dockerfile Path:** `Dockerfile.desktop` - **Watch Paths:** `packages/bytebotd/**,packages/shared/**` 5. Add environment variables (Variables tab): @@ -72,7 +72,7 @@ Bytebot consists of four services that work together: 3. Configure build settings (Settings → Build): - **Builder:** Dockerfile - - **Dockerfile Path:** `packages/bytebot-agent/Dockerfile` + - **Dockerfile Path:** `Dockerfile.agent` - **Watch Paths:** `packages/bytebot-agent/**,packages/shared/**` 4. Add environment variables (Variables tab): @@ -97,7 +97,7 @@ Bytebot consists of four services that work together: 3. Configure build settings (Settings → Build): - **Builder:** Dockerfile - - **Dockerfile Path:** `packages/bytebot-ui/Dockerfile` + - **Dockerfile Path:** `Dockerfile.ui` - **Watch Paths:** `packages/bytebot-ui/**,packages/shared/**` 4. Add build variables (Settings → Variables → Add Variable → Check "Build Variable"): diff --git a/RAILWAY_QUICKSTART.md b/RAILWAY_QUICKSTART.md index bad90f59c..c095aa226 100644 --- a/RAILWAY_QUICKSTART.md +++ b/RAILWAY_QUICKSTART.md @@ -27,7 +27,7 @@ Deploy Bytebot to Railway from this repository in under 15 minutes. **Configure Build (Settings → Build):** - **Builder:** Dockerfile -- **Dockerfile Path:** `packages/bytebotd/Dockerfile` +- **Dockerfile Path:** `Dockerfile.desktop` - **Watch Paths:** `packages/bytebotd/**,packages/shared/**` **Environment Variables (Variables tab):** @@ -48,7 +48,7 @@ DISPLAY=:0 **Configure Build (Settings → Build):** - **Builder:** Dockerfile -- **Dockerfile Path:** `packages/bytebot-agent/Dockerfile` +- **Dockerfile Path:** `Dockerfile.agent` - **Watch Paths:** `packages/bytebot-agent/**,packages/shared/**` **Environment Variables (Variables tab):** @@ -73,7 +73,7 @@ GEMINI_API_KEY=xxxxx **Configure Build (Settings → Build):** - **Builder:** Dockerfile -- **Dockerfile Path:** `packages/bytebot-ui/Dockerfile` +- **Dockerfile Path:** `Dockerfile.ui` - **Watch Paths:** `packages/bytebot-ui/**,packages/shared/**` **Build Variables (Settings → Variables → Add Variable → Make Build Variable):** diff --git a/railway.toml b/railway.toml index f3c49a4b4..176263174 100644 --- a/railway.toml +++ b/railway.toml @@ -3,18 +3,21 @@ # IMPORTANT: This file is for documentation only. # Railway requires manual service configuration for monorepos. # +# Railway automatically sets the build context based on the Dockerfile location. +# To ensure the context is the repository root, we use Dockerfiles at the root level. +# # For each service, configure in Railway UI: # # Service: bytebot-agent -# - Dockerfile Path: packages/bytebot-agent/Dockerfile +# - Dockerfile Path: Dockerfile.agent # - Watch Paths: packages/bytebot-agent/**, packages/shared/** # # Service: bytebot-ui -# - Dockerfile Path: packages/bytebot-ui/Dockerfile +# - Dockerfile Path: Dockerfile.ui # - Watch Paths: packages/bytebot-ui/**, packages/shared/** # # Service: bytebot-desktop -# - Dockerfile Path: packages/bytebotd/Dockerfile +# - Dockerfile Path: Dockerfile.desktop # - Watch Paths: packages/bytebotd/**, packages/shared/** # -# All services use repository root as build context. +# All Dockerfiles are at the repository root, ensuring the build context is correct.