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:
parent
6a0c49e5c7
commit
b4f8a457a8
@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -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"]
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
[](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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user