Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/noelzappy/vaulx/llms.txt

Use this file to discover all available pages before exploring further.

Vaulx is configured entirely through environment variables — there is no YAML or TOML config file. On startup the server loads variables from a .env file in the working directory if one is present (via godotenv), and then falls back to the process environment. This means the same binary works identically in local development, Docker Compose, and production PaaS deployments like Dokploy without any code changes.

Environment variables

VariableRequiredDefaultDescription
DATABASE_URLYesPostgres connection string, e.g. postgres://user:pass@host:5432/db?sslmode=disable
SESSION_SECRETYesRandom string ≥ 32 chars used to sign and verify session cookies
PORTNo8080HTTP listen port
SEED_ADMIN_EMAILNoEmail for the admin account seeded on first boot. If unset, seeding is skipped.
SEED_ADMIN_PASSWORDNoPassword for the seeded admin. If unset, seeding is skipped. No length or complexity check is enforced at seed time.
HETZNER_ACCESS_KEYYesHetzner Object Storage access key
HETZNER_SECRET_KEYYesHetzner Object Storage secret key
HETZNER_S3_ENDPOINTYesStorage endpoint URL, e.g. https://fsn1.your-objectstorage.com
HETZNER_BUCKETYesBucket name
A complete .env file for local development looks like this:
DATABASE_URL=postgres://user:pass@localhost:5432/vaulx?sslmode=disable
SESSION_SECRET=replace-with-32-plus-byte-random-string
PORT=8080
SEED_ADMIN_EMAIL=admin@yourdomain.com
SEED_ADMIN_PASSWORD=Ch4ngeMe99
HETZNER_ACCESS_KEY=your-access-key
HETZNER_SECRET_KEY=your-secret-key
HETZNER_S3_ENDPOINT=https://fsn1.your-objectstorage.com
HETZNER_BUCKET=vaulx
Copy .env.example from the repository root and fill in your values before the first run.
Never commit SESSION_SECRET, HETZNER_ACCESS_KEY, or HETZNER_SECRET_KEY to source control. Rotate SESSION_SECRET immediately if it is ever exposed — doing so invalidates all active sessions.

Session configuration

Sessions are backed by PostgreSQL using pgstore. The store is initialised in main.go with the following options:
sessionStore.Options = &gorillasessions.Options{
    Path:     "/",
    MaxAge:   86400 * 7,
    HttpOnly: true,
    SameSite: http.SameSiteLaxMode,
    Secure:   true,
}
SettingValueNotes
MaxAge86400 * 7 (7 days)Sessions expire after one week
HttpOnlytrueCookie is not accessible via JavaScript
SameSiteLaxProtects against most CSRF vectors
SecuretrueCookie is only sent over HTTPS
Cleanup interval5 minutesExpired session rows are pruned automatically
The cleanup goroutine is started at server boot and shut down gracefully on exit:
defer sessionStore.StopCleanup(sessionStore.Cleanup(5 * time.Minute))
Secure: true means the session cookie will only be transmitted over HTTPS. In production you must terminate TLS in front of Vaulx (e.g. via a reverse proxy or Dokploy’s built-in domain/HTTPS feature). If you are testing locally over plain HTTP, log-in will appear to succeed but the session cookie will not be sent back by the browser on subsequent requests.

Storage configuration

Vaulx uses the AWS SDK for Go v2 (aws-sdk-go-v2) with a custom endpoint, which makes it compatible with any S3-compatible object store.
BackendHow to configure
Hetzner Object StorageSet HETZNER_S3_ENDPOINT to your region endpoint, e.g. https://fsn1.your-objectstorage.com
AWS S3Point HETZNER_S3_ENDPOINT to the standard AWS regional endpoint for your bucket
MinIOPoint HETZNER_S3_ENDPOINT to your MinIO server URL

Rate limiting

Vaulx uses go-chi/httprate to apply per-IP rate limits on endpoints that are either sensitive or computationally expensive. Limits are configured in main.go:
RouteMethodLimit
/auth/loginPOST10 requests per IP per minute
/s/{slug}/zip/preparePOST5 requests per IP per minute
r.With(httprate.LimitByIP(10, 1*time.Minute)).Post("/auth/login", authHandler.LoginPage)
r.With(httprate.LimitByIP(5, 1*time.Minute)).Post("/s/{slug}/zip/prepare", zipHandler.SharedPrepareZip)
Requests that exceed a limit receive 429 Too Many Requests. No configuration is needed — the limits are fixed in the source.

Database

Vaulx requires PostgreSQL 16. The connection is established via the pgx/v5 driver using the DATABASE_URL environment variable.

Automatic migrations

Migrations are embedded directly in the compiled binary using Go’s embed.FS and executed automatically at startup via golang-migrate. There is no separate migration step or CLI command — the database is always up to date when the server starts.
src, err := iofs.New(migrations.FS, ".")
m, err := migrate.NewWithInstance("iofs", src, "postgres", driver)
m.Up() // no-op if already at latest version

Session storage

The pgstore session backend creates its own http_sessions table in the same database. No additional setup is required — the table is created by pgstore on first use. Sessions are cleaned up every 5 minutes by a background goroutine.

Build docs developers (and LLMs) love