itsez.dev
๐Ÿ“–Tutorial

How to install Logto on a VPS

2026-07-30ยท4 min readยทAuth & users

Logto provides authentication, user management and social sign-in building blocks for applications. This guide runs the official Logto container with PostgreSQL on an Ubuntu VPS, puts the console behind HTTPS and separates public application data from private management credentials.

Prerequisites

Use a clean Ubuntu 22.04 or 24.04 VPS with SSH, a public IP, at least 2 GB of RAM and a domain such as auth.example.com. Plan separate hostnames if you want the management console and user-facing endpoints to have different access policies.

PostgreSQL 14 or higher is required. You need Docker Compose, a PostgreSQL backup destination and a way to generate random secrets. Identity data is security-sensitive, so keep the host patched and restrict administrative access.

Step 1, Connecting to your server

Prepare the host:

ssh root@SERVER_IP
apt update && apt upgrade -y
apt install -y ca-certificates curl
mkdir -p /opt/logto
cd /opt/logto
chmod 750 /opt/logto

Allow SSH, HTTP and HTTPS only. Keep PostgreSQL on the private Docker network, and check that no unrelated service occupies the proxy ports.

Step 2, Installing Docker and Docker Compose

Install Docker Engine and the Compose plugin from Docker's official Ubuntu documentation:

docker --version
docker compose version
systemctl enable --now docker

Use the PostgreSQL and Logto versions supported by the current official release. Do not update either major version without reading the migration notes.

Step 3, Running Logto with Docker Compose

Create .env and replace every value marked as a placeholder:

POSTGRES_DB=logto
POSTGRES_USER=logto
POSTGRES_PASSWORD=REPLACE_WITH_A_RANDOM_VALUE
DB_URL=postgres://logto:REPLACE_WITH_A_RANDOM_VALUE@db:5432/logto
LOGTO_ENDPOINT=https://auth.example.com
LOGTO_ADMIN_ENDPOINT=https://admin.example.com

The exact environment names and endpoint model can vary by release. Use the names from the official Logto deployment documentation and keep the database password synchronized with DB_URL. LOGTO_ENDPOINT must be set to your final public URL (e.g., https://auth.example.com). Changing this after setup invalidates existing OIDC clients and tokens.

The deployment shape is:

services:
  db:
    image: postgres:14
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db_data:/var/lib/postgresql/data

  logto:
    image: svhd/logto:latest
    restart: unless-stopped
    depends_on:
      - db
    environment:
      DB_URL: ${DB_URL}
    ports:
      - "127.0.0.1:3001:3001"
      - "127.0.0.1:3002:3002"

volumes:
  db_data:

Use the official Compose file if the current release adds required services or commands. Validate, start and inspect it:

docker compose config
docker compose pull
docker compose up -d
docker compose ps

Run the documented database initialization or migration command before creating production tenants. For air-gapped servers, pass --disable-admin-pwned-password-check during initial database seeding, otherwise the first admin signup hangs on the Have I Been Pwned check.

Step 4, Configuring the reverse proxy

Logto exposes two ports: 3001 for the Core/Experience/auth endpoint and 3002 for the Admin Console. Route the user endpoint to port 3001 and the administration endpoint to port 3002 as specified by the release. Terminate HTTPS with Caddy or Nginx, forward host and protocol headers and keep both container ports private. Give the console a separate hostname and an additional access restriction when possible.

Test redirect URIs, cookie security and certificate renewal. OAuth clients reject small hostname or scheme mismatches, so use the exact HTTPS URLs configured in Logto. Set TRUST_PROXY_HEADER=1 in the environment when running Logto behind a reverse proxy. Without this, the OIDC issuer URL defaults to http://127.0.0.1:3001.

Step 5, First access and initial setup

Open the protected console and create the first tenant or organization. Register a test application, configure its redirect URI and create a test user. Verify sign-in, sign-out, token refresh and the callback from a disposable environment.

Keep client IDs in application configuration and client secrets on the server. Enable only the social connectors and scopes you actually need. Review user invitation and password policies before onboarding real users.

Maintenance

Back up PostgreSQL and all Logto secrets together. Test restoring a tenant on a separate host. Update Logto through the supported release process, monitor migration logs and verify a complete login flow after every update.

Watch failed logins, database connections, disk and certificate expiry. Never solve a login problem by disabling HTTPS or exposing PostgreSQL publicly.

Tools mentioned

Logto

โ†—

Authentication and authorization infrastructure for consumer and business apps.

FreemiumNo cardOSS

Free cloud plan: 50k monthly active users and core auth; the open-source edition can be self-hosted free.

ABOUT US

Honest, independent, no fluff.

No paid placements. Just a clear look at what this does, what it costs, and what to know before you commit.

Read moreโ†’

FAQ

Questions, answered.

What database does Logto use?๏ผ‹

Use the PostgreSQL version supported by the current Logto release and preserve its data on a persistent volume or managed database.

Should the Logto console be public?๏ผ‹

Protect the console with HTTPS, strong administrator accounts and, where possible, an IP or VPN restriction. Applications only need the public endpoints they use.

What must be backed up?๏ผ‹

Back up PostgreSQL and the environment secrets required to decrypt or sign Logto data. Test the restore before relying on it.