# How to install Plausible Community Edition with Docker Compose

> Self-host Plausible Analytics Community Edition with Docker Compose, PostgreSQL and ClickHouse behind Caddy HTTPS, set up email, back up both databases.

Difficulty: Intermediate\
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

Plausible Analytics is a lightweight, privacy-focused web analytics tool with a single-page dashboard for visitors, pages, sources, locations, devices, goals and custom events. **Plausible Community Edition (CE)** is its self-hosted version: it runs as three containers, the Plausible app, PostgreSQL for accounts and settings, and ClickHouse for the event data. Plausible CE is open source.

This guide follows Plausible's official [community-edition](https://github.com/plausible/community-edition) repository and wiki. You clone the current release, create the `.env` file with `BASE_URL` and `SECRET_KEY_BASE`, publish Plausible on `127.0.0.1:8000` with a Compose override file, and serve it over HTTPS with Caddy. You then create the first account, keep registration invite-only, connect an SMTP relay and learn how to back up, restore and upgrade both databases.

> **Note**
>
> Plausible CE can also terminate TLS itself: with `HTTP_PORT=80` and `HTTPS_PORT=443` in `.env` and ports `80:80` and `443:443` in `compose.override.yml`, it requests Let's Encrypt certificates on its own. That works only if nothing else on the server uses ports 80 and 443, so this guide uses the reverse proxy setup from Plausible's wiki instead.

## Prerequisites

- A server running **Ubuntu 24.04 LTS**, **Ubuntu 26.04 LTS**, **Debian 12** or **Debian 13**.
- A non-root user with `sudo` rights. See [Secure a new Linux server](/guides/secure-a-new-linux-server) and [Set up SSH keys](/guides/ssh-keys).
- Docker Engine with the Compose plugin: [Install Docker on Ubuntu](/guides/install-docker-ubuntu) or [Install Docker on Debian](/guides/install-docker-debian). You also need `git`.
- Caddy installed on the host as described in [Caddy as a reverse proxy](/guides/caddy-reverse-proxy).
- A domain name such as `plausible.example.com` with an A record (and AAAA record if you use IPv6) pointing at your server.

Plausible's README lists two hardware requirements; the project does not publish a disk figure, so that value is a conservative starting point, not an official or benchmarked number:

| Resource | Minimum (official) | Suggested starting point |
|---|---|---|
| CPU | x86-64 with SSE 4.2, or ARM with NEON (required by ClickHouse) | 2 vCPU |
| Memory | At least 2 GB RAM recommended | 2 GB RAM, 4 GB for busier sites |
| Disk | Not published | 20 GB; ClickHouse data grows with every tracked event |

## Step 1 — Check the CPU and install git

ClickHouse does not start on a CPU without SSE 4.2 (x86-64) or NEON (ARM). Check the flags your server reports:

```bash
grep -m1 -o -w sse4_2 /proc/cpuinfo || echo "sse4_2 not reported"
uname -m
sudo apt update
sudo apt install git
```

On an `x86_64` server the first command should print `sse4_2`. On an `aarch64` server, check for `asimd` instead with `grep -m1 -o -w asimd /proc/cpuinfo`; this is how Linux reports NEON.

## Step 2 — Clone the current release

The community-edition repository has one branch per release. At the time of writing the current release is **v3.2.1**; check the [Plausible releases](https://github.com/plausible/analytics/releases) for a newer one and use its name in the commands below:

```bash
sudo mkdir -p /opt/plausible-ce && sudo chown $USER:$USER /opt/plausible-ce
git clone -b v3.2.1 --single-branch https://github.com/plausible/community-edition /opt/plausible-ce
cd /opt/plausible-ce
ls
```

You should see `compose.yml`, a `clickhouse` folder with ClickHouse configuration files, and the README. `compose.yml` pins the matching image, here `ghcr.io/plausible/community-edition:v3.2.1`, together with `postgres:16-alpine` and a ClickHouse server image. Do not edit `compose.yml`; put your changes in `.env` and `compose.override.yml`, so that later upgrades with `git pull` stay clean.

## Step 3 — Create the .env file

Create `.env`, restrict it to your user, and add the two required values. `BASE_URL` is the public address of your instance, and `SECRET_KEY_BASE` is a secret of at least 64 bytes, generated with the command from Plausible's documentation:

```bash
cd /opt/plausible-ce
touch .env
chmod 600 .env
echo "BASE_URL=https://plausible.example.com" >> .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48)" >> .env
echo "HTTP_PORT=8000" >> .env
echo "DISABLE_REGISTRATION=invite_only" >> .env
cat .env
```

`HTTP_PORT=8000` makes Plausible listen on plain HTTP inside the container, as the reverse proxy page of the wiki describes, and leaving out `HTTPS_PORT` keeps its built-in TLS off. `DISABLE_REGISTRATION=invite_only` is already the default; writing it down makes the choice visible.

> **Warning**
>
> Keep `SECRET_KEY_BASE` stable and secret. Plausible uses it for dashboard sessions and derives other secrets from it, including the default key that encrypts two-factor secrets. Changing it later logs everyone out and can break existing 2FA setups.

## Step 4 — Publish Plausible on the loopback address

Create `compose.override.yml` next to `compose.yml`:

```bash
nano /opt/plausible-ce/compose.override.yml
```

Map the container port to `127.0.0.1:8000`, exactly as in Plausible's reverse proxy guide:

```yaml
services:
  plausible:
    ports:
      - 127.0.0.1:8000:${HTTP_PORT}
```

Start the stack. The first start pulls the images, creates the PostgreSQL database and runs the migrations before the app starts:

```bash
cd /opt/plausible-ce
docker compose up -d
docker compose ps
docker compose logs plausible --tail 30
curl --head http://127.0.0.1:8000
```

`docker compose ps` should list `plausible`, `plausible_db` and `plausible_events_db`, and the two databases should be healthy. The `curl` command should return `HTTP/1.1 200 OK`.

## Step 5 — Serve Plausible over HTTPS with Caddy

Add a site block for the domain from `BASE_URL` to `/etc/caddy/Caddyfile`:

```caddyfile
plausible.example.com {
    reverse_proxy 127.0.0.1:8000
}
```

Reload Caddy, open the firewall for web traffic only, and test the public address:

```bash
sudo systemctl reload caddy
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
curl -I https://plausible.example.com
```

The domain in Caddy must match `BASE_URL` exactly, because Plausible uses `BASE_URL` to build links and to check the origin of dashboard connections. Caddy forwards the visitor's address in the `X-Forwarded-For` header, which Plausible uses to count unique visitors. The wiki also has Nginx and Apache examples; see [Nginx with Certbot](/guides/nginx-reverse-proxy-certbot) if you prefer Nginx.

## Step 6 — Create your account and add a site

Open `https://plausible.example.com` straight away and register the first user: until that account exists, anyone who reaches the address could create it. Use a long, unique password, and turn on two-factor authentication in your account settings.

Then add your first website with its domain and copy the tracking snippet that Plausible shows. Paste it into the `head` section of every page of that site. Plausible 3.1 introduced a new tracker script and snippet; scripts installed with older versions keep working. Open your site in a browser and check the dashboard: the visit should appear in the realtime view within a minute.

With `DISABLE_REGISTRATION=invite_only`, other people can only join through an invitation that you send from Plausible. If you never want new accounts, set `DISABLE_REGISTRATION=true` in `.env` and run `docker compose up -d`.

> **Tip**
>
> Plausible CE ships with a country-level DB-IP geolocation database. For city-level locations, create a MaxMind account, add its key to `.env` as `MAXMIND_LICENSE_KEY` and run `docker compose up -d`; Plausible then downloads the GeoLite2 City database itself.

## Step 7 — Configure email

Plausible sends invitations, password resets, email verification and scheduled reports. Without `SMTP_HOST_ADDR` it tries to deliver mail directly to the recipients' mail servers, so configure an SMTP relay from a transactional email provider instead.

> **Note**
>
> Outbound port 25 is closed by default on HyperDC VPS. For services bought for a term of 3 months or longer, it is opened on request: [open a support ticket](/guides/support-tickets). Until then, send mail through an SMTP relay on port 587.

Add the relay settings to `.env` and recreate the container:

```bash
cd /opt/plausible-ce
echo "MAILER_EMAIL=plausible@example.com" >> .env
echo "MAILER_NAME=Plausible" >> .env
echo "SMTP_HOST_ADDR=smtp.example.com" >> .env
echo "SMTP_HOST_PORT=587" >> .env
echo "SMTP_USER_NAME=your-smtp-username" >> .env
echo "SMTP_USER_PWD=change-me" >> .env
docker compose up -d
```

`MAILER_EMAIL` is the sender address and must belong to a domain your provider lets you send from. Port 587 is also Plausible's default for `SMTP_HOST_PORT`; leave `SMTP_HOST_SSL_ENABLED` at its default `false` for this port. Plausible also has API adapters for Postmark, Mailgun, Mandrill and SendGrid, selected with `MAILER_ADAPTER` and the matching API key variable. Test delivery by inviting a colleague or requesting a password reset, and check `docker compose logs plausible --tail 50` if nothing arrives.

## Back up and restore

Plausible CE keeps its state in two databases: PostgreSQL (`plausible_db`) holds users, sites, goals and settings, and ClickHouse (`plausible_events_db`) holds every pageview and event. Back up both, plus your `.env` and `compose.override.yml`. The PostgreSQL dump can run while Plausible is up. The ClickHouse data is copied as a volume archive with the containers stopped, Docker's documented way to back up a volume, so tracking requests that arrive during those minutes are lost; run it at a quiet time.

Compose prefixes volume names with the project folder name, so they are called `plausible-ce_db-data`, `plausible-ce_event-data` and so on. Confirm with `docker volume ls`, then run:

```bash
sudo mkdir -p /opt/backups && sudo chown $USER:$USER /opt/backups && chmod 700 /opt/backups
cd /opt/plausible-ce
docker compose exec -T plausible_db pg_dump -U postgres -Fc plausible_db > /opt/backups/plausible-db-$(date +%F).dump
docker compose stop plausible plausible_events_db
docker run --rm -v plausible-ce_event-data:/data -v /opt/backups:/backup alpine tar czf /backup/plausible-events-$(date +%F).tar.gz -C /data .
docker compose up -d
tar czf /opt/backups/plausible-config-$(date +%F).tar.gz -C /opt/plausible-ce .env compose.override.yml
ls -lh /opt/backups
```

Copy the three files off the server. To restore, clone the **same release** as in Step 2, put `.env` and `compose.override.yml` back in `/opt/plausible-ce`, and load both databases. Restore ClickHouse data only into the ClickHouse version it came from, which is the one pinned by the same release branch.

> **Danger**
>
> The first two commands below delete the PostgreSQL and ClickHouse data on this server. Run them only when you intend to replace that data with your backup.

```bash
cd /opt/plausible-ce
docker compose down
docker volume rm plausible-ce_db-data plausible-ce_event-data
docker compose create
docker run --rm -v plausible-ce_event-data:/data -v /opt/backups:/backup alpine tar xzf /backup/plausible-events-2026-10-09.tar.gz -C /data
docker compose up -d --wait plausible_db
docker compose exec -T plausible_db createdb -U postgres plausible_db
docker compose exec -T plausible_db pg_restore -U postgres -d plausible_db < /opt/backups/plausible-db-2026-10-09.dump
docker compose up -d
```

Replace the dates with those of your backup files. `docker compose create` recreates the empty volumes and containers without starting them, so ClickHouse finds the restored files on its first start. Sign in and check that your sites and their history are back.

## Update Plausible CE

Read the [release notes](https://github.com/plausible/analytics/releases) for every version between yours and the new one, and back up first. Plausible's wiki points out that security patches and bug fixes are not backported to older releases, so stay current; v3.2.1, for example, fixed a remote code execution issue that affected v3.0.0-rc.0 to v3.2.0. The wiki's upgrade procedure pulls the new release branch into your clone and recreates the containers:

```bash
cd /opt/plausible-ce
git pull origin v3.2.1
docker compose up -d
docker compose ps
docker image prune
```

Replace `v3.2.1` with the release branch named in the release notes. Because your settings live in the untracked files `.env` and `compose.override.yml`, `git pull` only updates `compose.yml` and the ClickHouse configuration; some releases, such as v3.2.0, change exactly those ClickHouse settings, which is why the notes ask you to switch branches instead of only changing the image tag. Migrations run automatically when the app container starts. Major PostgreSQL upgrades need a dump and restore; follow the wiki's Upgrade PostgreSQL page when a release asks for one.

## Troubleshooting

### plausible_events_db keeps restarting

ClickHouse cannot start. Read `docker compose logs plausible_events_db --tail 50`. On x86-64, missing SSE 4.2 support is a hard stop; check Step 1. If the logs mention memory, give the server more RAM; the repository's `clickhouse` folder already applies low-resource settings.

### Bind for 127.0.0.1:8000 failed: port is already allocated

Another service on the host uses port 8000. Pick a free port, change `HTTP_PORT` in `.env` and the left-hand side of the mapping in `compose.override.yml` (for example `127.0.0.1:8100:${HTTP_PORT}`), update the Caddy site block to match, and run `docker compose up -d`.

### The dashboard shows no visits

Check that the snippet is on the page and that the domain you added in Plausible matches your site's hostname. Open the browser's developer tools on your site and look for a blocked request to your Plausible domain; ad blockers often block analytics scripts. Also confirm that `BASE_URL` matches the address in the snippet.

### Invitation or password reset emails never arrive

Run `docker compose logs plausible --tail 100` and look for SMTP errors. Typical causes are a wrong host or port, `SMTP_HOST_SSL_ENABLED=true` together with port 587, a `MAILER_EMAIL` address your provider does not allow, or a missing `docker compose up -d` after editing `.env`.

### Links in emails point to the wrong address

`BASE_URL` does not match the address users open. Set it to the exact HTTPS address, including the subdomain, run `docker compose up -d`, and make sure the Caddy site block uses the same domain.

## Next steps

- Compare with another lightweight tool: [How to install Umami](/guides/install-umami).
- Need ecommerce reports and a classic PHP stack? See [How to install Matomo](/guides/install-matomo).
- Learn more about override files in [Docker Compose basics](/guides/docker-compose-basics).
- See servers for self-hosted analytics on the [web analytics hosting](/web-analytics-hosting) page.
- Read the [Plausible CE wiki](https://github.com/plausible/community-edition/wiki) for every configuration option.

## Frequently asked questions

### Where does Plausible CE store its data?

In two databases: PostgreSQL holds users, sites, goals and settings, and ClickHouse holds every pageview and event. Both run as containers defined in compose.yml, so back up both, together with .env and compose.override.yml.

### Why does Plausible CE need a CPU with SSE 4.2 or NEON?

Plausible stores events in ClickHouse, and ClickHouse requires the SSE 4.2 instruction set on x86-64 or NEON on ARM. Check the CPU flags of your server before you install.

### Can Plausible CE handle HTTPS without a reverse proxy?

Yes. Since version 2.1.2 it can obtain Let's Encrypt certificates itself when HTTP_PORT is 80 and HTTPS_PORT is 443. This guide uses Caddy instead so the same server can host other web apps on ports 80 and 443.

### Can anyone sign up on my Plausible instance?

Not by default. DISABLE_REGISTRATION defaults to invite_only, so after you create the first account new users can only join through an invitation. Set it to true to close registration completely.

### Which HyperDC servers can run Plausible CE?

Plausible CE runs in Docker on any HyperDC Linux VPS, VDS or dedicated server with root access, a supported Ubuntu or Debian release and a CPU that reports SSE 4.2 or NEON.

---

Source: <https://hyperdc.com/guides/tutorials/install-plausible-ce>\
Updated: 2026-10-09
