Docs / Programming & Development / Directus Backend

Directus Backend

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 135 views · 4 min read

Directus wraps any SQL database with a real-time REST and GraphQL API, plus an intuitive admin interface for non-technical users. Unlike code-first CMS solutions, Directus works with your existing database schema and adds an API layer on top. This guide covers deploying Directus on a VPS.

Installation with Docker

# docker-compose.yml
services:
  directus:
    image: directus/directus:11
    ports:
      - "8055:8055"
    environment:
      SECRET: "your-random-secret-string"
      DB_CLIENT: "pg"
      DB_HOST: "postgres"
      DB_PORT: "5432"
      DB_DATABASE: "directus"
      DB_USER: "directus"
      DB_PASSWORD: "directuspassword"
      ADMIN_EMAIL: "admin@example.com"
      ADMIN_PASSWORD: "securepassword"
      PUBLIC_URL: "https://cms.example.com"
      CACHE_ENABLED: "true"
      CACHE_STORE: "redis"
      REDIS: "redis://redis:6379"
    volumes:
      - uploads:/directus/uploads
      - extensions:/directus/extensions
    depends_on:
      - postgres
      - redis
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: directus
      POSTGRES_USER: directus
      POSTGRES_PASSWORD: directuspassword
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

volumes:
  pgdata:
  uploads:
  extensions:
# Start
docker compose up -d

# Access admin at http://localhost:8055

Using the API

# REST API
# List items
curl https://cms.example.com/items/articles \
  -H "Authorization: Bearer YOUR_TOKEN"

# Create item
curl -X POST https://cms.example.com/items/articles \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Hello World", "content": "My first article"}'

# GraphQL
curl -X POST https://cms.example.com/graphql \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ articles { id title content } }"}'

# Real-time with WebSocket
# Connect to wss://cms.example.com/websocket

JavaScript SDK

import { createDirectus, rest, readItems, createItem } from "@directus/sdk";

const client = createDirectus("https://cms.example.com").with(rest());

// Fetch articles
const articles = await client.request(
  readItems("articles", {
    filter: { status: { _eq: "published" } },
    sort: ["-date_published"],
    limit: 20,
  })
);

// Create article
await client.request(
  createItem("articles", {
    title: "New Article",
    content: "Content here",
    status: "draft",
  })
);

Collections and Fields

# Create collections via Admin UI or API:
# Settings > Data Model > Create Collection

# Or via migration/snapshot
# npx directus schema snapshot ./snapshot.yaml
# npx directus schema apply ./snapshot.yaml

# Field types available:
# - Text (input, textarea, WYSIWYG, Markdown)
# - Numeric (integer, decimal, slider)
# - Boolean (toggle, checkbox)
# - DateTime (date, time, timestamp)
# - Selection (dropdown, radio, checkboxes)
# - Relational (M2O, O2M, M2M, M2A)
# - File/Image upload
# - JSON
# - Translations

Roles and Permissions

# Directus has granular CRUDS permissions per collection per role:
# C - Create
# R - Read
# U - Update
# D - Delete
# S - Share (file sharing)

# Configure via Admin UI:
# Settings > Roles & Permissions
# Create custom roles: Editor, Author, Viewer
# Set field-level and item-level permissions
# Use custom filters for row-level security

Flows (Automation)

# Directus Flows provide visual automation:
# - Trigger: item.create, item.update, schedule, webhook
# - Operations: send email, run script, HTTP request, transform data
#
# Example: Send email on new contact form submission
# Trigger: items.create (contacts collection)
# Operation 1: Send Email
#   To: admin@example.com
#   Subject: New Contact: {{$trigger.payload.name}}
#   Body: {{$trigger.payload.message}}

Nginx Reverse Proxy

server {
    listen 443 ssl http2;
    server_name cms.example.com;

    ssl_certificate /etc/letsencrypt/live/cms.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cms.example.com/privkey.pem;

    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:8055;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Summary

Directus is the most flexible open-source backend-as-a-service, working with any existing SQL database without migration. The admin UI is polished enough for non-technical content editors, while the REST/GraphQL API and JavaScript SDK serve developers. Flows provide no-code automation, and the granular permission system handles complex multi-tenant scenarios. For teams that want a Supabase-like experience they can self-host, Directus on a VPS is the strongest option.

Was this article helpful?