# Self-hosting Nothing Left

> Run the tracker and its agent interface on your infrastructure. The software is open source under AGPL-3.0 and uses the same build as the hosted service.

The repository's Docker Compose file runs the whole system on one machine: the web app, the API with MCP, PostgreSQL, Redis and S3-compatible storage. You build the images from source. [Self-hosting with Docker Compose](https://nothingleft.dev/docs/self-hosting.md) covers a trial, a server with HTTPS, upgrades and backups; [Deploying on AWS](https://nothingleft.dev/docs/self-hosting-aws.md) covers ECS Fargate, RDS, ElastiCache, S3 and SES.

## Architecture

### Web app

Next.js build

The interface people use. The browser calls the API directly, so the build needs one setting: NEXT_PUBLIC_API_BASE_URL, matching the API’s API_BASE_URL, inlined at build time.

### API

Fastify on Bun, one process

The only backend process. It must be long-running, not serverless: the job queue holds a Postgres connection and runs scheduled work in-process.

MCP is part of the same process. Its tools call the REST API over loopback, so an agent passes the same permissions and rules as a person. Configuration is validated at boot, and the process refuses to start on a bad one.

### PostgreSQL

Standard wire protocol

Every record, and the background job queue. Two connection strings: DATABASE_URL (direct) for migrations and jobs, DATABASE_URL_POOLED for application queries.

Two roles: the owner migrates, and nothingleft_app runs every query. The audit log is append-only for that role, so it must not own tables or be a superuser.

### Redis

Any Redis 6 or later

Session cache, rate-limit counters, report caches and idempotency replays. It is not the job queue. Outside localhost and the Compose stack, REDIS_URL must use TLS (rediss://).

### Object storage

Any S3-compatible store, two buckets

The private bucket has no public access: the API checks each request and redirects to a short-lived presigned URL. The public bucket holds avatars and nothing else.

File bytes never pass through the API. Browsers upload and download directly with presigned URLs; the API only authorises.

## Configurable limits

- `FREE_SEAT_LIMIT` (default: 20 members): Where the seat notice starts. Members beyond it are still allowed: the invite dialog and a banner for admins say so, and nothing is blocked.
- `FREE_STORAGE_BYTES` (default: 5368709120 bytes, 5 GB): The storage cap for attachments. Warnings at 80% and 95%; at 100% new uploads are refused until there is room. Avatars never count.

## Operating responsibilities

### Running the services

Hosted: We run the web app, the API with /mcp, the database, Redis and the buckets.

Self-hosted: You run the web app, the API, PostgreSQL, Redis and an S3-compatible store. Docker Compose starts all of them on one machine.

### Upgrades

Hosted: We deploy them. Migrations run before a new API version takes traffic.

Self-hosted: You pull the new source, rebuild and restart. Migrations run before the new API starts; each guide has the steps.

### Backups

Hosted: Ours, for the hosted database and platform storage. A bucket you connect is yours.

Self-hosted: Yours: PostgreSQL and both buckets, plus the encryption key. Each guide says what to keep and how.

### Email

Hosted: Account, security, invitation and storage email is sent for you.

Self-hosted: You pick a mail provider (Resend, Zoho CPaaS or any SMTP server), supply its credentials and set EMAIL_FROM. In production the API does not start without them; a trial on your laptop catches mail in Mailpit.

### File storage

Hosted: 5 GB per organisation on the free plan, or connect your own R2 or S3 bucket.

Self-hosted: Your own store and two buckets. FREE_STORAGE_BYTES sets the cap.

### Google and GitHub sign-in

Hosted: Ready to use.

Self-hosted: Register your own OAuth apps. Until you do, those buttons answer that the provider is not switched on.

### Agent endpoint

Hosted: https://api.nothingleft.dev/mcp

Self-hosted: /mcp on your own API address.

## Questions before self-hosting

### What does the AGPL-3.0 licence ask of us?

You may run, study, change and share the code. If you modify it and let people use your version over a network, the licence asks you to offer those users its source. The licence text is the authority, not this summary.

[Read the licence](https://github.com/nothingleft-dev/nothingleft/blob/main/LICENSE)

### Where does our data live?

Self-hosted: in your PostgreSQL database and your two buckets, wherever you run them. Product analytics and error capture are separate switches, and with both off nothing is sent.

On the hosted service, issues, comments and accounts are in our database. Attachments can live in your own R2 bucket (with an EU or FedRAMP jurisdiction) or S3 bucket in your region; avatars stay with us.

### Is the self-hosted build different from the hosted one?

No. It is the same codebase and the same build. Plans are limit presets, not feature gates, so there is no reduced community edition and nothing to unlock.

### Does docker-compose.yml run the whole app?

Yes. Its app profile builds the web app and the API from source and starts them with PostgreSQL 16, Redis 7, RustFS for S3-compatible storage and Mailpit to catch email on a trial. Migrations run before the API starts. On a server, the proxy profile adds Caddy for HTTPS.

Settings live in one file, infra/docker/.env. The guide covers a trial on your laptop, a server, upgrades and backups.

[Self-hosting with Docker Compose](https://nothingleft.dev/docs/self-hosting.md)

### Can we run it on AWS?

Yes. The web app and the API run as containers on ECS Fargate, with RDS for PostgreSQL, ElastiCache for Valkey, two S3 buckets and SES for mail. A load balancer is the only way in; everything else sits in private subnets.

[Deploying on AWS](https://nothingleft.dev/docs/self-hosting-aws.md)

### Can we turn off sign-up?

No. Anyone who can open the web app can create an account and their own organisation, and there is no setting that turns this off. To keep an install to your team, put it where only your team can reach it: a private network, a VPN or a firewall rule.

### Can our agents connect to a self-hosted install?

Yes. MCP is served by the API at /mcp, so an HTTP client points at your own address with a personal access token. The local stdio shim reads the address from NOTHINGLEFT_MCP_URL.

[MCP setup guide](https://nothingleft.dev/docs/mcp.md)

### Is connecting our own bucket the same as self-hosting?

No. Your own R2 or S3 bucket is a storage option on the hosted service: attachments move into your account and the storage limit lifts, while the app and its database stay with us. Self-hosting means running all of it yourself.

[Storage manual](https://nothingleft.dev/docs/storage.md)

## Source and guides

- [Source repository](https://github.com/nothingleft-dev/nothingleft)
- [AGPL-3.0 licence](https://github.com/nothingleft-dev/nothingleft/blob/main/LICENSE): The licence text is authoritative.
- [Self-hosting with Docker Compose](https://nothingleft.dev/docs/self-hosting.md)
- [Deploying on AWS](https://nothingleft.dev/docs/self-hosting-aws.md)
- [Storage manual](https://nothingleft.dev/docs/storage.md)
- [Connecting an AI agent](https://nothingleft.dev/docs/mcp.md)

---

[Read the web page](https://nothingleft.dev/solutions/self-hosting)
