Skip to content

Configuration

Configuring your self hosted Papra allows you to customize the application to better suit your environment and requirements. This guide covers the key environment variables you can set to control various aspects of the application, including port settings, security options, and storage configurations.

Configuration files

You can configure Papra using standard environment variables or use some configuration files. Papra uses c12 to load configuration files and figue to validate and merge environment variables and configuration files.

The c12 allows you to use the file format you want. The configuration file should be named papra.config.[ext] and should be located in the root of the project or in /app/app-data/ directory in docker container (it can be changed using PAPRA_CONFIG_DIR environment variable).

The supported formats are: json, jsonc, json5, yaml, yml, toml, js, ts, cjs, mjs.

Example of configuration files:

server:
baseUrl: https://papra.example.com
corsOrigins: *
client:
baseUrl: https://papra.example.com
auth:
secret: your-secret-key
isRegistrationEnabled: true
# ...

You’ll find the complete list of configuration variables with their environment variables equivalents and path for files in the next section.

Complete .env

Here is the full configuration file that you can use to configure Papra. The variables values are the default values.

.env
# The URL of the client.
# CLIENT_BASE_URL=http://localhost:3000
# The URL to redirect to after OAuth.
# CLIENT_OAUTH_REDIRECT_URL=http://localhost:3000/confirm
# The base URL of the server.
# SERVER_BASE_URL=http://localhost:1221
# A comma separated list of origins that are trusted to make requests to the
# server. The client baseUrl (CLIENT_BASE_URL) is automatically added by
# default, no need to add it to the list.
# TRUSTED_ORIGINS=
# The port to listen on when using node server.
# PORT=1221
# The maximum time in milliseconds for a route to complete before timing out.
# SERVER_API_ROUTES_TIMEOUT_MS=20000
# The CORS origin for the api server.
# SERVER_CORS_ORIGINS=http://localhost:3000
# Whether to serve the public directory (default as true when using docker).
# SERVER_SERVE_PUBLIC_DIR=false
# The URL of the database (default as "file:./app-data/db/db.sqlite" when
# using docker).
# DATABASE_URL=file:./db.sqlite
# The auth token for the database.
# DATABASE_AUTH_TOKEN=
# The encryption key for the database. If not provided, the database will not
# be encrypted. Use with caution as if lost, the data will be unrecoverable.
# DATABASE_ENCRYPTION_KEY=
# The retention period in days for deleted documents.
# DOCUMENTS_DELETED_DOCUMENTS_RETENTION_DAYS=30
# The maximum size in bytes for an uploaded file. Set to 0 to disable the
# limit and allow uploading documents of any size.
# DOCUMENT_STORAGE_MAX_UPLOAD_SIZE=10485760
# The driver to use for document storage, values can be one of: `filesystem`,
# `s3`, `in-memory`.
# DOCUMENT_STORAGE_DRIVER=filesystem
# The root directory to store documents in (default as "./app-data/documents"
# when using docker).
# DOCUMENT_STORAGE_FILESYSTEM_ROOT=./local-documents
# The AWS access key ID for S3.
# DOCUMENT_STORAGE_S3_ACCESS_KEY_ID=
# The AWS secret access key for S3.
# DOCUMENT_STORAGE_S3_SECRET_ACCESS_KEY=
# The S3 bucket name.
# DOCUMENT_STORAGE_S3_BUCKET_NAME=
# The AWS region for S3.
# DOCUMENT_STORAGE_S3_REGION=auto
# The S3 endpoint.
# DOCUMENT_STORAGE_S3_ENDPOINT=
# The secret for the auth.
# AUTH_SECRET=change-me-for-god-sake
# Whether registration is enabled.
# AUTH_IS_REGISTRATION_ENABLED=true
# Whether password reset is enabled.
# AUTH_IS_PASSWORD_RESET_ENABLED=true
# Whether email verification is required.
# AUTH_IS_EMAIL_VERIFICATION_REQUIRED=false
# Whether to show Papra legal links on the auth pages (terms of service,
# privacy policy), useless for self-hosted instances.
# AUTH_SHOW_LEGAL_LINKS=false
# Whether Github OAuth is enabled.
# AUTH_PROVIDERS_GITHUB_IS_ENABLED=false
# The client id for Github OAuth.
# AUTH_PROVIDERS_GITHUB_CLIENT_ID=set-me
# The client secret for Github OAuth.
# AUTH_PROVIDERS_GITHUB_CLIENT_SECRET=set-me
# Whether Google OAuth is enabled.
# AUTH_PROVIDERS_GOOGLE_IS_ENABLED=false
# The client id for Google OAuth.
# AUTH_PROVIDERS_GOOGLE_CLIENT_ID=set-me
# The client secret for Google OAuth.
# AUTH_PROVIDERS_GOOGLE_CLIENT_SECRET=set-me
# Whether the task to hard delete expired "soft deleted" documents is
# enabled.
# DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_ENABLED=true
# The cron schedule for the task to hard delete expired "soft deleted"
# documents.
# DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_CRON=0 0 * * *
# Whether the task to hard delete expired "soft deleted" documents should run
# on startup.
# DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_RUN_ON_STARTUP=true
# Whether intake emails are enabled.
# INTAKE_EMAILS_IS_ENABLED=false
# The driver to use when generating email addresses for intake emails, value
# can be one of: `random-username`, `owlrelay`.
# INTAKE_EMAILS_DRIVER=random-username
# The secret to use when verifying webhooks.
# INTAKE_EMAILS_WEBHOOK_SECRET=change-me
# The domain to use when generating email addresses for intake emails when
# using the random username driver.
# INTAKE_EMAILS_EMAIL_GENERATION_DOMAIN=papra.email
# The API key used to interact with OwlRelay for the intake emails.
# OWLRELAY_API_KEY=change-me
# The webhook URL to use when generating email addresses for intake emails
# with OwlRelay, if not provided, the webhook will be inferred from the
# server URL.
# OWLRELAY_WEBHOOK_URL=
# The API key for Resend (use to send emails).
# RESEND_API_KEY=set-me
# The email address to send emails from.
# EMAILS_FROM_ADDRESS=Papra <[email protected]>
# Whether to run the email service in dry run mode.
# EMAILS_DRY_RUN=false
# The maximum number of organizations a standard user can have.
# MAX_ORGANIZATION_COUNT_PER_USER=10
# Whether the free plan is unlimited, meaning it has no limits on the number
# of documents, tags, and organizations, basically always true for
# self-hosted instances.
# IS_FREE_PLAN_UNLIMITED=true
# The price id of the plus plan (useless for self-hosting).
# PLANS_PLUS_PLAN_PRICE_ID=change-me
# The price id of the family plan (useless for self-hosting).
# PLANS_FAMILY_PLAN_PRICE_ID=change-me
# The API secret key for the Stripe (useless for self-hosting).
# STRIPE_API_SECRET_KEY=change-me
# The secret for the Stripe webhook (useless for self-hosting).
# STRIPE_WEBHOOK_SECRET=change-me
# Whether to enable PostHog.
# POSTHOG_ENABLED=false
# The API key for PostHog.
# POSTHOG_API_KEY=set-me
# The host for PostHog.
# POSTHOG_HOST=https://eu.i.posthog.com

Configuration variables

Here is the complete list of configuration variables that you can use to configure Papra. You can set these variables in the .env file or pass them as environment variables when running the Docker container.

CLIENT_BASE_URL

The URL of the client.

  • Path: client.baseUrl
  • Environment variable: CLIENT_BASE_URL
  • Default value: http://localhost:3000

CLIENT_OAUTH_REDIRECT_URL

The URL to redirect to after OAuth.

  • Path: client.oauthRedirectUrl
  • Environment variable: CLIENT_OAUTH_REDIRECT_URL
  • Default value: http://localhost:3000/confirm

SERVER_BASE_URL

The base URL of the server.

  • Path: server.baseUrl
  • Environment variable: SERVER_BASE_URL
  • Default value: http://localhost:1221

TRUSTED_ORIGINS

A comma separated list of origins that are trusted to make requests to the server. The client baseUrl (CLIENT_BASE_URL) is automatically added by default, no need to add it to the list.

  • Path: server.trustedOrigins
  • Environment variable: TRUSTED_ORIGINS
  • Default value: undefined

PORT

The port to listen on when using node server.

  • Path: server.port
  • Environment variable: PORT
  • Default value: 1221

SERVER_API_ROUTES_TIMEOUT_MS

The maximum time in milliseconds for a route to complete before timing out.

  • Path: server.routeTimeoutMs
  • Environment variable: SERVER_API_ROUTES_TIMEOUT_MS
  • Default value: 20000

SERVER_CORS_ORIGINS

The CORS origin for the api server.

  • Path: server.corsOrigins
  • Environment variable: SERVER_CORS_ORIGINS
  • Default value: http://localhost:3000

SERVER_SERVE_PUBLIC_DIR

Whether to serve the public directory (default as true when using docker).

  • Path: server.servePublicDir
  • Environment variable: SERVER_SERVE_PUBLIC_DIR
  • Default value: false

DATABASE_URL

The URL of the database (default as "file:./app-data/db/db.sqlite" when using docker).

  • Path: database.url
  • Environment variable: DATABASE_URL
  • Default value: file:./db.sqlite

DATABASE_AUTH_TOKEN

The auth token for the database.

  • Path: database.authToken
  • Environment variable: DATABASE_AUTH_TOKEN
  • Default value: undefined

DATABASE_ENCRYPTION_KEY

The encryption key for the database. If not provided, the database will not be encrypted. Use with caution as if lost, the data will be unrecoverable.

  • Path: database.encryptionKey
  • Environment variable: DATABASE_ENCRYPTION_KEY
  • Default value: undefined

DOCUMENTS_DELETED_DOCUMENTS_RETENTION_DAYS

The retention period in days for deleted documents.

  • Path: documents.deletedDocumentsRetentionDays
  • Environment variable: DOCUMENTS_DELETED_DOCUMENTS_RETENTION_DAYS
  • Default value: 30

DOCUMENT_STORAGE_MAX_UPLOAD_SIZE

The maximum size in bytes for an uploaded file. Set to 0 to disable the limit and allow uploading documents of any size.

  • Path: documentsStorage.maxUploadSize
  • Environment variable: DOCUMENT_STORAGE_MAX_UPLOAD_SIZE
  • Default value: 10485760

DOCUMENT_STORAGE_DRIVER

The driver to use for document storage, values can be one of: filesystem, s3, in-memory.

  • Path: documentsStorage.driver
  • Environment variable: DOCUMENT_STORAGE_DRIVER
  • Default value: filesystem

DOCUMENT_STORAGE_FILESYSTEM_ROOT

The root directory to store documents in (default as "./app-data/documents" when using docker).

  • Path: documentsStorage.drivers.filesystem.root
  • Environment variable: DOCUMENT_STORAGE_FILESYSTEM_ROOT
  • Default value: ./local-documents

DOCUMENT_STORAGE_S3_ACCESS_KEY_ID

The AWS access key ID for S3.

  • Path: documentsStorage.drivers.s3.accessKeyId
  • Environment variable: DOCUMENT_STORAGE_S3_ACCESS_KEY_ID
  • Default value: undefined

DOCUMENT_STORAGE_S3_SECRET_ACCESS_KEY

The AWS secret access key for S3.

  • Path: documentsStorage.drivers.s3.secretAccessKey
  • Environment variable: DOCUMENT_STORAGE_S3_SECRET_ACCESS_KEY
  • Default value: undefined

DOCUMENT_STORAGE_S3_BUCKET_NAME

The S3 bucket name.

  • Path: documentsStorage.drivers.s3.bucketName
  • Environment variable: DOCUMENT_STORAGE_S3_BUCKET_NAME
  • Default value: undefined

DOCUMENT_STORAGE_S3_REGION

The AWS region for S3.

  • Path: documentsStorage.drivers.s3.region
  • Environment variable: DOCUMENT_STORAGE_S3_REGION
  • Default value: auto

DOCUMENT_STORAGE_S3_ENDPOINT

The S3 endpoint.

  • Path: documentsStorage.drivers.s3.endpoint
  • Environment variable: DOCUMENT_STORAGE_S3_ENDPOINT
  • Default value: undefined

AUTH_SECRET

The secret for the auth.

  • Path: auth.secret
  • Environment variable: AUTH_SECRET
  • Default value: change-me-for-god-sake

AUTH_IS_REGISTRATION_ENABLED

Whether registration is enabled.

  • Path: auth.isRegistrationEnabled
  • Environment variable: AUTH_IS_REGISTRATION_ENABLED
  • Default value: true

AUTH_IS_PASSWORD_RESET_ENABLED

Whether password reset is enabled.

  • Path: auth.isPasswordResetEnabled
  • Environment variable: AUTH_IS_PASSWORD_RESET_ENABLED
  • Default value: true

AUTH_IS_EMAIL_VERIFICATION_REQUIRED

Whether email verification is required.

  • Path: auth.isEmailVerificationRequired
  • Environment variable: AUTH_IS_EMAIL_VERIFICATION_REQUIRED
  • Default value: false

AUTH_SHOW_LEGAL_LINKS

Whether to show Papra legal links on the auth pages (terms of service, privacy policy), useless for self-hosted instances.

  • Path: auth.showLegalLinksOnAuthPage
  • Environment variable: AUTH_SHOW_LEGAL_LINKS
  • Default value: false

AUTH_PROVIDERS_GITHUB_IS_ENABLED

Whether Github OAuth is enabled.

  • Path: auth.providers.github.isEnabled
  • Environment variable: AUTH_PROVIDERS_GITHUB_IS_ENABLED
  • Default value: false

AUTH_PROVIDERS_GITHUB_CLIENT_ID

The client id for Github OAuth.

  • Path: auth.providers.github.clientId
  • Environment variable: AUTH_PROVIDERS_GITHUB_CLIENT_ID
  • Default value: set-me

AUTH_PROVIDERS_GITHUB_CLIENT_SECRET

The client secret for Github OAuth.

  • Path: auth.providers.github.clientSecret
  • Environment variable: AUTH_PROVIDERS_GITHUB_CLIENT_SECRET
  • Default value: set-me

AUTH_PROVIDERS_GOOGLE_IS_ENABLED

Whether Google OAuth is enabled.

  • Path: auth.providers.google.isEnabled
  • Environment variable: AUTH_PROVIDERS_GOOGLE_IS_ENABLED
  • Default value: false

AUTH_PROVIDERS_GOOGLE_CLIENT_ID

The client id for Google OAuth.

  • Path: auth.providers.google.clientId
  • Environment variable: AUTH_PROVIDERS_GOOGLE_CLIENT_ID
  • Default value: set-me

AUTH_PROVIDERS_GOOGLE_CLIENT_SECRET

The client secret for Google OAuth.

  • Path: auth.providers.google.clientSecret
  • Environment variable: AUTH_PROVIDERS_GOOGLE_CLIENT_SECRET
  • Default value: set-me

DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_ENABLED

Whether the task to hard delete expired "soft deleted" documents is enabled.

  • Path: tasks.hardDeleteExpiredDocuments.enabled
  • Environment variable: DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_ENABLED
  • Default value: true

DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_CRON

The cron schedule for the task to hard delete expired "soft deleted" documents.

  • Path: tasks.hardDeleteExpiredDocuments.cron
  • Environment variable: DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_CRON
  • Default value: 0 0 * * *

DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_RUN_ON_STARTUP

Whether the task to hard delete expired "soft deleted" documents should run on startup.

  • Path: tasks.hardDeleteExpiredDocuments.runOnStartup
  • Environment variable: DOCUMENTS_HARD_DELETE_EXPIRED_DOCUMENTS_RUN_ON_STARTUP
  • Default value: true

INTAKE_EMAILS_IS_ENABLED

Whether intake emails are enabled.

  • Path: intakeEmails.isEnabled
  • Environment variable: INTAKE_EMAILS_IS_ENABLED
  • Default value: false

INTAKE_EMAILS_DRIVER

The driver to use when generating email addresses for intake emails, value can be one of: random-username, owlrelay.

  • Path: intakeEmails.driver
  • Environment variable: INTAKE_EMAILS_DRIVER
  • Default value: random-username

INTAKE_EMAILS_WEBHOOK_SECRET

The secret to use when verifying webhooks.

  • Path: intakeEmails.webhookSecret
  • Environment variable: INTAKE_EMAILS_WEBHOOK_SECRET
  • Default value: change-me

INTAKE_EMAILS_EMAIL_GENERATION_DOMAIN

The domain to use when generating email addresses for intake emails when using the random username driver.

  • Path: intakeEmails.drivers.randomUsername.domain
  • Environment variable: INTAKE_EMAILS_EMAIL_GENERATION_DOMAIN
  • Default value: papra.email

OWLRELAY_API_KEY

The API key used to interact with OwlRelay for the intake emails.

  • Path: intakeEmails.drivers.owlrelay.owlrelayApiKey
  • Environment variable: OWLRELAY_API_KEY
  • Default value: change-me

OWLRELAY_WEBHOOK_URL

The webhook URL to use when generating email addresses for intake emails with OwlRelay, if not provided, the webhook will be inferred from the server URL.

  • Path: intakeEmails.drivers.owlrelay.webhookUrl
  • Environment variable: OWLRELAY_WEBHOOK_URL
  • Default value: undefined

RESEND_API_KEY

The API key for Resend (use to send emails).

  • Path: emails.resendApiKey
  • Environment variable: RESEND_API_KEY
  • Default value: set-me

EMAILS_FROM_ADDRESS

The email address to send emails from.

  • Path: emails.fromEmail
  • Environment variable: EMAILS_FROM_ADDRESS
  • Default value: Papra <[email protected]>

EMAILS_DRY_RUN

Whether to run the email service in dry run mode.

  • Path: emails.dryRun
  • Environment variable: EMAILS_DRY_RUN
  • Default value: false

MAX_ORGANIZATION_COUNT_PER_USER

The maximum number of organizations a standard user can have.

  • Path: organizations.maxOrganizationCount
  • Environment variable: MAX_ORGANIZATION_COUNT_PER_USER
  • Default value: 10

IS_FREE_PLAN_UNLIMITED

Whether the free plan is unlimited, meaning it has no limits on the number of documents, tags, and organizations, basically always true for self-hosted instances.

  • Path: organizationPlans.isFreePlanUnlimited
  • Environment variable: IS_FREE_PLAN_UNLIMITED
  • Default value: true

PLANS_PLUS_PLAN_PRICE_ID

The price id of the plus plan (useless for self-hosting).

  • Path: organizationPlans.plusPlanPriceId
  • Environment variable: PLANS_PLUS_PLAN_PRICE_ID
  • Default value: change-me

PLANS_FAMILY_PLAN_PRICE_ID

The price id of the family plan (useless for self-hosting).

  • Path: organizationPlans.familyPlanPriceId
  • Environment variable: PLANS_FAMILY_PLAN_PRICE_ID
  • Default value: change-me

STRIPE_API_SECRET_KEY

The API secret key for the Stripe (useless for self-hosting).

  • Path: subscriptions.stripeApiSecretKey
  • Environment variable: STRIPE_API_SECRET_KEY
  • Default value: change-me

STRIPE_WEBHOOK_SECRET

The secret for the Stripe webhook (useless for self-hosting).

  • Path: subscriptions.stripeWebhookSecret
  • Environment variable: STRIPE_WEBHOOK_SECRET
  • Default value: change-me

POSTHOG_ENABLED

Whether to enable PostHog.

  • Path: tracking.posthog.isEnabled
  • Environment variable: POSTHOG_ENABLED
  • Default value: false

POSTHOG_API_KEY

The API key for PostHog.

  • Path: tracking.posthog.apiKey
  • Environment variable: POSTHOG_API_KEY
  • Default value: set-me

POSTHOG_HOST

The host for PostHog.

  • Path: tracking.posthog.host
  • Environment variable: POSTHOG_HOST
  • Default value: https://eu.i.posthog.com