Skip to main content

Documentation Index

Fetch the complete documentation index at: https://help.draftable.com/llms.txt

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

Web Server

Application

Licensing

Compare API

Application Security

Database (PostgreSQL)

Redis

AMQP (RabbitMQ)

File Storage

HTTP Headers

X-Frame-Options (iframe embedding)

Logging

Infrastructure Services

Web server

SERVER_DNS

  • Type: String
  • Default: (empty)
  • Example: draftable.yourcompany.com
Primary domain name for the server. Used for configuring the load balancer to serve requests, SSL certificate validation, and virtual host configuration.

TLS_CERT

  • Type: String (PEM content)
  • Default: (empty)
Full PEM-encoded SSL/TLS certificate content. Paste the entire certificate including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines directly into the .env file.
The load balancer container reads certificate content from environment variables and writes it to its internal Nginx SSL paths. You must provide the actual PEM content — file paths are not supported.

TLS_KEY

  • Type: String (PEM content)
  • Default: (empty)
Full PEM-encoded SSL/TLS private key content. Paste the entire key including the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- lines directly into the .env file.

TLS_CA_CHAIN

  • Type: String (PEM content)
  • Default: (empty)
Full PEM-encoded SSL/TLS certificate authority chain. If your certificate chain includes intermediate and root CA certificates, concatenate them together in a single value. To populate your .env file from existing certificate files, you can use:
echo "TLS_CERT=\"$(cat /path/to/tls-cert.pem)\"" >> .env
echo "TLS_KEY=\"$(cat /path/to/privkey.pem)\"" >> .env
echo "TLS_CA_CHAIN=\"$(cat /path/to/tls-ca-chain.pem)\"" >> .env

Application

APP_BASE_URL

  • Type: String
  • Default: https://localhost
  • Example: https://draftable.yourcompany.com
Base URL where the application is accessible. Must include the protocol (https://) and port if non-standard. Used for generating links in API responses and the web interface.

ENV

  • Type: String
  • Default: prod
  • Valid Values: dev, prod
Environment mode for the application containers. Use prod for all production and customer deployments.

CSRF_TRUSTED_ORIGINS

  • Type: List
  • Default: Value of APP_BASE_URL
  • Example: https://draftable.yourcompany.com
List of trusted origins for CSRF validation. In most deployments, the default (derived from APP_BASE_URL) is sufficient. Set explicitly if serving from multiple origins.

APP_MODE

  • Type: String
  • Valid Values: web, web_init, celery_worker, celery_beat
Defines the role of each application container. This is set automatically in Docker Compose and should be set per-container in Kubernetes deployments. web_init runs database migrations and should complete before other containers start.

DEFAULT_FROM_EMAIL

  • Type: String
  • Default: draftable@localhost
  • Example: noreply@yourcompany.com
Default sender email address for system notifications.

Licensing

DRAFTABLE_PRODUCT_KEY

  • Type: String
  • Default: (empty)
Product key for automatic activation of Draftable API Self-hosted. If left empty, the product key can be entered in the web administration interface.
Upgrading from v2? Your existing v2 product key is fully compatible with v3. No new key is required.

Compare API

COMPARE_API_ACCOUNT_SIGNUP_ENABLED

  • Type: Boolean
  • Default: true
Allow users to create accounts through self-registration.

COMPARE_API_SOURCE_URL_ALLOW_HTTP

  • Type: Boolean
  • Default: false
Allow HTTP URLs in the source_url parameter of comparison requests.

COMPARE_API_SOURCE_URL_ALLOW_PRIVATE_IP

  • Type: Boolean
  • Default: false
Allow private IP addresses in the source_url parameter of comparison requests.

Application security

DJANGO_SECRET_KEY

  • Mandatory setting
  • Type: String
  • Default: (empty)
Secret key used for cryptographic signing by web containers. A random alphanumeric value of at least 64 characters is recommended. The secret key can be changed at any time, however, doing so will invalidate all existing login sessions forcing all users to login again.

ALLOWED_HOSTS

  • Type: List
  • Default: Value of SERVER_DNS
  • Example: draftable.yourcompany.com, www.draftable.yourcompany.com
List of hosts and domains which the application is permitted to serve. By default, the value of SERVER_DNS is automatically used.

REQUIRE_HTTPS

  • Type: Boolean
  • Default: true
Require all web requests and responses be served over HTTPS. When enabled, any HTTP requests will be redirected to the equivalent HTTPS URL. See also the configuration of the X-Forwarded-Proto HTTP header.
  • Type: Integer
  • Default: 86400
  • Valid Values: >= 0
Duration for which a session cookie (login session) is valid. The value is provided in seconds with the default of 86400 equal to one day.
  • Type: String
  • Default: Lax
  • Valid Values: Strict, Lax, None, (empty)
Value for the SameSite attribute of session cookies. Consult general online documentation for the behaviours set by the Strict, Lax, and None values. Setting an empty string will result in omitting the SameSite attribute from session cookies, which on modern web browsers is typically equivalent to the Lax setting.

Database (PostgreSQL)

PostgreSQL database connection settings. When using the default Docker Compose configuration, the built-in PostgreSQL container is used and these defaults are sufficient. For Kubernetes deployments or when connecting to an external database (e.g. Amazon RDS), you must configure these variables explicitly.

DB_HOST

  • Type: String
  • Default: pgsql
Hostname or IP address of the PostgreSQL server.
The default value pgsql corresponds to the Docker Compose service name. For Kubernetes or external database deployments, set this to your database hostname (e.g. postgres.internal or your-rds-endpoint.region.rds.amazonaws.com).

DB_PORT

  • Type: Integer
  • Default: 5432
  • Valid Range: 1–65535
Port number for the PostgreSQL server.

DB_NAME

  • Type: String
  • Default: draftable
Name of the PostgreSQL database.

DB_USER

  • Type: String
  • Default: postgres
Username for PostgreSQL authentication.

DB_PASS

  • Type: String
  • Default: password
Password for PostgreSQL authentication. Change from default in production.

DB_TLS_MODE

  • Type: String
  • Default: prefer
  • Valid Values: disable, allow, prefer, require, verify-ca, verify-full
TLS connection mode for PostgreSQL. Use require or higher for production, especially when connecting to a remote or managed database.

DB_CONN_MAX_AGE

  • Type: Integer
  • Default: -1
  • Valid Values: -1 (unlimited), 0 (no persistent connections), >0 (seconds)
Lifetime of database connections in seconds. The default of -1 enables unlimited persistent connections, which is appropriate for most deployments.

Redis

Redis is used for caching, session storage, license data, and custom font storage. When using the default Docker Compose configuration, the built-in Redis container is used and these defaults are sufficient. For Kubernetes deployments or when connecting to an external Redis instance (e.g. Amazon ElastiCache), you must configure these variables explicitly.
Redis persistence is critical. Redis stores the activated license and any custom fonts. If Redis data is lost, all users will be locked out until the license is reactivated. Always ensure Redis is configured with persistent storage (the default Docker Compose configuration includes AOF and RDB persistence). If using a managed Redis service, ensure persistence is enabled.If Redis data is lost, re-run the web_init container to reactivate the license from the DRAFTABLE_PRODUCT_KEY environment variable. In Docker Compose: docker compose run --rm web_init. You do not need to restart the entire deployment.

REDIS_HOST

  • Type: String
  • Default: redis
Hostname or IP address of the Redis server.
The default value redis corresponds to the Docker Compose service name. For Kubernetes or external Redis deployments, set this to your Redis hostname (e.g. redis.internal or your-elasticache-endpoint.region.cache.amazonaws.com).
Kubernetes naming conflict: Kubernetes automatically creates an environment variable REDIS_PORT=tcp://ip:port when a service is named redis. This conflicts with the integer port value expected by the application. To avoid this, name your Redis Kubernetes service something other than redis (e.g. redis-svc).

REDIS_PORT

  • Type: Integer
  • Default: 6379
  • Valid Range: 1–65535
Port number for the Redis server. Use 6380 for TLS connections if required by your provider.

REDIS_PASSWORD

  • Type: String
  • Default: (empty)
Password for Redis authentication. Leave empty if Redis has no authentication configured.

REDIS_USER

  • Type: String
  • Default: (empty)
Username for Redis authentication (Redis 6.0+ with ACLs). Leave empty for password-only authentication.

REDIS_TLS

  • Type: Boolean
  • Default: false
Enable TLS encryption for Redis connections. Set to true when connecting to managed Redis services that require TLS (e.g. ElastiCache in-transit encryption).

REDIS_DB

  • Type: Integer
  • Default: 0
  • Valid Range: 0–2147483646
Redis database number to use.

AMQP (RabbitMQ)

RabbitMQ is the message broker used for communication between the web application and the comparison engine. When using the default Docker Compose configuration, the built-in RabbitMQ container is used and these defaults are sufficient. For Kubernetes deployments or when connecting to an external RabbitMQ instance (e.g. Amazon MQ), you must configure these variables explicitly.

AMQP_HOST

  • Type: String
  • Default: rabbitmq
Hostname or IP address of the RabbitMQ server.
The default value rabbitmq corresponds to the Docker Compose service name. For Kubernetes or external RabbitMQ deployments, set this to your broker hostname (e.g. rabbitmq.internal or your-amazonmq-endpoint.mq.region.amazonaws.com).

AMQP_PORT

  • Type: Integer
  • Default: 5672
  • Valid Range: 1–65535
Port number for the RabbitMQ server. Use 5671 for TLS connections (e.g. Amazon MQ).

AMQP_USER

  • Type: String
  • Default: draftable
Username for RabbitMQ authentication.

AMQP_PASSWORD

  • Type: String
  • Default: draftable
Password for RabbitMQ authentication. Change from default in production.

AMQP_TLS

  • Type: Boolean
  • Default: false
Enable TLS encryption for RabbitMQ connections. Set to true when connecting to managed RabbitMQ services that require TLS (e.g. Amazon MQ).

File storage

FILE_STORAGE_TYPE

  • Type: String
  • Default: local
  • Valid Values: local, s3
Storage provider to use for storing uploaded documents and resulting comparison data.
  • local
    Data is made directly accessible to Draftable containers through the container filesystem. When using the default Docker Compose configuration a Docker volume will be created and mounted into all Draftable containers. Using a Docker volume is not generally compatible with deployments where Draftable containers span multiple servers as the underlying volume will typically not be accessible across discrete hosts.
  • s3
    Data is stored in AWS S3 buckets. This storage option is highly scalable and permits usage of Draftable containers across multiple servers due to the separation of the storage backed from compute. The AWS S3 buckets must be configured in advance. Please reach out to Draftable support for details.
Azure Blob Storage is not supported. The only supported values for FILE_STORAGE_TYPE are local and s3 (AWS S3). There is no native support for Azure Blob Storage, Azure Files, or any other Azure storage identifier. Customers deploying on Microsoft Azure infrastructure should use local storage or contact support@draftable.com to discuss their requirements.
NFS shared volumes (e.g. Azure NetApp Files) are not officially supported. While it is technically possible to use an NFS shared volume with FILE_STORAGE_TYPE=local to share the /srv/draftable mount across multiple pods (for example, in an Azure AKS deployment), Draftable does not test or optimise against NFS storage internally. Our limited testing has identified performance issues inherent to NFS that can impact comparison workloads.Customers who choose to use NFS do so at their own risk. Draftable support is unable to assist with troubleshooting issues related to NFS storage performance, reliability, or configuration. Your infrastructure team is welcome to build and optimise an NFS-based solution that works within your environment, but this falls outside the scope of Draftable’s supported deployment configurations.If you are deploying on Azure and require a supported multi-node storage solution, please contact support@draftable.com to discuss your requirements.

DRAFTABLE_API_FILE_STORAGE_ROOT

  • Type: String
  • Default: /srv/draftable/data
Path at which the comparison data will be mounted in Draftable containers when using the local storage type. Changing the default is not recommended unless directed by Draftable support for specific advanced scenarios. To enable S3 storage, the 2 environment variables must be set below:

S3_STORAGE_BUCKET

- Type: String
- Default: (empty).
Name of the bucket to use. The bucket must be configured with Cross-origin resource sharing (CORS). Below is a minimal JSON example:
[
   {
       "AllowedHeaders": [
           "*"
       ],
       "AllowedMethods": [
           "GET"
       ],
       "AllowedOrigins": [
           "*"
       ],
       "ExposeHeaders": []
   }
]

AWS_REGION

- Type: String
- Default: (empty)
AWS region name. Must match the region of the bucket.

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

AWS credentials. The user/role used to access the bucket requires the following permissions: s3:ListBucket, s3:GetObject, s3:PutObject, s3:DeleteObject Example IAM policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListBucket",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::bucket-name"
        },
        {
            "Sid": "ReadWriteObjects",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::bucket-name/*"
        }
    ]
}

HTTP headers

X-Frame-Options (iframe embedding)

Known issue (v3.0.5 and earlier): The load balancer container includes a hardcoded X-Frame-Options: DENY header on all HTTPS responses. This prevents the comparison viewer from being embedded in an iframe — a regression from v2 where iframe embedding worked without issue.Adding X_FRAME_OPTIONS to your .env file will not resolve this, as the header is set at the nginx level inside the load balancer container, not by the application.A fix will be included in a future release. In the meantime, use the workaround below.
Workaround: override the nginx configuration template
The load balancer container uses a template file at /nginx.conf.template which its entrypoint script processes on startup — substituting your SERVER_DNS value and DNS resolver — before writing the final configuration to /etc/nginx/nginx.conf. The workaround below replaces this template so that the entrypoint can still run normally.
1

Extract the nginx configuration template

Extract the template file (not the processed config) from the running container:
docker compose exec server cat /nginx.conf.template > custom-nginx.conf
2

Edit the template

Open custom-nginx.conf and find this line in the HTTPS server block:
add_header X-Frame-Options DENY always;
Change it to one of the following depending on your requirements:
  • Same-origin embedding (viewer iframe is hosted on the exact same origin as the APISH server):
    add_header X-Frame-Options SAMEORIGIN always;
    
  • Cross-origin embedding (viewer iframe is on a different domain or subdomain to the APISH server): Remove the add_header X-Frame-Options line entirely.
SAMEORIGIN requires an exact origin match (scheme + host + port). Different subdomains — for example, embedding from app.yourcompany.com when APISH is hosted at draftable.yourcompany.com — are considered cross-origin and will still be blocked by SAMEORIGIN. In this case, remove the line entirely.For more granular control, you can replace the X-Frame-Options line with a Content-Security-Policy header that specifies which origins are permitted to embed the viewer:
add_header Content-Security-Policy "frame-ancestors https://app.yourcompany.com https://draftable.yourcompany.com" always;
You can also use wildcards (e.g. https://*.yourcompany.com). See the MDN Content-Security-Policy frame-ancestors documentation for full syntax.
Do not change the SERVER_NAME_PLACEHOLDER or RESOLVER_PLACEHOLDER tokens in the file. These are replaced automatically by the container’s entrypoint script on startup.
3

Mount the custom template

Add a volume mount to the server service in your docker-compose.yml, mapping your custom file to /nginx.conf.template:
server:
  image: draftable/apish-load-balancer:latest
  volumes:
    - ./custom-nginx.conf:/nginx.conf.template:ro
  # ... keep your existing configuration below
4

Restart the stack

docker compose down
docker compose up -d
5

Verify the fix

Open your browser’s developer tools, load the comparison viewer URL, and confirm the X-Frame-Options response header now shows SAMEORIGIN (or is absent if you removed the line).

Cross-Origin Resource Sharing (CORS)

CORS_ENABLED

  • Type: Boolean
  • Default: false
Enable including CORS headers in API Self-hosted responses to HTTP(S) requests.

CORS_ALLOWED_ORIGINS

  • Type: List
  • Default: (empty)
  • Example: https://app.yourcompany.com, https://api.yourcompany.com
List of origins permitted to make cross-origin requests.

CORS_ALLOWED_ORIGIN_REGEXES

  • Type: List
  • Default: (empty)
  • Example: https://.*\.yourcompany\.com
List of regular expression patterns for which matches are permitted to make cross-origin requests.

CORS_ALLOW_ALL_ORIGINS

  • Type: Boolean
  • Default: false
Permit requests from any origin. Enabling this behaviour can be a security risk and should be carefully evaluated.

Cross-Site Request Forgery (CSRF) protection

  • Type: String
  • Default: Strict
  • Valid Values: Strict, Lax, None, (empty)
Value for the SameSite attribute of CSRF cookies. Consult general online documentation for the behaviours set by the Strict, Lax, and None values. Setting an empty string will result in omitting the SameSite attribute from CSRF cookies, which on modern web browsers is typically equivalent to the Lax setting.

HTTP Strict Transport Security (HSTS)

SECURE_HSTS_SECONDS

  • Type: Integer
  • Default: 0
  • Valid Values: >= 0
Number of seconds for which the HSTS policy will be enforced when received by a web browser. The configured value is set in the max-age attribute of the HSTS header. The default of zero disables the HSTS header, while for production deployments a value of two years (63072000) is recommended.

SECURE_HSTS_INCLUDE_SUBDOMAINS

  • Type: Boolean
  • Default: false
Enables applying the HSTS policy to all subdomains of the API Self-hosted domain. When enabled, sets the includeSubDomains attribute in the HSTS header.

SECURE_HSTS_PRELOAD

  • Type: Boolean
  • Default: false
  • Required: Optional
Enables inclusion of the HSTS policy in the preload list maintained by Google. When enabled, sets the preload attribute in the HSTS header, indicating that the API Self-hosted domain may be included in the preload list, which is used by all major web browsers. To take effect the SECURE_HSTS_SECONDS value must be at least one year (31536000) and SECURE_HSTS_INCLUDE_SUBDOMAINS must be enabled. There are additional requirements for inclusion in the preload list; see the submission requirements for full details.

X-Forwarded-Proto

SECURE_PROXY_SSL_HEADER_ENABLED

  • Type: Boolean
  • Default: true
Enables setting the X-Forwarded-Proto header on requests sent from the load balancer to web containers and configures the API Self-hosted application to respect the header. If HTTPS support is enabled via the REQUIRE_HTTPS setting (the default) then the X-Forwarded-Proto header will be implicitly enabled irrespective of the value of this setting.

SECURE_PROXY_SSL_HEADER_NAME

  • Type: String
  • Default: HTTP_X_FORWARDED_PROTO
The name of the header used to communicate the protocol used by the client which originated the request.

SECURE_PROXY_SSL_HEADER_VALUE

  • Type: String
  • Default: https
The value of the header which indicates that the originating client request is secure.

Logging

Configuration of logging functionality and minimum logging severity levels of components. Changing logging severity levels from the defaults is not recommended unless directed by Draftable support.

CONSOLE_LOG_LEVEL

  • Type: String
  • Default: WARNING
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for outputting logs to the console.

AWS_LOG_LEVEL

  • Type: String
  • Default: INFO
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for logs from Amazon Web Services (AWS) libraries.

CELERY_LOG_LEVEL

  • Type: String
  • Default: INFO
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for logs from the Celery distributed task queue.

DJANGO_LOG_LEVEL

  • Type: String
  • Default: INFO
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for logs from the Django web application framework.

DRAFTABLE_LOG_LEVEL

  • Type: String
  • Default: INFO
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for logs from Draftable components.

GUNICORN_LOG_LEVEL

  • Type: String
  • Default: INFO
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for logs from the Gunicorn WSGI HTTP server.

MISC_LOG_LEVEL

  • Type: String
  • Default: INFO
  • Valid Values: CRITICAL, ERROR, WARNING, INFO, DEBUG
Minimum severity level for logs from components not covered by a specific LOG_LEVEL setting.

CONSOLE_LOG_TIMESTAMP_ENABLED

  • Type: Boolean
  • Default: true
Prepend a timestamp for logs output to the console. When collecting console logs via a log aggregation system that adds its own timestamps to the processed events you may wish to disable this behaviour to avoid duplication of timestamps.

Infrastructure services

These environment variables configure supporting infrastructure services and the document processing pipeline.

JODCONVERTER_URL

  • Type: String
  • Default: http://converter:8080/lool/convert-to/pdf
URL for the JODConverter service used for document format conversion (e.g. Office to PDF). The default value uses the Docker Compose service name. For Kubernetes deployments, update this to match your converter service name and namespace (e.g. http://converter-svc.draftable.svc.cluster.local:8080/lool/convert-to/pdf).

COMPARE_WORKERS_COUNT

  • Type: Integer
  • Default: 1
  • Valid Range: 1–10
Number of comparison worker processes within the compare container. Increase for higher throughput on multi-core systems. In Kubernetes, you can also scale horizontally by increasing the number of compare pod replicas.

HTTP_PORT

  • Type: Integer
  • Default: 80
HTTP port exposed by the load balancer container. Only applicable to Docker Compose deployments.

HTTPS_PORT

  • Type: Integer
  • Default: 443
HTTPS port exposed by the load balancer container. Only applicable to Docker Compose deployments.