Skip to content

Deploying Directus

Introduction

Directus is a powerful open-source data platform and headless CMS that wraps your database with an intuitive admin interface and RESTful API. It provides a flexible content management solution that works with your existing SQL database, making it perfect for modern applications that need dynamic content management with complete control over your data structure.

This comprehensive guide shows you how to deploy Directus on Klutch.sh using Docker, configure persistent storage for uploads and database files, set up environment variables for production, and follow best practices for a secure, scalable deployment. Whether you’re building a content-driven website, mobile app backend, or data management platform, this guide will help you get Directus running reliably on Klutch.sh.


Prerequisites

  • A Klutch.sh account
  • A GitHub repository for your Directus deployment
  • Basic familiarity with Docker, databases, and environment variables
  • (Recommended for production) A PostgreSQL or MySQL database instance

Getting Started: Understanding Directus

Directus is designed to work with your existing SQL database and provides:

  • Intuitive Admin Interface: A modern UI for managing content and data
  • RESTful & GraphQL APIs: Automatic API generation from your database schema
  • File Management: Built-in asset storage with transformations
  • Role-Based Access Control: Granular permissions for users and teams
  • Extensibility: Custom endpoints, hooks, and interfaces

Quick Installation Overview

Directus runs as a Node.js application that connects to your database. For Klutch.sh deployment, you’ll:

  1. Create a Dockerfile with Directus
  2. Configure database connection and storage
  3. Set up persistent volumes for uploads
  4. Deploy through the Klutch.sh dashboard

Sample Dockerfile

Klutch.sh automatically detects a Dockerfile in your repository root. Here’s a production-ready Dockerfile for Directus:

FROM directus/directus:11
# Set working directory
WORKDIR /directus
# Environment defaults (override these in Klutch.sh)
ENV PORT=8055
ENV PUBLIC_URL="https://example-app.klutch.sh"
# Expose the Directus port
EXPOSE 8055
# Health check to ensure Directus is running
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8055/server/health || exit 1
# Start Directus
CMD ["node", "cli.js", "start"]

Alternative: Custom Build Dockerfile

If you need to install extensions or customize the build:

FROM node:20-alpine
# Install dependencies
RUN apk add --no-cache \
bash \
git \
curl
# Set working directory
WORKDIR /directus
# Install Directus
RUN npm install -g directus@11
# Create directories for uploads and extensions
RUN mkdir -p /directus/uploads /directus/extensions
# Expose port
EXPOSE 8055
# Start command
CMD ["directus", "start"]

Deploying Directus on Klutch.sh

    1. Prepare Your Repository

    Create a new GitHub repository for your Directus deployment:

    Terminal window
    mkdir directus-klutch
    cd directus-klutch
    git init

    Add the Dockerfile (from above) to your repository root:

    Terminal window
    # Create Dockerfile
    cat > Dockerfile << 'EOF'
    FROM directus/directus:11
    WORKDIR /directus
    ENV PORT=8055
    ENV PUBLIC_URL="https://example-app.klutch.sh"
    EXPOSE 8055
    HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
    CMD node -e "require('http').get('http://localhost:8055/server/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
    CMD ["node", "cli.js", "start"]
    EOF
    # Initialize and push to GitHub
    git add Dockerfile
    git commit -m "Add Directus Dockerfile"
    git branch -M main
    git remote add origin https://github.com/yourusername/directus-klutch.git
    git push -u origin main

    2. Create a New App on Klutch.sh

    Navigate to the Klutch.sh dashboard:

    • Click “Create New App”
    • Select your GitHub repository
    • Choose the main branch
    • Klutch.sh will automatically detect your Dockerfile

    3. Configure Network Settings

    In the app configuration:

    • Traffic Type: Select HTTP (Directus serves web traffic)
    • Internal Port: Set to 8055 (Directus default port)

    4. Set Up Persistent Storage

    Directus needs persistent storage for uploaded files. In the Klutch.sh dashboard:

    • Navigate to the “Volumes” section
    • Click “Add Volume”
    • Mount Path: /directus/uploads
    • Size: Choose based on your storage needs (start with 10GB)

    For database persistence (if using SQLite for testing):

    • Add another volume
    • Mount Path: /directus/database
    • Size: 5GB

    5. Configure Environment Variables

    In the Klutch.sh dashboard, add these environment variables:

    Required Variables:

    Terminal window
    KEY=your-random-secret-key-min-32-chars
    SECRET=your-random-secret-min-32-chars
    PUBLIC_URL=https://your-app.klutch.sh

    Generate secure keys with:

    Terminal window
    openssl rand -base64 32
    Terminal window
    DB_CLIENT=pg
    DB_HOST=your-postgres-host
    DB_PORT=5432
    DB_DATABASE=directus
    DB_USER=directus_user
    DB_PASSWORD=your-secure-password

    Database Configuration (MySQL):

    Terminal window
    DB_CLIENT=mysql
    DB_HOST=your-mysql-host
    DB_PORT=3306
    DB_DATABASE=directus
    DB_USER=directus_user
    DB_PASSWORD=your-secure-password

    Database Configuration (SQLite - For Testing Only):

    Terminal window
    DB_CLIENT=sqlite3
    DB_FILENAME=/directus/database/data.db
    Terminal window
    # Admin user (created on first startup)
    ADMIN_EMAIL=admin@example.com
    ADMIN_PASSWORD=your-secure-admin-password
    # File storage configuration
    STORAGE_LOCATIONS=local
    STORAGE_LOCAL_ROOT=/directus/uploads
    # Email configuration (for password resets, etc.)
    EMAIL_FROM=noreply@example.com
    EMAIL_TRANSPORT=smtp
    EMAIL_SMTP_HOST=smtp.example.com
    EMAIL_SMTP_PORT=587
    EMAIL_SMTP_USER=your-smtp-user
    EMAIL_SMTP_PASSWORD=your-smtp-password
    # Cache configuration (optional)
    CACHE_ENABLED=true
    CACHE_TTL=30m
    # Rate limiting
    RATE_LIMITER_ENABLED=true
    RATE_LIMITER_POINTS=50
    RATE_LIMITER_DURATION=1
    # CORS settings
    CORS_ENABLED=true
    CORS_ORIGIN=true

    6. Deploy Your Application

    • Review your configuration
    • Click “Create” to deploy
    • Klutch.sh will build your Docker image and start the container
    • Your Directus instance will be available at https://your-app.klutch.sh

    7. Initial Setup

    Once deployed:

    • Navigate to your app URL
    • Log in with the admin credentials you configured (or create an admin user if not set)
    • Configure your data model and collections
    • Set up user roles and permissions

Database Setup and Configuration

PostgreSQL is the recommended database for production Directus deployments. It offers excellent performance, reliability, and feature support.

Setup Steps:

  1. Provision a PostgreSQL database (either on Klutch.sh or an external provider)
  2. Create a dedicated database and user:
CREATE DATABASE directus;
CREATE USER directus_user WITH ENCRYPTED PASSWORD 'your-secure-password';
GRANT ALL PRIVILEGES ON DATABASE directus TO directus_user;
  1. Configure the environment variables as shown in the deployment section
  2. Directus will automatically create the necessary tables on first startup

MySQL/MariaDB

MySQL and MariaDB are also well-supported:

CREATE DATABASE directus;
CREATE USER 'directus_user'@'%' IDENTIFIED BY 'your-secure-password';
GRANT ALL PRIVILEGES ON directus.* TO 'directus_user'@'%';
FLUSH PRIVILEGES;

SQLite (Development Only)

SQLite is suitable for testing and development but not recommended for production:

  • No separate database server needed
  • File-based storage
  • Limited concurrent write performance
  • Requires persistent volume for the database file

Persistent Storage Configuration

File Uploads Storage

Directus stores uploaded files in the /directus/uploads directory by default. This must be mounted to a persistent volume:

In Klutch.sh Dashboard:

  • Mount Path: /directus/uploads
  • Recommended Size: 20GB+ (depending on expected usage)

Database Storage (SQLite Only)

If using SQLite for development:

  • Mount Path: /directus/database
  • Recommended Size: 5GB

Extensions and Custom Code

For custom extensions:

  • Mount Path: /directus/extensions
  • Size: 1GB

Environment Variables Reference

Core Settings

VariableDescriptionRequiredDefault
KEYSecurity key for encryptionYes-
SECRETSecret for JWT tokensYes-
PUBLIC_URLPublic URL of your instanceYes-
PORTPort Directus listens onNo8055

Database Settings

VariableDescriptionRequiredExample
DB_CLIENTDatabase typeYespg, mysql, sqlite3
DB_HOSTDatabase hostYes*postgres.example.com
DB_PORTDatabase portYes*5432
DB_DATABASEDatabase nameYesdirectus
DB_USERDatabase userYes*directus_user
DB_PASSWORDDatabase passwordYes*-

*Not required for SQLite

Storage Settings

VariableDescriptionDefault
STORAGE_LOCATIONSStorage driver to uselocal
STORAGE_LOCAL_ROOTLocal storage path./uploads

Security Settings

VariableDescriptionDefault
ACCESS_TOKEN_TTLAccess token lifetime15m
REFRESH_TOKEN_TTLRefresh token lifetime7d
RATE_LIMITER_ENABLEDEnable rate limitingfalse
RATE_LIMITER_POINTSRequests per duration50
RATE_LIMITER_DURATIONDuration in seconds1

Sample Code: Environment Configuration

Create a .env.example file in your repository as a template:

Terminal window
# Core Configuration
KEY=generate-with-openssl-rand-base64-32
SECRET=generate-with-openssl-rand-base64-32
PUBLIC_URL=https://your-app.klutch.sh
# Database Configuration (PostgreSQL)
DB_CLIENT=pg
DB_HOST=your-postgres-host.klutch.sh
DB_PORT=5432
DB_DATABASE=directus
DB_USER=directus_user
DB_PASSWORD=your-secure-password
# Admin User (Created on First Startup)
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=your-secure-admin-password
# File Storage
STORAGE_LOCATIONS=local
STORAGE_LOCAL_ROOT=/directus/uploads
# Email Configuration
EMAIL_FROM=noreply@example.com
EMAIL_TRANSPORT=smtp
EMAIL_SMTP_HOST=smtp.sendgrid.net
EMAIL_SMTP_PORT=587
EMAIL_SMTP_USER=apikey
EMAIL_SMTP_PASSWORD=your-sendgrid-api-key
EMAIL_SMTP_SECURE=false
# Performance
CACHE_ENABLED=true
CACHE_TTL=30m
# Security
RATE_LIMITER_ENABLED=true
RATE_LIMITER_POINTS=50
RATE_LIMITER_DURATION=1
# CORS
CORS_ENABLED=true
CORS_ORIGIN=true
CORS_METHODS=GET,POST,PATCH,DELETE
CORS_ALLOWED_HEADERS=Content-Type,Authorization
# Logging
LOG_LEVEL=info
LOG_STYLE=pretty

Production Best Practices

Security

  • Use Strong Keys: Generate random keys with openssl rand -base64 32
  • Enable HTTPS: Klutch.sh provides automatic TLS for all deployments
  • Configure CORS: Restrict API access to trusted domains
  • Enable Rate Limiting: Protect against brute force attacks
  • Regular Backups: Back up both database and uploaded files
  • Keep Updated: Regularly update to the latest Directus version

Performance

  • Use PostgreSQL: Best performance for production workloads
  • Enable Caching: Reduces database load and improves response times
  • Optimize Images: Use Directus image transformations instead of storing multiple sizes
  • Monitor Resources: Use Klutch.sh monitoring to track CPU and memory usage
  • Scale Horizontally: Run multiple instances behind a load balancer for high traffic

Monitoring and Maintenance

Monitor your Directus deployment:

Terminal window
# Health check endpoint
curl https://your-app.klutch.sh/server/health
# Server info
curl https://your-app.klutch.sh/server/info

Set up alerts in Klutch.sh for:

  • High CPU usage (>80%)
  • High memory usage (>85%)
  • Disk space usage (>80%)
  • Application downtime

Backup Strategy

Database Backups:

For PostgreSQL:

Terminal window
pg_dump -h your-postgres-host -U directus_user directus > directus-backup-$(date +%Y%m%d).sql

For MySQL:

Terminal window
mysqldump -h your-mysql-host -u directus_user -p directus > directus-backup-$(date +%Y%m%d).sql

File Storage Backups:

Regularly backup the /directus/uploads volume to external storage like S3:

Terminal window
# Example backup script
aws s3 sync /directus/uploads s3://your-backup-bucket/directus-uploads/

Using Nixpacks Customizations

Klutch.sh uses Nixpacks for building applications. If you need to customize the build or start commands without using a Dockerfile, you can use environment variables:

Build-time Variables:

Terminal window
# Custom install command
NIXPACKS_INSTALL_CMD=npm install --production
# Custom build command
NIXPACKS_BUILD_CMD=npm run build

Runtime Variables:

Terminal window
# Custom start command
START_COMMAND=node cli.js start
# Node version
NODE_VERSION=20

However, for Directus, using a Dockerfile is recommended for better control and reproducibility.


Troubleshooting

Common Issues and Solutions

Connection Refused / 502 Error:

  • Verify the internal port is set to 8055
  • Check that Directus is binding to 0.0.0.0 not localhost
  • Review application logs in Klutch.sh dashboard

Database Connection Failed:

  • Verify database credentials are correct
  • Ensure database host is accessible from Klutch.sh
  • Check database user has proper permissions
  • Confirm the database server is running and accepting connections

File Upload Errors:

  • Verify persistent volume is mounted to /directus/uploads
  • Check volume has sufficient space
  • Ensure directory permissions are correct

Admin User Not Created:

  • Verify ADMIN_EMAIL and ADMIN_PASSWORD are set
  • Check application logs for errors
  • Try creating admin user manually through API

Memory Issues:

  • Increase instance size in Klutch.sh dashboard
  • Enable caching to reduce memory usage
  • Optimize database queries

Debug Mode

Enable debug logging for troubleshooting:

Terminal window
LOG_LEVEL=debug
LOG_STYLE=pretty

Access logs through the Klutch.sh dashboard to diagnose issues.


Scaling Your Directus Deployment

Vertical Scaling

Increase resources for a single instance:

  • Upgrade to larger compute size in Klutch.sh dashboard
  • Monitor CPU and memory usage to determine needs
  • Recommended for most small to medium deployments

Horizontal Scaling

Run multiple instances for high availability:

  • Deploy multiple instances behind a load balancer
  • Use shared database (PostgreSQL or MySQL, not SQLite)
  • Use external storage (S3) for uploads
  • Configure session storage in Redis or database

For external storage with S3:

Terminal window
STORAGE_LOCATIONS=s3
STORAGE_S3_DRIVER=s3
STORAGE_S3_KEY=your-access-key
STORAGE_S3_SECRET=your-secret-key
STORAGE_S3_BUCKET=your-bucket-name
STORAGE_S3_REGION=us-east-1

Advanced Configuration

Custom Extensions

Add custom extensions by mounting a volume:

  1. Create extensions locally
  2. Mount /directus/extensions volume in Klutch.sh
  3. Upload extensions to the volume
  4. Restart the application

Webhooks and Automation

Configure webhooks for automation:

Terminal window
WEBHOOKS_ENABLED=true

Set up webhooks in the Directus admin interface to trigger actions on content changes.

Custom Email Templates

Mount custom email templates:

  1. Create templates directory structure
  2. Mount volume to /directus/templates
  3. Configure template path:
Terminal window
EMAIL_TEMPLATES_PATH=/directus/templates

Multi-Tenancy

Deploy separate Directus instances for each tenant:

  • Create separate apps in Klutch.sh
  • Use separate databases per tenant
  • Configure unique public URLs
  • Isolate data and access control

Migration from Existing Directus

Migrating Data

Export from existing instance:

  1. Export database using pg_dump or mysqldump
  2. Download uploaded files
  3. Export schema and configuration

Import to Klutch.sh deployment:

  1. Deploy new Directus instance on Klutch.sh
  2. Import database:
Terminal window
psql -h new-host -U directus_user directus < backup.sql
  1. Upload files to persistent volume
  2. Verify data integrity
  3. Update DNS to point to new instance

Resources


Deploying Directus on Klutch.sh provides you with a powerful, scalable content management platform backed by reliable infrastructure. With proper configuration of persistent storage, database connections, and security settings, you can build production-ready applications that leverage Directus’s flexible data management capabilities. The automatic Dockerfile detection and seamless deployment process make it easy to get started, while advanced features like horizontal scaling and external storage support your growth as your application evolves.