Workload · Running your own web analytics

Plausible Analytics self-hosted, on a server nobody else uses

To run Plausible Analytics self-hosted you install its Community Edition with Docker Compose on a Linux server whose processor supports SSE 4.2, and the project recommends giving it at least 2 GB of memory. You get cookie-free visitor stats with the data on a machine you control. Here is what that machine needs, what the free edition leaves out, and an evening's setup that keeps strangers from claiming your dashboard.

The short version
  1. Your visitor data stays on hardware you rent alone
  2. Needs SSE 4.2 (or NEON on ARM); 2 GB of RAM or more recommended
  3. Installs as three Docker containers
  4. First sign-up wins, so make sure it is yours
  5. No traffic allowance on the port to outgrow

Why run Plausible yourself

Plausible counts visits without cookies, and its Community Edition (CE) is the version you host. Plausible's own comparison is honest about the trade: you take on installation, upgrades, backups and security, and in return you decide which country the data lives in and you can read the raw events straight out of the database. If your reason is keeping visitor data in a place you choose, that is exactly what a server of your own gives you.

Behind the dashboard sit two databases. PostgreSQL holds your login, your sites and your goals. ClickHouse, a column database built for analytics, holds every pageview. You never install either by hand; the Compose file starts them for you.

Will a small server keep up?

Yes, for most sites, because the published requirements are modest:

  • Processor: it must support the SSE 4.2 instruction set, or NEON on ARM. ClickHouse will not run without it. Type grep -o -m1 sse4_2 /proc/cpuinfo; if it prints sse4_2, you are fine.
  • Memory: the README's recommendation is 2 GB of memory or more, so neither database runs out. The Compose file switches ClickHouse to low-resource settings to make that work.
  • City-level locations: country lookup is built in; adding MaxMind's GeoLite2-City database for cities costs roughly 1 GB more RAM, per the wiki.
  • Disk and traffic: Plausible publishes no figure. Storage grows with the pageviews you keep, so watch it after the first month.

What the free edition leaves out

CE's licence, as the main plausible/analytics README puts it, is the GNU Affero GPL in version 3, or a later version if you prefer. The tracking snippet that goes on your website carries the MIT licence instead, which keeps your own site outside the AGPL.

You get with CEYou do not get
Dashboards, goals, imports, raw event accessFunnels for marketing, revenue goals for online shops, single sign-on, the sites API
Bot filtering by User-Agent and referrer spamThe cloud's exclusion of data-centre IP ranges
A long-term release twice a yearNew features the week they ship
Community help on GitHub discussionsPremium support from the Plausible team

The server that fits

Our smallest dedicated server already carries 8 GB of RAM, well past what Plausible recommends, and it is entirely yours: every core, all the memory and the disks, with root access and no other customer on the hardware. For one or a handful of sites, a compact x86 cartridge server does the job; skip the X-Gene ARM cartridge, which cannot run the ClickHouse image (on ARM it requires ARMv8.2 or newer). If you plan to let colleagues query ClickHouse directly, pick more memory and NVMe storage; our ClickHouse workload page explains how that database likes to be sized.

Choose the city with your visitors and your privacy rules in mind; Amsterdam and Bucharest are our European locations. Nothing meters the port, so a post that goes viral and floods you with tracking hits never shows up on the invoice. A ready server is handed over within 30 minutes of the payment being approved, and if a setup goes sideways you can reinstall the operating system yourself in the control panel, any number of times.

Up and running in an evening

  1. Create a DNS record, for example stats.yourdomain.com, pointing at the server.
  2. Install Docker and its Compose plugin by following Docker's own instructions for your Linux distribution.
  3. Switch on the firewall first, letting in only SSH and web traffic: sudo ufw allow OpenSSH, then sudo ufw allow 80/tcp and sudo ufw allow 443/tcp, then sudo ufw enable. On Ubuntu, ufw writes IPv6 rules alongside the IPv4 ones by default (IPV6=yes in /etc/default/ufw); leave that on.
  4. Download Plausible, create the settings file and start it, as below. The override makes Plausible answer only on 127.0.0.1, the server talking to itself, so nothing outside can reach it yet.
  5. Check it is alive with curl --head http://localhost:8000.
git clone -b v3.2.1 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
touch .env
chmod 600 .env
echo "BASE_URL=https://stats.yourdomain.com" >> .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48)" >> .env
echo "HTTP_PORT=8000" >> .env
printf 'services:\n  plausible:\n    ports:\n      - 127.0.0.1:8000:8000\n' > compose.override.yml
docker compose up -d

SECRET_KEY_BASE signs your login sessions and must be at least 64 bytes; openssl rand -base64 48 gives exactly 64 characters. The file is made private with chmod 600 before any secret goes in, and because the key is created inside the command, your shell history keeps the $(openssl ...) text rather than the key itself.

Make sure the first account is yours

A brand-new Plausible redirects every visitor to its sign-up form, and the first person to fill it in becomes the owner, even if you have already set DISABLE_REGISTRATION (the check in Plausible's source skips that setting until an account exists). So when you put a web server in front, start with a rule that turns everyone away except you.

The wiki's reverse-proxy page shows Caddy first; Caddy fetches the HTTPS certificate on its own. Install it from Caddy's packages, then write /etc/caddy/Caddyfile with your home or office IPv4 address and, if you have IPv6, your whole /64 prefix: home IPv6 addresses change often, but the prefix stays put.

stats.yourdomain.com {
    @notme {
        not remote_ip 198.51.100.7 2001:db8:1::/64
    }
    respond @notme "Coming soon" 403
    reverse_proxy localhost:8000
}
  1. Run sudo systemctl reload caddy and give it a moment to get the certificate.
  2. Open https://stats.yourdomain.com and create your account.
  3. Remove the @notme block and the respond line, reload Caddy again, and the dashboard is open to the world, with sign-ups closed.

Keeping it locked down

Out of the box DISABLE_REGISTRATION is invite_only: nobody can sign up unless you invite them. Never adding teammates? Add DISABLE_REGISTRATION=true to .env, which turns invitations off too, and apply it with docker compose up -d.

One trap catches many Docker users: ports that Docker publishes skip the ufw firewall completely. That is why the override above names 127.0.0.1. If you copied the README's quicker setup with 80:80 and 443:443, those ports would be open on every IPv4 and IPv6 address whatever ufw says. Run sudo ss -tlnp and check that only SSH and Caddy face the internet.

Plausible also sends email, for password resets, invitations and weekly reports. Point SMTP_HOST_ADDR and its login settings at a mail relay you trust; sending on its own requires the server to reach port 25 outbound, plus SPF or DKIM records on your domain.

Keeping your numbers safe

  • Update when a release lands. The wiki says fixes are not backported. A minor update is docker compose up -d after a git pull origin of the new version's tag. Before a major version, read its release notes: they list extra steps.
  • Back up both databases. Dump PostgreSQL with docker compose exec -T plausible_db pg_dump -U postgres plausible_db, piped to a compressed file. Save ClickHouse's event-data volume while the containers are stopped, or with ClickHouse's own backup command.
  • Keep the .env file with the backups, encrypted, because a restored install needs the same secret key.
  • Copy everything off the server. Copies that never leave the machine are lost with it.

When a server of your own is not the answer

If you need funnels, revenue tracking or single sign-on, CE simply does not include them. If an hour of lost stats during an upgrade would hurt, remember that one server is one machine. And if nobody on your team wants to look after updates and backups, the README itself says self-hosting means you do it all.

Questions people ask

Is self-hosted Plausible really free?
The software costs nothing: CE is AGPLv3, and Plausible calls it free as in beer. You pay for the server you run it on and any backup storage. Plausible itself charges self-hosters no fee.
Can I bring over years of history from Google Analytics?
You can import GA4 data. The CE wiki walks through creating an OAuth client in Google Cloud and putting its two values, GOOGLE_CLIENT_SECRET and GOOGLE_CLIENT_ID, into .env. The same setup can pull Search Console keywords into your dashboard.
Do I need Nginx or Caddy at all?
Not strictly. Plausible can serve HTTPS itself and fetch Let's Encrypt certificates when you set HTTPS_PORT=443 together with HTTP_PORT=80. A web server in front lets you keep Plausible on 127.0.0.1, create your account privately and host other sites on the same machine.
Will one server handle several websites?
Yes. You add each website in the dashboard and each gets its own stats. Plausible publishes no sizing per site, so start with plenty of memory and watch disk use as events build up.
What if a firewall rule shuts me out of SSH?
On our rack servers and blades, and on two cartridge models (m510, m710x), the out-of-band console gives you the screen and the power button without SSH, so you can fix the rule yourself. On other cartridges you have power control only, and you can always reinstall the operating system from the control panel.

Give your analytics a home of its own

Pick a server, choose the city closest to your visitors and see the monthly price before you pay. No contract, and nothing metered on the port.

Get a server for your analytics

Read next