fix: standalone Dockerfile + clear Railway deploy instructions

- Rewrite Dockerfile to be fully standalone (no workspace deps)
- Use npm install instead of pnpm workspace
- Update README with step-by-step Railway deployment
- Critical: Root Directory must be set to 'secure' in Railway
- Add instructions for getting Telegram user ID

https://claude.ai/code/session_015VqJ7gN4vaxtYfYc92UjLs
This commit is contained in:
Claude 2026-01-30 07:28:25 +00:00
parent 6a0c49e5c7
commit b4f8a457a8
No known key found for this signature in database
4 changed files with 52 additions and 54 deletions

View File

@ -2,34 +2,30 @@
"$schema": "https://railway.app/railway.schema.json", "$schema": "https://railway.app/railway.schema.json",
"name": "AssureBot", "name": "AssureBot",
"description": "Lean, secure, self-hosted AI assistant with Telegram, document analysis, and scheduled tasks", "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": [ "services": [
{ {
"name": "assurebot", "name": "assurebot",
"build": { "build": {
"builder": "DOCKERFILE", "builder": "DOCKERFILE",
"dockerfilePath": "secure/Dockerfile" "dockerfilePath": "secure/Dockerfile",
"watchPatterns": ["secure/**"]
}, },
"deploy": { "deploy": {
"startCommand": "node dist/index.js", "startCommand": "node dist/index.js",
"healthcheckPath": "/health", "healthcheckPath": "/health",
"healthcheckTimeout": 30, "healthcheckTimeout": 60,
"restartPolicyType": "ON_FAILURE", "restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 3 "restartPolicyMaxRetries": 3
}, },
"variables": { "variables": {
"DATABASE_URL": { "DATABASE_URL": "${{Postgres.DATABASE_URL}}",
"reference": "postgres.DATABASE_URL" "REDIS_URL": "${{Redis.REDIS_URL}}",
},
"REDIS_URL": {
"reference": "redis.REDIS_URL"
},
"TELEGRAM_BOT_TOKEN": { "TELEGRAM_BOT_TOKEN": {
"description": "Telegram bot token from @BotFather", "description": "Telegram bot token from @BotFather",
"required": true "required": true
}, },
"ALLOWED_USERS": { "ALLOWED_USERS": {
"description": "Comma-separated Telegram user IDs (e.g., 123456789,987654321)", "description": "Comma-separated Telegram user IDs",
"required": true "required": true
}, },
"ANTHROPIC_API_KEY": { "ANTHROPIC_API_KEY": {
@ -37,33 +33,25 @@
"required": false "required": false
}, },
"OPENAI_API_KEY": { "OPENAI_API_KEY": {
"description": "OpenAI API key (or use ANTHROPIC_API_KEY or OPENROUTER_API_KEY)", "description": "OpenAI API key",
"required": false "required": false
}, },
"OPENROUTER_API_KEY": { "OPENROUTER_API_KEY": {
"description": "OpenRouter API key (or use ANTHROPIC_API_KEY or OPENAI_API_KEY)", "description": "OpenRouter API key (100+ models)",
"required": false "required": false
}, },
"AI_MODEL": { "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 "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" "plugin": "postgresql"
}, },
{ {
"name": "redis", "name": "Redis",
"plugin": "redis" "plugin": "redis"
} }
] ]

View File

@ -1,43 +1,42 @@
# AssureBot - Minimal Docker Image # AssureBot - Standalone Docker Image
# Lean, secure, self-hosted AI assistant for Railway # 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 FROM node:22-slim AS builder
WORKDIR /app WORKDIR /app
# Install pnpm # Copy package files (handles both root and secure/ as context)
RUN corepack enable && corepack prepare pnpm@latest --activate COPY package*.json ./
COPY tsconfig.json* ./
# Copy workspace config and package files COPY *.ts ./
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./ COPY *.d.ts ./
COPY secure/package.json ./secure/
# Install dependencies # Install dependencies
RUN pnpm install --frozen-lockfile --prod=false RUN npm install --omit=dev=false
# Copy source
COPY secure/ ./secure/
# Build TypeScript # Build TypeScript
RUN cd secure && pnpm exec tsc RUN npm run build
# Production image # Production image
FROM node:22-slim AS runner FROM node:22-slim AS runner
# Security: Run as non-root user # Security: Run as non-root user
RUN useradd -m -u 1000 -s /bin/bash assurebot RUN useradd -m -u 1000 -s /bin/bash assurebot
USER assurebot
WORKDIR /app WORKDIR /app
# Copy built files and production deps # Copy built files and production deps
COPY --from=builder --chown=assurebot:assurebot /app/node_modules ./node_modules 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/dist ./dist
COPY --from=builder --chown=assurebot:assurebot /app/secure/dist ./dist COPY --from=builder --chown=assurebot:assurebot /app/package.json ./
COPY --from=builder --chown=assurebot:assurebot /app/secure/package.json ./
# Create data directory for audit logs # Create data directory for audit logs (before switching user)
RUN mkdir -p /app/data RUN mkdir -p /app/data && chown assurebot:assurebot /app/data
USER assurebot
ENV NODE_ENV=production ENV NODE_ENV=production
ENV PORT=8080 ENV PORT=8080
@ -45,7 +44,7 @@ ENV PORT=8080
EXPOSE 8080 EXPOSE 8080
# Health check # 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 -e "fetch('http://localhost:8080/health').then(r => process.exit(r.ok ? 0 : 1))" || exit 1
CMD ["node", "dist/index.js"] CMD ["node", "dist/index.js"]

View File

@ -49,17 +49,27 @@ Your AI agent that runs on your infrastructure, answers only to you, and you can
## Deploy to Railway ## Deploy to Railway
### One-Click ### Quick Start
[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/assurebot)
### Manual
1. Fork this repo 1. Fork this repo
2. Create Railway project from GitHub 2. Create new Railway project → "Deploy from GitHub repo"
3. Set environment variables (see below) 3. Select your fork
4. Add volume at `/data` 4. **Critical**: Click "Settings" → Set **Root Directory** to `secure`
5. Deploy 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 ## Configuration

View File

@ -2,12 +2,13 @@
"$schema": "https://railway.app/railway.schema.json", "$schema": "https://railway.app/railway.schema.json",
"build": { "build": {
"builder": "DOCKERFILE", "builder": "DOCKERFILE",
"dockerfilePath": "secure/Dockerfile" "dockerfilePath": "Dockerfile"
}, },
"deploy": { "deploy": {
"startCommand": "node dist/index.js",
"healthcheckPath": "/health", "healthcheckPath": "/health",
"healthcheckTimeout": 30, "healthcheckTimeout": 60,
"restartPolicyType": "ON_FAILURE", "restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 5 "restartPolicyMaxRetries": 3
} }
} }