diff --git a/railway-template.json b/railway-template.json index 875839848..b0a0a4868 100644 --- a/railway-template.json +++ b/railway-template.json @@ -2,34 +2,30 @@ "$schema": "https://railway.app/railway.schema.json", "name": "AssureBot", "description": "Lean, secure, self-hosted AI assistant with Telegram, document analysis, and scheduled tasks", - "icon": "https://raw.githubusercontent.com/TNovs1/moltbot/main/secure/icon.png", "services": [ { "name": "assurebot", "build": { "builder": "DOCKERFILE", - "dockerfilePath": "secure/Dockerfile" + "dockerfilePath": "secure/Dockerfile", + "watchPatterns": ["secure/**"] }, "deploy": { "startCommand": "node dist/index.js", "healthcheckPath": "/health", - "healthcheckTimeout": 30, + "healthcheckTimeout": 60, "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 3 }, "variables": { - "DATABASE_URL": { - "reference": "postgres.DATABASE_URL" - }, - "REDIS_URL": { - "reference": "redis.REDIS_URL" - }, + "DATABASE_URL": "${{Postgres.DATABASE_URL}}", + "REDIS_URL": "${{Redis.REDIS_URL}}", "TELEGRAM_BOT_TOKEN": { "description": "Telegram bot token from @BotFather", "required": true }, "ALLOWED_USERS": { - "description": "Comma-separated Telegram user IDs (e.g., 123456789,987654321)", + "description": "Comma-separated Telegram user IDs", "required": true }, "ANTHROPIC_API_KEY": { @@ -37,33 +33,25 @@ "required": false }, "OPENAI_API_KEY": { - "description": "OpenAI API key (or use ANTHROPIC_API_KEY or OPENROUTER_API_KEY)", + "description": "OpenAI API key", "required": false }, "OPENROUTER_API_KEY": { - "description": "OpenRouter API key (or use ANTHROPIC_API_KEY or OPENAI_API_KEY)", + "description": "OpenRouter API key (100+ models)", "required": false }, "AI_MODEL": { - "description": "Model to use (e.g., claude-3-5-sonnet-20241022, gpt-4o, anthropic/claude-3.5-sonnet)", + "description": "Model override (e.g., claude-3-5-sonnet-20241022)", "required": false - }, - "WEBHOOK_SECRET": { - "description": "Secret for authenticating webhooks (auto-generated if empty)", - "required": false - }, - "SANDBOX_ENABLED": { - "description": "Enable Docker sandbox for code execution", - "default": "false" } } }, { - "name": "postgres", + "name": "Postgres", "plugin": "postgresql" }, { - "name": "redis", + "name": "Redis", "plugin": "redis" } ] diff --git a/secure/Dockerfile b/secure/Dockerfile index 8c58159d3..aed3e01bb 100644 --- a/secure/Dockerfile +++ b/secure/Dockerfile @@ -1,43 +1,42 @@ -# AssureBot - Minimal Docker Image +# AssureBot - Standalone Docker Image # Lean, secure, self-hosted AI assistant for Railway +# +# Build from repo root: docker build -f secure/Dockerfile . +# Or set Railway root directory to: secure/ FROM node:22-slim AS builder WORKDIR /app -# Install pnpm -RUN corepack enable && corepack prepare pnpm@latest --activate - -# Copy workspace config and package files -COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./ -COPY secure/package.json ./secure/ +# Copy package files (handles both root and secure/ as context) +COPY package*.json ./ +COPY tsconfig.json* ./ +COPY *.ts ./ +COPY *.d.ts ./ # Install dependencies -RUN pnpm install --frozen-lockfile --prod=false - -# Copy source -COPY secure/ ./secure/ +RUN npm install --omit=dev=false # Build TypeScript -RUN cd secure && pnpm exec tsc +RUN npm run build # Production image FROM node:22-slim AS runner # Security: Run as non-root user RUN useradd -m -u 1000 -s /bin/bash assurebot -USER assurebot WORKDIR /app # Copy built files and production deps COPY --from=builder --chown=assurebot:assurebot /app/node_modules ./node_modules -COPY --from=builder --chown=assurebot:assurebot /app/secure/node_modules ./secure/node_modules -COPY --from=builder --chown=assurebot:assurebot /app/secure/dist ./dist -COPY --from=builder --chown=assurebot:assurebot /app/secure/package.json ./ +COPY --from=builder --chown=assurebot:assurebot /app/dist ./dist +COPY --from=builder --chown=assurebot:assurebot /app/package.json ./ -# Create data directory for audit logs -RUN mkdir -p /app/data +# Create data directory for audit logs (before switching user) +RUN mkdir -p /app/data && chown assurebot:assurebot /app/data + +USER assurebot ENV NODE_ENV=production ENV PORT=8080 @@ -45,7 +44,7 @@ ENV PORT=8080 EXPOSE 8080 # Health check -HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ +HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD node -e "fetch('http://localhost:8080/health').then(r => process.exit(r.ok ? 0 : 1))" || exit 1 CMD ["node", "dist/index.js"] diff --git a/secure/README.md b/secure/README.md index e3ad514e2..caa2ed4b3 100644 --- a/secure/README.md +++ b/secure/README.md @@ -49,17 +49,27 @@ Your AI agent that runs on your infrastructure, answers only to you, and you can ## Deploy to Railway -### One-Click - -[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/assurebot) - -### Manual +### Quick Start 1. Fork this repo -2. Create Railway project from GitHub -3. Set environment variables (see below) -4. Add volume at `/data` -5. Deploy +2. Create new Railway project → "Deploy from GitHub repo" +3. Select your fork +4. **Critical**: Click "Settings" → Set **Root Directory** to `secure` +5. Add services: + - Click "New" → "Database" → "PostgreSQL" + - Click "New" → "Database" → "Redis" +6. In main service, add Variables: + - `TELEGRAM_BOT_TOKEN` (from @BotFather) + - `ALLOWED_USERS` (your Telegram user ID, get it from @userinfobot) + - `OPENROUTER_API_KEY` or `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` +7. Railway auto-wires `DATABASE_URL` and `REDIS_URL` from the database services +8. Deploy! + +### Getting Your Telegram User ID + +1. Message @userinfobot on Telegram +2. It replies with your user ID (a number like `123456789`) +3. Use this as `ALLOWED_USERS` ## Configuration diff --git a/secure/railway.json b/secure/railway.json index 39c1c8402..00de9201e 100644 --- a/secure/railway.json +++ b/secure/railway.json @@ -2,12 +2,13 @@ "$schema": "https://railway.app/railway.schema.json", "build": { "builder": "DOCKERFILE", - "dockerfilePath": "secure/Dockerfile" + "dockerfilePath": "Dockerfile" }, "deploy": { + "startCommand": "node dist/index.js", "healthcheckPath": "/health", - "healthcheckTimeout": 30, + "healthcheckTimeout": 60, "restartPolicyType": "ON_FAILURE", - "restartPolicyMaxRetries": 5 + "restartPolicyMaxRetries": 3 } }