# Installing Community Edition

> A step-by-step guide to the free edition of Buff on your own machine: one-command install, first sign-in, licence, connector, updates.

Community Edition is a free edition for internal use by one organisation: one organisation, three users, up to 15 concurrent developments, one model per installation. How it differs from SaaS and Enterprise is on the [Editions](/en/docs/self-hosted) page. The installation repository is [github.com/buffsystems/buff-community](https://github.com/buffsystems/buff-community); a copy of this guide lives in it as `docs/install.md`.

## What you need

| | Requirement |
|---|---|
| Linux | **Ubuntu 22.04 or 24.04**, amd64, kernel 5.7 or later, a user with `sudo`, `git` installed. Runners work in [Sysbox](https://github.com/nestybox/sysbox) — without privileged containers and without the host socket |
| macOS, Windows | [Docker Desktop](https://docs.docker.com/desktop/); on Windows the script is run from Git Bash. There is no Sysbox here, so **the Buff container runs privileged** — for a personal machine, not for a server |
| Resources | at least 4 CPUs and 8 GB of memory (one development at a time); 8 CPUs and 16 GB are recommended for three concurrent ones — each development takes up to 1.5 GB. About 12 GB of disk for the images (the stock ones, ours and the sandbox built on site) plus room for your repositories: the data lives in Docker volumes, not in the image |
| Access | outbound internet: images from ghcr.io (ours included) and Docker Hub, the daily licence check with buff.systems, your model endpoint |
| Model | a key to an OpenAI-compatible endpoint: [OpenRouter](https://openrouter.ai), your own LiteLLM, vLLM, Ollama and so on |

<Callout type="warn">
On Linux, make sure the whole disk is given to the root partition or mounted under `/var/lib/docker` — a server image with an 8 GB root will not do. On Apple Silicon the (amd64) image runs under emulation and is noticeably slower.
</Callout>

## One-command installation

Run it as a regular user with `sudo` — root is not needed:

```sh
git clone https://github.com/buffsystems/buff-community.git
cd buff-community
./install.sh
```

The script asks five questions (Enter keeps the default; everything can be changed later in `.env`):

```
настройки установки (Enter — оставить как есть, поправить можно потом в .env)
имя вашей организации латиницей [company]: acme
почта администратора [admin@37.18.90.39]: you@example.com
адрес OpenAI-совместимого эндпоинта модели [https://openrouter.ai/api/v1]:
ключ эндпоинта (ввод скрыт):
модель, например openai/gpt-4.1 []: openai/gpt-4.1
пароли записаны в …/buff-community/.env (пароль администратора — ADMIN_PASSWORD)
```

The same values can be passed as environment variables, without the dialogue: `ORG=acme LLM_API_KEY=… ./install.sh`.

Then the script, on its own:

1. detects the mode — Linux (installs Docker and Sysbox) or Docker Desktop (adds `docker-compose.desktop.yml`);
2. creates `.env` from `.env.example` with random passwords;
3. downloads the edition image `ghcr.io/buffsystems/buff-community` and verifies it;
4. builds the agent sandbox image `buff-community-sandbox` on top of the stock Windmill image and hands it to the inner docker;
5. brings up `docker compose` and shows the progress of the first start right in the terminal — `[bootstrap]` lines up to **готово** (“done”; a few minutes: databases, accounts, deploying the pipeline).

Running `./install.sh` again on a working installation is safe: it only updates what has changed.

## Settings in `.env`

The `.env` file sits next to `docker-compose.yml`, with permissions `600`. What is worth checking in it:

| Variable | What it is |
|---|---|
| `ORG` | your organisation’s name in Latin letters, for example `acme` |
| `ADMIN_USER`, `ADMIN_EMAIL`, `ADMIN_PASSWORD` | the app’s first user, who is also the administrator; the password is generated and can be replaced |
| `LLM_BASE_URL`, `LLM_API_KEY`, `LLM_MODEL` | the endpoint, key and model, for example `https://openrouter.ai/api/v1`, `sk-or-…`, `openai/gpt-4.1` |
| `APP_URL` | the address at which people will open the app; by default the machine’s IP and port 8138 |
| `APP_PORT`, `ADMIN_PORT`, `BIND_IP` | the ports of the app (8138) and the admin panel (8150), the interface they listen on |
| `RUNNERS` | how many development workers to start — that many developments run at once, 3 by default. A value above the licence limit has no effect: the limit is signed into the licence and shown in the admin panel → “Licence” (Community — 15) |
| `BUFF_IMAGE`, `SANDBOX_IMAGE`, `WINDMILL_IMAGE` | image versions; they change on update from `.env.example` |

Changed `.env`? Apply it: `docker compose up -d`.

## First sign-in

**The app** — `APP_URL` (`http://<machine>:8138/app/`). The login is `ADMIN_USER`, the password is `ADMIN_PASSWORD` from `.env`.

![Signing in to the app](/docs/community/ce-login.png)

After signing in you are in your organisation, in its first space. On the left are the sections: “Ask”, “Deep research”, “Connectors”, “Development sessions”, “Knowledge base”. You can ask your first question as soon as the licence is in place (see below).

![The organisation’s space: “Ask”](/docs/community/ce-org.png)

**The admin panel** — `http://<machine>:8150`, user `admin`, the same password. Sections: users, projects, repositories, connectors, workers, pipeline, configuration, usage, licence.

## Licence

The installation runs under the Community licence: perpetual, with [terms](/en/docs/self-hosted/license) of internal use by one organisation. While there is no licence, and also if it has been revoked, **new tasks, runs, research and questions do not start**; sign-in and reading work.

1. In the admin panel open “Licence”, enter the organisation name and the administrator’s email, tick the box consenting to the processing of this data and press “Register”.
2. The installation contacts buff.systems on its own and receives the licence — usually within a minute, no longer than an hour. The status changes to “active”.

![Licence received: the limits and the date of the last check](/docs/community/ce-admin-license.png)

The limits — users, concurrent developments, organisations — are signed into the licence and shown on the same page; installation settings above them have no effect. Once a day the installation checks the licence and sends four fields: the installation identifier, the version, the number of users and the number of runners. Nothing else; on the buff.systems side the address the check came from is recorded — more in the [licence terms](/en/docs/self-hosted/license). Losing the connection to buff.systems does not end the licence. For an environment without internet there is a “Licence file” field — see [Air-gapped environment](#air-gapped-environment).

## Users

There is no self-registration: the administrator creates people in the admin panel → “Users” → “Create”. The counter on the right shows how many licence seats are taken. Accounts marked “bot” are the pipeline’s service agents (analyst, developer, reviewer); they do not count towards the limit. All members see everything in the organisation.

![Admin panel: users](/docs/community/ce-admin-users.png)

## Repositories: the central connector

In Community there is one connector, and it is built into the installation: the **“Central connector”** runs inside the container and pairs itself with your organisation on first start — it shows up in “Connectors” in the app within a minute or two, and no others can be added. Its settings are the `connector/connector.yaml` file next to `docker-compose.yml`: it lists the git providers (GitLab, GitHub, Gitea, Bitbucket, self-hosted ones included) and the tokens for them; the format is described in the comments of the file itself. The tokens stay in this file on your machine.

Changed the file? Restart the connector:

```sh
docker compose exec buff supervisorctl restart services:connector
```

After that, connect a repository in the app: the project appears in the organisation’s section with its tasks, audits and development settings.

![A project with a connected repository: tasks and their stages](/docs/community/dev.png)

The connector sees the network the same way the container does: it needs network access from this machine to your git server. A proxy for external models is not configured here but in your LiteLLM.

## First work: a question, a research, a task

- **Ask** — a question about the organisation’s documents and code; an answer with sources, read-only. The quickest way to check that the model responds.
- **Deep research** — the analyst and the reviewer prepare a document (Markdown and PDF) from your sources; it takes from ten minutes to an hour depending on the model.
- **Task** — describe a task in a project: the analyst clarifies it with questions, after your “approve” the developer implements it in a sandbox, the reviewer checks it, and the output is a branch and a merge request in your repository. For engineers there is also [Buff Code](/en/docs/buff-code) in the terminal.

![“Ask”: an answer with sources](/docs/community/ask.png)

## Mobile app

Employees connect a phone to the installation: in the cabinet, “Settings → Phone” — a QR code or
a link and a code. From the phone you can see tasks, review, “Ask”, research, the knowledge base, audits and
repositories, and notifications arrive even when the app is closed. An employee’s Buff Code
connects to the phone separately, from their own machine — [Connecting to Buff Code](/en/docs/mobile/pair-buff-code);
the installation’s policy applies to it too if it is signed in to the installation. The phone and the installation meet at the
buff.systems gateway and encrypt everything end to end — the gateway does not see the content, and the installation
does not need to open any ports to the outside; it only needs outbound access to buff.systems. Who may
connect phones and whether push notifications are sent is set by the administrator in the admin panel, in the
“Mobile app” section.

The app is on the [mobile app page](/en/mobile); connecting step by step —
[Connecting to the cabinet](/en/docs/mobile/pair-cabinet). An APK for Android without a store is in the releases of
[buff-community on GitHub](https://github.com/buffsystems/buff-community/releases) — the file
`buff-<version>.apk`, with its `.sha256` checksum next to it.

## Docker Desktop (macOS, Windows)

On macOS and Windows `install.sh` switches to Docker Desktop mode by itself (on Linux it can be forced: `BUFF_MODE=desktop ./install.sh`). In this mode the line `COMPOSE_FILE=docker-compose.yml:docker-compose.desktop.yml` is uncommented in `.env`: Sysbox is unavailable, and the Buff container starts privileged with the `runc` runtime. This is fine for a personal machine and not for a server. On Windows, run the script from Git Bash; Docker Desktop must be started beforehand.

## Air-gapped environment

If the machine has no access to the internet:

- put the edition image file and its `.sha256` into `images/` — `install.sh` loads it instead of downloading; the same for the sandbox: `images/buff-community-sandbox.tar.zst`;
- carry the stock images (PostgreSQL, Gitea, NATS, Windmill, Tika) over with your own registry or `docker save`/`docker load`;
- get the licence on buff.systems for the `instance_id` shown in the admin panel and paste it into the “Licence file” field.

## Updating

```sh
git pull
./install.sh
```

Put the new `BUFF_IMAGE` and `SANDBOX_IMAGE` from the updated `.env.example` into `.env` — the script downloads the image, rebuilds the sandbox and restarts the containers. Database migrations are applied at start. The installation’s version is shown in the admin panel.

## Backup

All data is in Docker volumes: `pgdata` (databases), `gitea-data` (repositories), `buff-data` (secrets, keys, working directories), `buff-docker` (the inner docker’s layers). To make a copy: stop the stack (`docker compose stop`), copy the volumes in whatever way you are used to, start it again. Keep the `.env` file together with the copy — it holds the passwords.

## Troubleshooting

- `docker compose ps` — container state; `docker compose logs buff` — our container.
- `docker compose exec buff supervisorctl status` — the services inside the container; `supervisorctl restart services:auth-worker` restarts one of them.
- Repeating the first start is safe: `docker compose exec buff buff-bootstrap` — all steps are idempotent.
- Runners do not start — check that the sandbox image exists in the inner docker: `docker compose exec buff /opt/docker-real/docker images`.
- Removing the installation completely: `docker compose down -v` (the data volumes are deleted) and `sudo rm -rf` of the kit directory — `connector/state` is written by the container as root.
- Questions and bugs go to the [repository’s issues](https://github.com/buffsystems/buff-community/issues); how to file them and how to contribute is in `CONTRIBUTING.md`. Technical support for Community Edition is not provided.

## What is inside

`docker compose` brings up the stock images of PostgreSQL, Gitea (the internal git storage, invisible to the user), NATS, Windmill (the server and workers — the number of workers is set by `RUNNERS`) and Apache Tika next to our single `buff-community` image (~1.4 GB), in which all Buff services and the inner docker live under a supervisor. On Linux our image is a Sysbox system container with its own docker inside: the runners and agent sandboxes work in it, without `privileged` and without the host socket; in Docker Desktop the same container runs privileged. Windmill workers start sandboxes through the socket of this inner docker on a shared volume.

The agent sandbox is a separate image, `buff-community-sandbox`: `install.sh` builds it on your machine on top of the same stock Windmill image (all language runtimes — parity with SaaS), adding docker, the Buff engine and MCP servers, and hands it to the inner docker without a second download. Windmill is pulled from ghcr.io under its authors’ terms and is not part of any of our images; the other third-party components are listed in the repository’s `THIRD-PARTY.md`.
