This guide explains how to set up Shelf.nu with Supabase using Podman completely self-hosted. The setup includes various services like database, authentication, storage, analytics, and more.
The current setup is experiencing significant stability issues due to race conditions between container startups. Containers may fail to start properly if their dependencies aren't fully initialized. To mitigate these issues:
- Always clean up existing containers first:
podman compose down- Start the analytics service first:
podman compose up analytics -d- Then start the remaining services:
podman compose upIf any containers fail, you'll see errors in the logs mentioning "error graph container name". You may need to repeat this process several times to get a stable environment.
- Fedora 40 (Workstation Edition)
- Podman installed
- podman-compose installed
- Basic understanding of containerization and PostgreSQL
- Deno for setting up
ANONandSERVICE_ROLE_KEYautomatically - A working SMTP server to sign up for a user,
src/main.jshas some code for creating a user but it hasn't been tested. I used Google Workspace.
sudo rm -rf volumes/db/data.
- Clone the repository and create necessary directories:
mkdir -p volumes/db/data
mkdir -p volumes/storage
mkdir -p volumes/functions
mkdir -p volumes/logs
mkdir -p volumes/api- Create the environment file:
cp .env.sample .envAfter setting up your .env file, you'll need to generate the JWT tokens for Supabase authentication. This is automated using a Deno script:
- Ensure you have set a value for
JWT_SECRETin your.envfile - Run the JWT generation script on any
JWT_SECRETchange:
deno run -A src/createjwt.jsThis will automatically:
- Generate an
ANON_KEYfor public access - Generate a
SERVICE_ROLE_KEYfor administrative access - Update your
.envfile with these values
The Vector service is responsible for log aggregation. Its configuration needs to be mounted with proper SELinux context (primarily for Fedora and other SELinux-enabled systems, can possibly be omitted on Ubuntu-based systems):
- ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro,zThe :ro,z flags mean:
ro: Read-only accessz: Proper SELinux context for sharing between container and host
Even though we're using PostgreSQL as our backend through Supabase, the analytics service (Logflare) requires a Google Cloud configuration file. We create a dummy file to satisfy this requirement:
{
"type": "service_account",
"project_id": "dummy",
"private_key_id": "dummy",
"private_key": "-----BEGIN PRIVATE KEY-----\nDUMMY\n-----END PRIVATE KEY-----\n",
"client_email": "dummy@dummy.iam.gserviceaccount.com",
"client_id": "000000000000000000000"
}The database service requires several Supabase-specific initialization scripts:
realtime.sql: Sets up the Supabase realtime schemawebhooks.sql: Configures Supabase webhook functionalityroles.sql: Sets up Supabase database roles and permissionsjwt.sql: Configures Supabase JWT settings
Kong serves as Supabase's API gateway and needs proper route configuration in volumes/api/kong.yml. It handles:
- Supabase authentication routes
- REST API routes
- Supabase realtime websocket connections
- Supabase storage endpoints
The analytics service is configured to use Supabase's PostgreSQL instead of BigQuery:
environment:
POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/_supabase
POSTGRES_BACKEND_SCHEMA: _analytics
LOGFLARE_FEATURE_FLAG_OVERRIDE: multibackend=trueThe SELinux-related configurations in this guide (:z, :Z, :ro,z flags for volume mounts) are specific to Fedora and other SELinux-enabled systems. If you're using Ubuntu or another distribution without SELinux, you can possibly omit these flags from the volume mount configurations.
If Kong can't resolve service names, verify the container network configuration and make sure the service names match the hostnames in Kong's configuration.
Always make sure all containers are in a healthy state and that depending containers are running without errors.
If services can't connect to the Supabase database:
- Verify the database is running
- Check the database logs
- Ensure proper credentials in environment variables
If the analytics service fails:
- Verify the gcloud.json file exists
- Ensure PostgreSQL backend configuration is correct
- Check if all required Supabase schemas are created
When using Podman with SELinux (Fedora-specific):
:z: Share the volume among multiple containers:Z: Private unshared volume- Add
,rofor read-only mounts (e.g.,:ro,z)
- Change all default passwords and secrets in production
- Review and adjust JWT expiration times in Supabase
- Configure proper SSL/TLS in production
- Review and adjust database connection pool sizes based on load
- Implement proper backup strategies for the Supabase database and storage
# View running containers
podman ps
# View container logs
podman logs container-name
# Execute commands in containers
podman exec -it container-name command
# Reset database data only (safe to do)
sudo rm -rf volumes/db/data
# Reset everything
podman-compose down -vIf you're having issues with user signups or email notifications, you can test your SMTP configuration using the provided Deno script. First, ensure your .env file has the following SMTP-related variables:
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PWD=your-app-specific-password
SMTP_FROM=your-email@gmail.com
SMTP_ADMIN_EMAIL=admin@yourdomain.comTo test your SMTP configuration:
deno run -A src/test-smtp.jsIf you're using Gmail as your SMTP server:
- Disable 2-Factor Authentication if not already enabled
- Visit the Google Account settings page
- Enable 2-Factor Authentication if not already enabled
- Generate an App Password:
- Go to Security → App Passwords
- Select "Mail" and your device
- Use the generated 16-character password as your
SMTP_PWD
If you're experiencing SMTP-related problems:
-
Authentication Failures (535 Error):
- Verify
SMTP_USERmatches exactly with your email address - Check that
SMTP_PWDis correct - For Gmail: Use App Password in case of Method 2 and regular password in case of Method 1
- Ensure 2FA is enabled for Gmail App Password generation in case of Method 1
- Verify
-
Connection Issues:
- Verify
SMTP_HOSTandSMTP_PORTare correct - Try with TLS enabled/disabled
- Ensure
SMTP_FROMmatches your authenticated email
- Verify
You can use the SMTP test script to diagnose these issues. The script will provide specific error messages and suggestions for common problems. If you see "Test email sent successfully!", your SMTP configuration is working correctly.