Self-Hosting a Lightweight Firebase Auth Alternative: A Comprehensive Guide to SuperTokens on Docker VPS
Introduction: The Shift Toward Self-Hosted Authentication
In the modern web development landscape, choosing the right authentication provider is a critical architecture decision. For years, Google's Firebase Authentication has been the go-to solution for startups and enterprise teams alike due to its rapid setup and generous free tier. However, as applications scale, reliance on proprietary, third-party vendor ecosystems introduces distinct challenges. Data sovereignty regulations, unpredictable scaling costs, and vendor lock-in have forced engineering leaders to seek viable open-source alternatives.
Enter SuperTokens: an open-source, developer-first authentication solution designed to be highly secure, deeply customizable, and remarkably lightweight. Unlike Firebase, SuperTokens gives you complete ownership of your user data. In this technical guide, we will explore how to self-host SuperTokens on your own Virtual Private Server (VPS) utilizing Docker, providing a robust, cost-effective, and independent identity management infrastructure.
Why Choose SuperTokens Over Firebase Auth?
Before diving into the implementation details, it is essential to understand the strategic advantages of transitioning from a backend-as-a-service (BaaS) model like Firebase to a self-hosted SuperTokens architecture:
- Data Ownership and Compliance: With Firebase, your user credentials reside on Google's infrastructure. Self-hosting SuperTokens allows you to store all authentication data within your isolated database, ensuring strict compliance with regulations such as GDPR, CCPA, or local data localization laws.
- Uncompromised Customization: Firebase Auth offers rigid UI components and constrained backend hooks. SuperTokens provides a modular architecture (Recipes) that allows developers to control the exact logic of login, sign-up, session management, and multi-factor authentication (MFA).
- Cost Predictability: Firebase pricing can scale aggressively based on monthly active users (MAU) once you surpass the free tier limitations, particularly for enterprise features like SAML/OIDC. A VPS running SuperTokens incurs a flat, predictable infrastructure cost regardless of your user traffic scaling.
- Advanced Session Management: SuperTokens incorporates rotating refresh tokens out of the box, mitigating risks associated with session hijacking—a feature requiring extensive manual configuration in standard JWT setups.
Architecture Overview
To deploy a production-ready instance of SuperTokens, we need to understand its structural components. The SuperTokens architecture fundamentally splits into three layers:
- The Frontend SDK: Integrated into your client application (React, Angular, Vue, Next.js, or mobile frameworks) to handle UI states and secure token storage.
- The Backend SDK: Acts as a middleware layer within your existing API server (Node.js, Python, Go) to verify sessions.
- The SuperTokens Core: An independent HTTP service responsible for the core logic of authentication and database interactions. This is the component we will be self-hosting.
For this guide, we will configure the SuperTokens Core container alongside a dedicated PostgreSQL database container, managed seamlessly via docker-compose.
Prerequisites
To successfully follow this tutorial, ensure your environment meets the following specifications:
- A VPS running a clean installation of Ubuntu (22.04 LTS or newer recommended) with a public IP address.
- A registered domain or subdomain pointing to your VPS IP address (e.g.,
auth.yourdomain.com) for SSL/TLS configuration. - Docker and Docker Compose installed and configured on the host machine.
- Basic familiarity with SSH command-line interfaces and fundamental networking concepts.
Step 1: Setting Up the Directory Structure
Connect to your VPS via SSH and establish an organized directory structure to house your deployment configuration files. This prevents configuration drift and ensures clean backups.
mkdir -p ~/supertokens-deployment/data
cd ~/supertokens-deploymentInside this directory, we will create two essential configuration files: docker-compose.yml to orchestrate our infrastructure, and an .env file to securely manage environment variables.
Step 2: Configuring the Docker Compose Environment
We will utilize Docker Compose to manage both the SuperTokens Core engine and our PostgreSQL database container. Create the file using your preferred text editor:
nano docker-compose.ymlPopulate the file with the following production-grade service configuration:
version: '3.8'
services:
supertokens-db:
image: postgres:15-alpine
container_name: supertokens_db
restart: always
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: supertokens
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- auth-network
supertokens-core:
image: registry.supertokens.io/supertokens/supertokens-core:latest
container_name: supertokens_core
restart: always
depends_on:
- supertokens-db
ports:
- "3567:3567"
environment:
API_KEYS: ${API_KEY}
DATABASE_TYPE: postgresql
POSTGRESQL_CONNECTION_URI: "postgresql://${DB_USER}:${DB_PASSWORD}@supertokens-db:5432/supertokens"
networks:
- auth-network
networks:
auth-network:
driver: bridgeSecurity Note: Never expose your raw database container ports directly to the public internet. In the configuration above, only the supertokens-core port (3567) is bound to the host, while the database remains isolated within the internal bridge network.Step 3: Defining Environment Variables
To prevent hardcoding sensitive credentials into your orchestration templates, create a companion .env file within the same directory:
nano .envDefine your credentials accurately, ensuring you generate long, cryptographically secure keys for production environments:
DB_USER=supertokens_admin
DB_PASSWORD=SuperSecurePassword2026!
API_KEY=your_generated_long_random_string_for_core_api_protectionSave the file and restrict access permissions to protect the secrets from unauthorized read operations on the host:
chmod 600 .envStep 4: Launching and Verifying the Services
With the structural blueprints finalized, execute the deployment command in detached mode to pull the official registry images and spin up the containers:
docker-compose up -dVerify that both containers are initialized and running optimally by executing a process check:
docker-compose psTo ensure that the SuperTokens Core service successfully established its connection to the database layer and instantiated the necessary schema, inspect the real-time logs:
docker-compose logs -f supertokens-coreYou should observe a log initialization message confirming that the core is "Started SuperTokens Core successfully" and listening on port 3567.
Step 5: Securing the Installation with a Reverse Proxy (Optional but Recommended)
In a production scenario, exposing your authentication server via HTTP over port 3567 is highly insecure. It is vital to route external client requests through a reverse proxy like Nginx or Caddy paired with an SSL certificate provided by Let's Encrypt.
Below is an example configuration block for an Nginx reverse proxy to safely route HTTPS traffic to your self-hosted SuperTokens service:
server {
listen 80;
server_name auth.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name auth.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/[auth.yourdomain.com/fullchain.pem](https://auth.yourdomain.com/fullchain.pem);
ssl_certificate_key /etc/letsencrypt/live/[auth.yourdomain.com/privkey.pem](https://auth.yourdomain.com/privkey.pem);
location / {
proxy_pass http://localhost:3567;
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;
}
}Step 6: Integrating Your New SuperTokens Core with Your App
Now that your dedicated auth core is active on your VPS, configuring your backend application instance to connect to it is remarkably straightforward. Here is a brief look at initializing the SuperTokens Node.js SDK using your self-hosted endpoints:
import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import EmailPassword from "supertokens-node/recipe/emailpassword";
supertokens.init({
framework: "express",
supertokens: {
connectionURI: "[https://auth.yourdomain.com](https://auth.yourdomain.com)",
apiKey: "your_generated_long_random_string_for_core_api_protection",
},
appInfo: {
appName: "My Secure Enterprise App",
apiDomain: "[https://api.yourdomain.com](https://api.yourdomain.com)",
websiteDomain: "[https://yourdomain.com](https://yourdomain.com)",
apiBasePath: "/auth",
websiteBasePath: "/auth",
},
recipeList: [
EmailPassword.init(),
Session.init(),
],
});Conclusion: Taking Control of Your Stack
Migrating away from closed authentication clouds like Firebase Auth to a self-hosted SuperTokens setup represents a major milestone in building a sovereign, robust technological ecosystem. By employing Docker on a standard VPS, you successfully reduce variable billing risks, gain complete database ownership, and maintain strict infrastructure control—all while leveraging industry-grade session security patterns. As you continue to scale your architecture, this foundation ensures your user authentication scales on your own terms.
