...
🚀 install plausible ce on almalinux vps
Learn how to install plausible ce on almalinux vps!

This article provides a guide to install Plausible CE on AlmaLinux VPS using Docker Compose, then puts it behind Nginx with HTTPS from Let’s Encrypt.

What is Plausible CE?

Plausible CE stands for Plausible Community Edition.

It is the free, self-hosted version of Plausible Analytics, a privacy-focused alternative to Google Analytics. Instead of sending your website analytics data to a third-party analytics provider, you install Plausible CE on AlmaLinux VPS or server and keep the data under your control.

Plausible describes CE as the free, self-hosted, AGPL-licensed release of Plausible Analytics. Their managed cloud service is the paid hosted version, while CE is for users who want to run and maintain it themselves.

In practical terms, Plausible CE gives you:

  • Website traffic analytics
  • Page views, visitors, referrers, countries, devices, browsers, and operating systems
  • Goal and event tracking
  • A lightweight tracking script
  • Cookie-free analytics
  • A cleaner, simpler dashboard than Google Analytics
  • Full self-hosting control

It is commonly used by website owners, agencies, SaaS companies, privacy-focused businesses, and hosting providers that want analytics without the heavier tracking model of traditional ad-tech platforms.

A typical Plausible CE deployment runs with:

  • Plausible application
  • PostgreSQL database
  • ClickHouse analytics/event database
  • Docker Compose
  • Reverse proxy such as Nginx, Caddy, or Traefik

The official Plausible CE repository notes that Docker and Docker Compose are required, ClickHouse requires SSE 4.2 or NEON CPU support, and at least 2 GB RAM is recommended.

The main difference is:

  • Plausible Cloud = hosted and maintained by Plausible
  • Plausible CE = installed, hosted, updated, secured, and backed up by you

So, Plausible CE is best understood as a self-hosted, privacy-friendly web analytics platform for people who want Google Analytics-style insight without giving up control of their analytics data.

Plausible CE’s current official community setup is Docker-based. Its repo lists Docker and Docker Compose as prerequisites, requires a CPU with SSE 4.2 or NEON support because of ClickHouse, and recommends at least 2 GB RAM. The current quick-start branch shown by the Plausible CE repo is v3.2.1.

Assumptions used below:

  • Plausible domain: analytics.example.com
  • Server OS: AlmaLinux 9 or AlmaLinux 10
  • Public ports: 80 and 443 handled by Nginx
  • Plausible internal port: 8000, bound only to 127.0.0.1
  • Install directory: /opt/plausible-ce

Replace analytics.example.com with your real domain.

Launch 100% ssd almalinux vps from $3. 19/mo!
[pricing_comparison_almalinux]

Install Plausible CE on AlmaLinux VPS with Nginx Reverse Proxy

To install Plausible CE on AlmaLinux VPS with Nginx reverse proxy, follow the steps below:

  1. Point DNS to your VPS

    Create an A record:

    analytics.example.com -> YOUR_SERVER_IPV4
    

    Optional IPv6:

    analytics.example.com -> YOUR_SERVER_IPV6
    

    Wait until DNS resolves:

    dig +short analytics.example.com
    

    or:

    ping analytics.example.com
    

    Do not continue with Let’s Encrypt until the domain points to the VPS.

  2. Update AlmaLinux

    SSH into your VPS as root or a sudo user:

    ssh root@YOUR_SERVER_IP
    

    Update packages:

    dnf update -y
    dnf install -y curl wget git nano unzip tar dnf-plugins-core openssl
    

    Reboot if the kernel was updated:

    reboot
    

    Reconnect after reboot.

  3. Set the hostname

    Optional but recommended:

    hostnamectl set-hostname analytics.example.com
    

    Verify:

    hostnamectl
    
  4. Install Docker Engine and Docker Compose plugin

    Docker’s official CentOS/RHEL-family instructions recommend installing from Docker’s RPM repository and installing docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, and docker-compose-plugin.

    Remove conflicting container packages if present:

    dnf remove -y podman buildah runc
    

    Add Docker’s repo:

    dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    

    Install Docker:

    dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    

    Enable and start Docker:

    systemctl enable --now docker
    

    Verify:

    docker --version
    docker compose version
    systemctl status docker --no-pager
    

    Test Docker:

    docker run --rm hello-world
    
  5. Install Nginx and Certbot

    dnf install -y epel-release
    dnf install -y nginx certbot python3-certbot-nginx
    

    Enable Nginx:

    systemctl enable --now nginx
    

    Verify:

    nginx -v
    systemctl status nginx --no-pager
    
  6. Configure the firewall

    If firewalld is enabled:

    systemctl enable --now firewalld
    firewall-cmd --permanent --add-service=http
    firewall-cmd --permanent --add-service=https
    firewall-cmd --reload
    firewall-cmd --list-all
    

    Do not expose Plausible’s internal port 8000 publicly.

  7. Handle SELinux for Nginx reverse proxying

    On AlmaLinux, SELinux is usually enabled. Nginx may be blocked from proxying to a local backend unless this boolean is enabled:

    setsebool -P httpd_can_network_connect 1
    

    Verify SELinux status:

    getenforce
    
  8. Clone Plausible CE

    Create the install directory:

    mkdir -p /opt
    cd /opt
    

    Clone the current Plausible CE branch shown in the official quick start:

    git clone -b v3.2.1 --single-branch https://github.com/plausible/community-edition plausible-ce
    cd /opt/plausible-ce
    

    The official quick start uses this same clone pattern, then creates a .env file with BASE_URL and SECRET_KEY_BASE.

    Check files:

    ls -la
    

    You should see files like:

    compose.yml
    clickhouse/
    README.md
    LICENSE
    
  9. Create the Plausible environment file

    Create .env:

    cd /opt/plausible-ce
    nano .env
    

    Add:

    BASE_URL=https://analytics.example.com
    SECRET_KEY_BASE=REPLACE_WITH_GENERATED_SECRET
    HTTP_PORT=8000
    

    Generate a secure secret:

    openssl rand -base64 48
    

    Paste the generated value into .env.

    Example:

    BASE_URL=https://analytics.example.com
    SECRET_KEY_BASE=Q6c5xHhV7oYx7q9Z7REPLACE_THIS_WITH_YOUR_REAL_GENERATED_VALUE
    HTTP_PORT=8000
    

    BASE_URL and SECRET_KEY_BASE are required. Plausible’s configuration page says BASE_URL has no default, and SECRET_KEY_BASE must be at least 64 bytes; it also shows generating it with openssl rand -base64 48.

    Set safe permissions:

    chmod 600 .env
    
  10. Create a Docker Compose override for localhost-only access

    By default, this guide puts Nginx in front of Plausible. So Plausible should listen only on localhost, not directly on the public internet.

    Create:

    nano compose.override.yml
    

    Add:

    services:
      plausible:
        ports:
          - "127.0.0.1:8000:8000"
    

    This means:

    Host 127.0.0.1:8000 -> Plausible container port 8000
    

    Do not use:

    - "0.0.0.0:8000:8000"
    

    unless you intentionally want the app exposed directly.

  11. Start Plausible CE

    From /opt/plausible-ce:

    docker compose pull
    docker compose up -d
    

    Check running containers:

    docker compose ps
    

    Check logs:

    docker compose logs -f
    

    You should eventually see the Plausible app start successfully.

    Test locally from the server:

    curl -I http://127.0.0.1:8000
    

    Expected result should include an HTTP response from Plausible, commonly 200, 302, or similar.

  12. Create the Nginx reverse proxy config

    Create an Nginx server block:

    nano /etc/nginx/conf.d/plausible.conf
    

    Add:

    server {
        listen 80;
        listen [::]:80;
    
        server_name analytics.example.com;
    
        access_log /var/log/nginx/plausible.access.log;
        error_log  /var/log/nginx/plausible.error.log;
    
        location / {
            proxy_pass http://127.0.0.1:8000;
    
            proxy_http_version 1.1;
    
            proxy_set_header Host              $host;
            proxy_set_header X-Real-IP         $remote_addr;
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Host  $host;
    
            proxy_set_header Upgrade           $http_upgrade;
            proxy_set_header Connection        "upgrade";
    
            proxy_read_timeout 60s;
            proxy_send_timeout 60s;
        }
    }
    

    Test Nginx:

    nginx -t
    

    Reload:

    systemctl reload nginx
    

    Visit:

    http://analytics.example.com
    

    At this stage HTTP should work.

  13. Install Let’s Encrypt SSL

    Run Certbot:

    certbot --nginx -d analytics.example.com
    

    Choose the redirect-to-HTTPS option when prompted.

    Test renewal:

    certbot renew --dry-run
    

    Check the generated HTTPS config:

    nginx -t
    systemctl reload nginx
    

    Visit:

    https://analytics.example.com
    
  14. Create your first Plausible user

    Register plausible ce account
    Register plausible ce account

    Open:

    https://analytics.example.com
    

    Create the first admin user through the web interface.

    After creating the first user, I recommend disabling open registration.

    Edit .env:

    cd /opt/plausible-ce
    nano .env
    

    Add:

    DISABLE_REGISTRATION=true
    

    Restart Plausible:

    docker compose up -d
    

    Plausible CE’s configuration docs list DISABLE_REGISTRATION as an available registration control with values including true, false, and invite_only.

  15. Configure email sending

    Plausible can run without email, but password resets, invites, email verification, and reports need SMTP or an email provider.

    Add SMTP-related values to .env. Example:

    MAILER_EMAIL=analytics@example.com
    SMTP_HOST_ADDR=smtp.example.com
    SMTP_HOST_PORT=587
    SMTP_USER_NAME=analytics@example.com
    SMTP_USER_PWD=YOUR_SMTP_PASSWORD
    SMTP_HOST_SSL_ENABLED=false
    SMTP_RETRIES=2
    

    Then restart:

    docker compose up -d
    

    Check logs:

    docker compose logs -f plausible
    

    Plausible CE docs state that transactional emails such as account activation and password reset are sent through SMTP by default, with other services such as Postmark, Mailgun, Mandrill, or SendGrid also supported.

  16. Add your first website in Plausible

    Add website in plausible
    Add website in plausible

    Inside the Plausible dashboard:

    1. Click Add website.
    2. Enter your site domain, for example:
      example.com
      
    3. Copy the tracking script.
    4. Add it before on your website.

    The snippet will look similar to:

    <!-- Privacy-friendly analytics by Plausible -->
    <script async src="https://analytics.example.com/js/pa-iev8zYK-aOK0OR2L0DwJR.js"></script>
    <script>
    window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
    plausible.init()
    </script>
    

    Then visit your website and confirm real-time traffic appears in Plausible.

  17. Optional: proxy the tracking script through your main website domain

    This is different from the Nginx reverse proxy used to host Plausible itself.

    Example:

    Plausible dashboard: https://analytics.example.com
    Main website: https://example.com
    Proxied script: https://example.com/js/script.js
    Proxied event endpoint: https://example.com/api/event
    

    Plausible’s Nginx proxy guide describes proxying the script and event endpoint through your own domain, with locations for /js/script.js and /api/event.

    On your main website’s Nginx config, add:

    location = /js/script.js {
        proxy_pass https://analytics.example.com/js/script.js;
        proxy_set_header Host analytics.example.com;
        proxy_buffering on;
    }
    
    location = /api/event {
        proxy_pass https://analytics.example.com/api/event;
        proxy_set_header Host analytics.example.com;
        proxy_buffering on;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
    }
    

    Then change your tracking code to:

     

    For custom events, use the proxied endpoint if needed.

  18. Useful management commands

    Go to the install directory first:

    cd /opt/plausible-ce
    

    Start:

    docker compose up -d
    

    Stop:

    docker compose down
    

    Restart:

    docker compose restart
    

    View status:

    docker compose ps
    

    View logs:

    docker compose logs -f
    

    View only Plausible logs:

    docker compose logs -f plausible
    

    Pull updated images:

    docker compose pull
    docker compose up -d
    
  19. Backups

    Plausible CE uses PostgreSQL for user/config data and ClickHouse for analytics events. Its configuration docs state that PostgreSQL stores user data and ClickHouse stores analytics data.

    Create a backup directory:

    mkdir -p /opt/backups/plausible
    chmod 700 /opt/backups/plausible
    

    Back up PostgreSQL

    cd /opt/plausible-ce
    
    docker compose exec -T plausible_db pg_dump -U postgres plausible_db > /opt/backups/plausible/plausible_db_$(date +%F).sql
    

    Back up Docker volumes

    List volumes:

    docker volume ls | grep plausible
    

    Create a compressed backup of Plausible-related volumes:

    cd /opt/plausible-ce
    
    docker run --rm \
      -v plausible-ce_db-data:/volume/db-data:ro \
      -v plausible-ce_event-data:/volume/event-data:ro \
      -v /opt/backups/plausible:/backup \
      alpine \
      tar czf /backup/plausible_volumes_$(date +%F).tar.gz -C /volume .
    

    Volume names may differ. Confirm them with:

    docker volume ls
    
  20. Set up automatic backup cron

    Create a script:

    nano /usr/local/sbin/backup-plausible.sh
    

    Add:

    #!/bin/bash
    set -euo pipefail
    
    BACKUP_DIR="/opt/backups/plausible"
    APP_DIR="/opt/plausible-ce"
    DATE="$(date +%F-%H%M%S)"
    
    mkdir -p "$BACKUP_DIR"
    
    cd "$APP_DIR"
    
    docker compose exec -T plausible_db pg_dump -U postgres plausible_db > "$BACKUP_DIR/plausible_db_$DATE.sql"
    
    docker run --rm \
      -v plausible-ce_db-data:/volume/db-data:ro \
      -v plausible-ce_event-data:/volume/event-data:ro \
      -v "$BACKUP_DIR":/backup \
      alpine \
      tar czf "/backup/plausible_volumes_$DATE.tar.gz" -C /volume .
    
    find "$BACKUP_DIR" -type f -mtime +14 -delete
    

    Make executable:

    chmod +x /usr/local/sbin/backup-plausible.sh
    

    Test:

    /usr/local/sbin/backup-plausible.sh
    ls -lh /opt/backups/plausible
    

    Create cron:

    crontab -e
    

    Add:

    15 2 * * * /usr/local/sbin/backup-plausible.sh >/var/log/plausible-backup.log 2>&1
    
  21. Update Plausible CE

    Check the Plausible CE GitHub releases before upgrading.

    Basic update process:

    cd /opt/plausible-ce
    docker compose down
    git fetch --tags
    git checkout vNEW_VERSION
    docker compose pull
    docker compose up -d
    docker compose logs -f
    

    Always back up before upgrading:

    /usr/local/sbin/backup-plausible.sh
    
  22. Harden the installation

    Recommended production settings:

    chmod 600 /opt/plausible-ce/.env
    chown -R root:root /opt/plausible-ce
    

    Make sure Plausible is not publicly exposed:

    ss -tulpn | grep 8000
    

    You want to see something like:

    127.0.0.1:8000
    

    not:

    0.0.0.0:8000
    

    Check open firewall services:

    firewall-cmd --list-services
    

    Expected:

    http https ssh
    

    Consider restricting SSH to your IP and using SSH keys.

  23. Troubleshooting

    • Nginx returns 502 Bad Gateway

      Check Plausible:

      cd /opt/plausible-ce
      docker compose ps
      docker compose logs --tail=100 plausible
      curl -I http://127.0.0.1:8000
      

      Check Nginx errors:

      tail -f /var/log/nginx/plausible.error.log
      

      If SELinux is enforcing, run:

      setsebool -P httpd_can_network_connect 1
      
    • Certbot fails

      Check DNS:

      dig +short analytics.example.com
      

      Check ports:

      firewall-cmd --list-services
      

      Check Nginx config:

      nginx -t
      

      Retry:

      certbot --nginx -d analytics.example.com
      
    • Plausible says the domain or URL is wrong

      Verify .env:

      cat /opt/plausible-ce/.env
      

      Make sure:

      BASE_URL=https://analytics.example.com
      

      Then restart:

      cd /opt/plausible-ce
      docker compose up -d
      
    • Containers keep restarting

      View logs:

      cd /opt/plausible-ce
      docker compose logs -f
      

      Common causes:

      Invalid SECRET_KEY_BASE
      Wrong BASE_URL
      Not enough RAM
      ClickHouse startup failure
      Bad compose.override.yml indentation
      
  24. Final verification checklist

    Run:

    curl -I https://analytics.example.com
    docker compose -f /opt/plausible-ce/compose.yml -f /opt/plausible-ce/compose.override.yml ps
    certbot certificates
    

    Confirm:

    https://analytics.example.com loads
    First admin user exists
    Registration is disabled
    Tracking script is installed on your site
    Real-time visits appear in Plausible
    Backups are working
    Certbot dry-run succeeds
    Plausible port 8000 is bound only to 127.0.0.1
    

Launch 100% ssd almalinux vps from $3. 19/mo!

Conclusion

You now know how to install Plausible CE on AlmaLinux VPS.

Avatar of editorial staff

Editorial Staff

Rad Web Hosting is a leading provider of web hosting, Cloud VPS, and Dedicated Servers in Dallas, TX.
lg