---
title: "Deploy Campfire"
description: "Group chat for teams, with rooms, direct messages and file sharing"
category: "Other"
url: https://railway.com/deploy/campfire-chat
---

# Deploy Campfire

Group chat for teams, with rooms, direct messages and file sharing

**[Deploy Campfire on Railway](https://railway.com/template/campfire-chat)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/campfire-chat/manifest.json

- **Creator:** A3A
- **Category:** Other
- **Total deploys:** 1

## Template content

### campfire https://cdn.jsdelivr.net/gh/basecamp/once-campfire@977cbcd135783e09d631301bc39cbb4e7961ec4e/app/assets/images/logos/app-icon-192.png

- **Source:** https://github.com/gridalpha/campfire-railway
- **Health check:** /up
- **Public domain:** Yes

## Documentation

# Deploy and Host Campfire on Railway

Campfire is 37signals' group chat app — the chat product that grew up inside Basecamp, released as open source under the MIT licence. Deploy Campfire when you want Slack-shaped team chat without per-seat billing, without a history cap, and without your conversations on someone else's infrastructure. It has open and closed rooms, direct messages, attachments with previews, full-text search, @mentions, push notifications, and a bot API.

Self-host Campfire on Railway and its small footprint becomes the advantage. This template runs one service, **campfire**, built from [gridalpha/campfire-railway](https://github.com/gridalpha/campfire-railway), which wraps the official `ghcr.io/basecamp/once-campfire:latest` image. Inside it a supervisor runs Thruster (an HTTP proxy with asset caching) in front of Puma, a Resque worker pool, and a loopback Redis backing the queue, the cache and the live-updating chat channels. Railway's edge terminates TLS and forwards to Thruster on port 8080. All state — the SQLite database, uploaded files and the signing keys — lives on a volume at `/rails/storage`.

![Campfire service and its storage volume on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789539647/campfire-architecture.webp)

## Getting Started with Campfire on Railway

Deploy the template and open the generated `*.up.railway.app` URL. There is no setup wizard to race and no default password: the container completes Campfire's first-run step while it boots, from `CAMPFIRE_ADMIN_EMAIL` and `CAMPFIRE_ADMIN_PASSWORD`, so the first page is the sign-in form. Read the generated password from the service's Variables tab, sign in, and you land in the "All Talk" room created with your account. Send a message — if it appears instantly, the web tier, Redis and the live-update channel all work. Drop a file on the composer to confirm attachments reach the volume; images render inline. Use **+** in the sidebar to add a room, and the search icon to check the full-text index. To invite your team, copy the join link from Account Settings (the gear, bottom-right): it carries a secret code and is the only route to an account, so rotate it there if it leaks. Change your password under My Settings, and point `CAMPFIRE_ADMIN_EMAIL` at a real address — the sign-in page shows it as the contact for anyone locked out.

![Campfire chat room with a conversation and an attached chart](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789539649/campfire-all-talk-room.webp)
![Campfire full-text search showing two matching messages](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789539651/campfire-search-results.webp)
![Campfire account settings with the admin user and invite link](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789539652/campfire-account-settings.webp)

## About Hosting Campfire

Campfire is single-tenant chat for one organisation. Open rooms are visible to every member, closed rooms are invite-only, and direct messages ("Pings") stay private. Teams self-host it to stop paying per seat, to keep history under their own retention policy, or because a contract requires chat data on infrastructure they control.

- Open, closed and direct rooms with per-room membership
- Attachments with image and video previews, via libvips and ffmpeg
- Full-text search across every message you can reach
- @mentions with browser push notifications over the Web Push standard
- A bot API — each bot gets a key and posts to rooms over HTTP
- Custom styles, a custom logo, and an installable web app

One Railway service is upstream's design, not a simplification: the web tier and the workers share the same SQLite file and attachments directory, so they share one container and one volume, with Redis beside them on loopback.

## Why Deploy Campfire on Railway

Railway removes the administration self-hosted chat usually needs:

- One-click deploy with TLS, a public domain and health checks configured
- A persistent volume for the database and uploads, mounted for you
- No reverse proxy, certificates or firewall rules to maintain
- Push to the source repository and Railway rebuilds automatically
- Logs and resource metrics beside the deployment

## Common Use Cases

- **Internal team chat replacing a paid Slack or Teams plan**, with unlimited searchable history instead of a 90-day window.
- **A private community or client channel**, where the join link is handed out deliberately and there is no sign-up page.
- **An alerting room for your services**, using the bot API to post deploy notifications or on-call handoffs.

## Dependencies for Campfire

- **campfire** — `ghcr.io/basecamp/once-campfire:latest`, built through [gridalpha/campfire-railway](https://github.com/gridalpha/campfire-railway). Serves the app on port 8080 and runs the workers and Redis beside it.
- **Volume at `/rails/storage`** — the SQLite database, uploaded files and signing keys. Back it up and you have backed up the installation.

No database, queue or object-storage service is needed: SQLite is the database, the in-container Redis is the queue, and Active Storage writes straight to the volume.

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `PORT` | Port Thruster listens on; leave at `8080`. |
| `SECRET_KEY_BASE` | Signs session cookies. Changing it signs everyone out. |
| `CAMPFIRE_ADMIN_EMAIL` | Seeds the first admin; shown on the sign-in page. Blank means `admin@`. |
| `CAMPFIRE_ADMIN_PASSWORD` | Password for that admin. Generated at deploy; change it in the app. |
| `CAMPFIRE_ADMIN_NAME` | Display name for that admin. |
| `WEB_CONCURRENCY` | Puma workers. Derived from the CPU quota when unset. |
| `JOB_CONCURRENCY` | Resque workers. Also derived when unset. |
| `VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY` | Web Push key pair, generated once and kept on the volume. Set only when migrating. |
| `RAILS_LOG_LEVEL` | `info`; use `debug` to troubleshoot. |
| `SKIP_TELEMETRY` | `true` disables Sentry reporting. |

Leave `TLS_DOMAIN` and `DISABLE_SSL` unset. Railway's edge already terminates TLS, and an empty `DISABLE_SSL` tells Rails to treat requests as secure — which puts the `Secure` flag on the session cookie and sends HSTS.

### Deployment Dependencies

- Source repository: 
- Upstream and self-hosting guide: 
- Runtime: Ruby 3.4, Rails 8, Puma, Thruster, Resque, Redis, SQLite

## Hardware Requirements for Self-Hosting Campfire

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2 GB |
| Storage | 5 GB volume | 10 GB+ for heavy file sharing |
| Runtime | Ruby 3.4 Linux container | Same, plus snapshots |

Campfire is frugal: a team of twenty runs comfortably in 1 GB, and what grows is storage, since every attachment stays on the volume. Worker counts follow the CPU quota, so raising the plan raises concurrency with no config change.

## Self-Hosting Campfire with Docker

The published image is self-contained: web app, workers, cache and file serving in one container. A minimal run needs a volume and a session key.

```
docker run -d --name campfire \
  -p 80:80 \
  -e SECRET_KEY_BASE=$(openssl rand -hex 64) \
  -e DISABLE_SSL=true \
  -v campfire:/rails/storage \
  ghcr.io/basecamp/once-campfire:latest
```

Web Push needs a VAPID key pair, which the image generates. Run this once and keep the output — reusing the same pair keeps existing push subscriptions valid.

```
docker run --rm ghcr.io/basecamp/once-campfire:latest \
  script/admin/generate-secrets
```

To build from source, clone the upstream repository and run `docker build -t campfire .`. For backups run `script/admin/prepare-backup` in the container, then archive `/rails/storage`.

## How Much Does Campfire Cost to Self-Host?

Campfire is free and open source under the MIT licence — no seat limits, no paid tier, no licence key. 37signals sells a managed installer, but the application itself is free. On Railway you pay only for compute, memory and volume storage: a few dollars a month for a small team, however many people you add.

## FAQ

**What is Campfire?**
Campfire is 37signals' group chat application, open-sourced under the MIT licence: rooms, direct messages, file sharing, search, @mentions and a bot API, in a compact Rails app built for a single machine.

**What does this Railway template deploy?**
One service, `campfire`, running the official `ghcr.io/basecamp/once-campfire` image with a volume at `/rails/storage`, a public domain and a health check on `/up`. The admin account is created during first boot, so nothing is unclaimed on a public URL.

**Why does Campfire need a volume instead of a database service?**
It keeps everything in SQLite plus a directory of uploaded files under `/rails/storage`, and a volume gives that directory persistence across deploys. There is no Postgres or MySQL option — SQLite is the only database it supports.

**How do people sign up for my self-hosted Campfire?**
They do not sign up; they are invited. The account has one join link containing a secret code, under Account Settings. Anyone with it can create an account, and regenerating the link invalidates the old one.

**Do browser push notifications work on a self-hosted instance?**
Yes. The container generates a VAPID key pair on first boot and keeps it on the volume, so notifications work immediately and survive redeploys. Set the VAPID variables only when migrating.

**How do I post messages into a room from CI or a script?**
Create a bot in Account Settings and copy its key. Each bot gets a room-scoped URL of the form `/rooms///messages`; POST a body there and the message appears in that room.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/campfire-chat
