---
title: "Deploy Bag Of Words"
description: "Chat with your data with memory, rules, and observability built in."
category: "Analytics"
url: https://railway.com/deploy/bagofwords
---

# Deploy Bag Of Words

Chat with your data with memory, rules, and observability built in.

**[Deploy Bag Of Words on Railway](https://railway.com/template/bagofwords)**

- **Creator:** Muhammad Bilal
- **Category:** Analytics

## Template content

### bagofwords

- **Image:** bagofwords/bagofwords:latest

### Postgres https://devicons.railway.app/i/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

## Documentation

# Deploy and Host Bag of Words on Railway

## About Hosting Bag of Words

Bag of Words (BOW) is an open-source agentic analytics platform that connects LLMs with business data, tools, credentials, instructions, and permissions. It enables teams to build data agents that can generate queries, reports, dashboards, deep analysis, root-cause investigations, automations, scheduled tasks, and MCP workflows.

Railway hosts BOW as a Docker-based application with PostgreSQL providing persistent application data. The application and database communicate through Railway's private network, while Railway provides public HTTP/HTTPS networking for users and external integrations.

The recommended deployment uses the published `bagofwords/bagofwords` Docker image and a Railway PostgreSQL service. A separate Caddy, Docker Compose, or Kubernetes deployment is not required. Railway handles service networking, domains, TLS, environment variables, and application scaling.

BOW can connect to external databases, warehouses, BI systems, files, business applications, LLM providers, MCP servers, and APIs after deployment.

## Common Use Cases

* **AI-Powered Analytics**: Ask questions about business data and generate queries, charts, reports, dashboards, and deeper analysis.
* **Data Agents**: Create specialized agents with dedicated data, tools, credentials, instructions, permissions, starters, and evaluations.
* **Automated Analytics**: Schedule reports and investigations or trigger agents through webhooks and APIs.
* **Governed Enterprise Analytics**: Use RBAC, approvals, audit logs, service accounts, SSO, model policies, and row-level security support.
* **MCP Workflows**: Connect agents to MCP servers and custom APIs and use them through supported MCP clients.

## Dependencies for Bag of Words Hosting

* **PostgreSQL** — Recommended persistent database for the Railway deployment.
* **Bag of Words Docker Image** — `bagofwords/bagofwords`.
* **BOW_ENCRYPTION_KEY** — Required for production configuration.
* **LLM Provider** — Required when configuring AI agents. BOW supports OpenAI, Azure OpenAI, Gemini, Anthropic, AWS Bedrock, and OpenAI-compatible APIs.
* **External Data Sources** — Optional; examples include PostgreSQL, Snowflake, BigQuery, Databricks, MySQL, SQL Server, MongoDB, S3, Salesforce, Power BI, Tableau, and others.
* **MCP/API Integrations** — Optional.
* **SMTP / OAuth / OIDC / LDAP** — Optional integrations.

### Deployment Dependencies

* [Bag of Words Documentation](https://docs.bagofwords.com/)
* [Bag of Words Installation Guide](https://docs.bagofwords.com/install)
* [Bag of Words Caching Documentation](https://docs.bagofwords.com/bow-fast/overview)
* [Railway Documentation](https://docs.railway.com)
* [Railway PostgreSQL](https://docs.railway.com/databases/postgresql)

### Implementation Details

## Docker

Deploy the published image:

```docker
bagofwords/bagofwords
```

The documented Docker deployment uses port `3000`:

```bash
docker run -p 3000:3000 bagofwords/bagofwords
```

When deployed as a Docker image, Railway uses the image's existing startup configuration. No Dockerfile, custom build command, Docker Compose service, or Kubernetes configuration is required.

## Public Networking

| Setting       | Value                                     |
| ------------- | ----------------------------------------- |
| Proxy Type    | HTTP Proxy                                |
| Target Port   | `3000`                                    |
| Protocol      | HTTP                                      |
| Public Access | Railway Generated Domain or Custom Domain |
| HTTPS         | Railway-managed                           |

To expose BOW, open the service and select **Settings → Networking → Generate Domain**.

A separate Caddy or Nginx service is not required because Railway provides the public networking and TLS layer.

The supplied documentation specifies port `3000`. If the image requires an explicit Railway port variable, use:

```env
PORT=3000
```

## Environment Variables

### Required

| Variable             | Required    | Description                                         |
| -------------------- | ----------- | --------------------------------------------------- |
| `BOW_DATABASE_URL`   | Yes         | PostgreSQL connection URL.                          |
| `BOW_ENCRYPTION_KEY` | Yes         | Production encryption key.                          |
| `PORT`               | Recommended | Application port; documented Docker port is `3000`. |

Use Railway's PostgreSQL reference:

```env
BOW_DATABASE_URL=${{Postgres.DATABASE_URL}}
BOW_ENCRYPTION_KEY=
PORT=3000
```

The PostgreSQL service must be named `Postgres`, or the reference must be changed to match its actual Railway service name.

Generate the encryption key with:

```bash
openssl rand -base64 32 | tr '+/' '-_'
```

Never use `localhost` for the PostgreSQL connection on Railway.

### Optional Configuration

BOW supports optional integrations including Google OAuth, SMTP, OIDC, LDAP, LLM providers, MCP servers, and external data sources.

For example, the documented Resend SMTP configuration uses:

```env
BOW_SMTP_HOST=smtp.resend.com
BOW_SMTP_PORT=587
BOW_SMTP_USERNAME=resend
BOW_SMTP_PASSWORD=
BOW_SMTP_FROM_NAME=Bag of words
BOW_SMTP_FROM_EMAIL=
BOW_SMTP_USE_TLS=true
BOW_SMTP_USE_SSL=false
BOW_SMTP_USE_CREDENTIALS=true
BOW_SMTP_VALIDATE_CERTS=true
```

Only configure optional variables for features you use. Provider-specific variable names not documented in the supplied material should not be invented.

## Persistent Storage

No separate Railway Volume is required for the recommended deployment.

BOW supports SQLite by default, but the Railway architecture uses PostgreSQL:

```env
BOW_DATABASE_URL=${{Postgres.DATABASE_URL}}
```

This keeps persistent application data in Railway PostgreSQL rather than inside the application container.

Do not attach an arbitrary application volume unless BOW documentation identifies a filesystem path that requires persistence.

## Database

PostgreSQL is the persistent database dependency.

Create:

**New → Database → PostgreSQL**

Name the service:

```text
Postgres
```

Then configure BOW:

```env
BOW_DATABASE_URL=${{Postgres.DATABASE_URL}}
```

The architecture is:

```text
Internet
   │
   ▼
Railway Domain
   │
   ▼
Bag of Words :3000
   │
   │ Private Network
   ▼
Railway PostgreSQL
```

PostgreSQL should remain private to the Railway project. BOW does not need a public database endpoint.

## Build &amp; Start

No custom build or start commands are required when deploying:

```text
bagofwords/bagofwords
```

Railway uses the Docker image's default `ENTRYPOINT` and `CMD`.

Do not use `docker run`, `docker compose up`, or Kubernetes commands as Railway start commands.

## Accessing the Application

After deployment:

1. Open the Bag of Words service.
2. Go to **Settings → Networking**.
3. Select **Generate Domain**.
4. Open the generated HTTPS URL.

A custom domain can also be configured through Railway Networking.

For Google OAuth, use the final Railway domain in the callback URL:

```text
https://YOUR_RAILWAY_DOMAIN/api/auth/google/callback
```

After accessing BOW, configure the required LLM providers, data connections, agents, tools, permissions, and integrations.

BOW supports agents across the web application, MCP clients, Excel, Teams, Slack, WhatsApp, email, webhooks, APIs, and scheduled tasks.

### Health Checks

The supplied documentation confirms port `3000` but does not document a dedicated health endpoint. Do not invent `/health` or `/api/health`.

Configure a Railway healthcheck only after verifying a BOW endpoint that reliably returns HTTP `200`.

### Security

BOW supports RBAC, approvals, audit logs, service accounts, SSO, model policies, and row-level security support.

Telemetry can be disabled in `bow-config.yaml`:

```yaml
telemetry:
  enabled: false
```

Intercom can also be disabled:

```yaml
intercom:
  enabled: false
```

Keep encryption keys, database credentials, API keys, OAuth secrets, and SMTP credentials in Railway Variables rather than committing them to source control.

### Troubleshooting

**Database connection fails**

Verify:

```env
BOW_DATABASE_URL=${{Postgres.DATABASE_URL}}
```

and ensure the service name matches the PostgreSQL service.

**Application is inaccessible**

Verify that BOW is listening on port `3000` and that Railway Networking targets port `3000`.

**OAuth fails**

Verify the OAuth callback uses the exact HTTPS Railway or custom domain:

```text
https://YOUR_RAILWAY_DOMAIN/api/auth/google/callback
```

**Email fails**

Verify SMTP credentials, port, TLS configuration, and sender address.

**External data connection fails**

Check the connector credentials and network accessibility of the external database, warehouse, API, or business application.

**Do not deploy Caddy**

Railway's public networking replaces the reverse-proxy layer used by traditional server deployments.

**Do not use Kubernetes**

Kubernetes-specific services, ingress resources, Helm configuration, and cluster infrastructure are not required for this Railway deployment.

## Why Deploy Bag of Words on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Bag of Words on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.


## Similar templates

- [Matomo Analytics + MariaDB](https://railway.com/deploy/matomo-analytics-mariadb) — Privacy-friendly analytics with MariaDB and persistent volumes.
- [Bugsink](https://railway.com/deploy/bugsink) — Self-hosted Error Tracking. Sentry-SDK compatible
- [SubTrackr](https://railway.com/deploy/bscottsubtrackr) — Self-hosted Subscription Tracker

Open this page in a browser: https://railway.com/deploy/bagofwords
