Skip to content

Storage connectors

Configure where Silex stores website data and assets.

Overview

Storage connectors handle the persistence layer: saving website HTML/CSS, assets, and metadata. Silex comes with three built-in options:

  • Filesystem (default) — Store on disk, suitable for self-hosted instances
  • GitLab — Store in GitLab repositories with OAuth authentication
  • FTP — Store on remote FTP servers

Connectors are swappable: you can use one for storage and another for publishing. A user might store websites on GitLab but publish to an FTP server.

Prerequisites

  • Understanding of server configuration
  • For GitLab: a GitLab instance and OAuth app credentials
  • For FTP: an FTP server and credentials

StorageConnector interface

All storage connectors implement this interface:

export interface StorageConnector extends Connector {
  // CRUD on websites
  listWebsites(session): Promise<WebsiteMeta[]>
  readWebsite(session, websiteId): Promise<WebsiteData | Readable>
  createWebsite(session, data): Promise<WebsiteId>
  updateWebsite(session, websiteId, data): Promise<void>
  deleteWebsite(session, websiteId): Promise<void>
  duplicateWebsite(session, websiteId): Promise<void>

  // CRUD on assets
  writeAssets(session, websiteId, files, status?): Promise<string[] | void>
  readAsset(session, websiteId, fileName): Promise<ConnectorFileContent>
  deleteAssets(session, websiteId, fileNames): Promise<void>

  // Metadata
  getWebsiteMeta(session, websiteId): Promise<WebsiteMeta>
  setWebsiteMeta(session, websiteId, data): Promise<void>

  // Auth
  isLoggedIn(session): Promise<boolean>
  setToken(session, token): Promise<void>
  logout(session): Promise<void>
  getUser(session): Promise<ConnectorUser | null>
  getOAuthUrl(session): Promise<string | null>
  getLoginForm(session, redirectTo): Promise<string | null>
  getSettingsForm(session, redirectTo): Promise<string | null>
  getOptions(formData): ConnectorOptions
}

Filesystem storage (default)

Store websites in directories on your server.

Setup

Enable in environment variables:

STORAGE_CONNECTORS=fs
SILEX_FS_ROOT=./silex/storage

Or in Docker:

environment:
  STORAGE_CONNECTORS: fs
  SILEX_FS_ROOT: /silex/storage
volumes:
  - ./silex-storage:/silex/storage

How it works

  • Each website is a directory at {SILEX_FS_ROOT}/{websiteId}/
  • Website data: {websiteId}/website.json
  • Website metadata: {websiteId}/.website.json
  • Assets: {websiteId}/assets/

Directory structure:

silex/storage/
├── my-site-1/
│   ├── website.json
│   ├── .website.json
│   └── assets/
│       ├── logo.png
│       └── hero.jpg
├── my-site-2/
│   ├── website.json
│   ├── .website.json
│   └── assets/

Authentication

Filesystem storage doesn't require authentication. All users on the server have access to all websites (no multi-user isolation).

For multi-user setups, use GitLab storage.

Configuration in code

const FsStorage = require('@silexlabs/silex/dist/server/connectors/FsStorage').FsStorage

module.exports = async function (config) {
  config.setStorageConnectors([
    new FsStorage(config, {
      path: process.env.SILEX_FS_ROOT || './silex/storage',
    }),
  ])
}

GitLab storage

Store websites in GitLab repositories with per-user authentication.

Prerequisites

  1. GitLab instance (gitlab.com or self-hosted)
  2. OAuth application registered in GitLab
  3. Environment variables set on your Silex server

OAuth app setup

On your GitLab instance:

  1. Go to AdminApplications (or your profile → Settings → Applications)
  2. Click New application
  3. Fill in:
  4. Name: Silex
  5. Redirect URI: https://your-silex.com/api/connector/login/callback?type=storage&connectorId=gitlab
  6. Scopes: api, write_repository, read_user
  7. Copy the Application ID and Secret

Set environment variables

STORAGE_CONNECTORS=gitlab
GITLAB_CLIENT_ID=your-app-id
GITLAB_CLIENT_SECRET=your-app-secret
GITLAB_DOMAIN=gitlab.com

For self-hosted GitLab:

GITLAB_DOMAIN=gitlab.mycompany.com

How it works

  • Each user connects with their GitLab account
  • Each website is a repository in their GitLab namespace
  • Website data: website.json in the repo
  • Website metadata: .website.json in the repo
  • Assets: assets/ directory
  • Users see only their own repositories

Repository structure:

my-silex-website/
├── website.json
├── .website.json
└── assets/
    ├── logo.png
    └── hero.jpg

Configuration in code

const GitlabConnector = require('@silexlabs/silex-plugins').GitlabConnector

module.exports = async function (config) {
  config.addStorageConnector(
    new GitlabConnector(config, {
      clientId: process.env.GITLAB_CLIENT_ID,
      clientSecret: process.env.GITLAB_CLIENT_SECRET,
      domain: process.env.GITLAB_DOMAIN || 'gitlab.com',
    })
  )
}

Multiple GitLab instances

To support both gitlab.com and a self-hosted instance:

STORAGE_CONNECTORS=gitlab,gitlab2
GITLAB_CLIENT_ID=app-id-for-gitlab.com
GITLAB_CLIENT_SECRET=secret-for-gitlab.com
GITLAB_DOMAIN=gitlab.com
GITLAB2_CLIENT_ID=app-id-for-self-hosted
GITLAB2_CLIENT_SECRET=secret-for-self-hosted
GITLAB2_DOMAIN=gitlab.mycompany.com

The silex-platform example config shows how to set this up:

class GitlabConnector1 extends GitlabConnector {
  displayName = 'GitLab.com'
}

class GitlabConnector2 extends GitlabConnector {
  connectorId = 'gitlab2'
  displayName = 'Company GitLab'
}

config.addStorageConnector(new GitlabConnector1(config, {...}))
config.addStorageConnector(new GitlabConnector2(config, {...}))

FTP storage

Store websites on an FTP server.

Prerequisites

  • FTP server with credentials
  • Basic FTP knowledge

Setup

STORAGE_CONNECTORS=ftp
FTP_STORAGE_PATH=/public_html

Or in Docker:

environment:
  STORAGE_CONNECTORS: ftp
  FTP_STORAGE_PATH: /public_html

How it works

  • Each website is a directory at {FTP_STORAGE_PATH}/{websiteId}/
  • Users enter FTP credentials (host, port, username, password) in the UI
  • Sessions are stored per user (credentials cached in browser session)
  • Files uploaded via SFTP or traditional FTP

Directory structure on FTP:

public_html/
├── my-site-1/
│   ├── website.json
│   ├── .website.json
│   └── assets/
├── my-site-2/
│   ├── website.json
│   ├── .website.json
│   └── assets/

Configuration in code

const FtpConnector = require('@silexlabs/silex-plugins').FtpConnector
const { ConnectorType } = require('@silexlabs/silex/dist/server/types')

module.exports = async function (config) {
  config.addStorageConnector(
    new FtpConnector(config, {
      type: ConnectorType.STORAGE,
      path: process.env.FTP_STORAGE_PATH || '/public_html',
    })
  )
}

Comparison table

Feature Filesystem GitLab FTP
Setup complexity Simple Medium (OAuth) Simple
Multi-user No isolation Full (per-user OAuth) Session-based
Cost Free Free (or self-hosted) Your FTP server
Security Local disk only OAuth + repo permissions FTP credentials in session
Scaling Single server Multiple servers (repos) Remote server
Best for Development, single user Teams, multiple users Traditional hosting

Combining storage and hosting

You can mix connectors: store on GitLab but publish to FTP:

STORAGE_CONNECTORS=gitlab
HOSTING_CONNECTORS=ftp

Users store their websites in GitLab and publish to their FTP hosting.

Troubleshooting

GitLab OAuth failing

Check that: - OAuth app is registered in GitLab - Redirect URI matches exactly: https://your-silex.com/api/connector/login/callback?type=storage&connectorId=gitlab - Credentials are correct: GITLAB_CLIENT_ID and GITLAB_CLIENT_SECRET - Domain is set: GITLAB_DOMAIN=gitlab.com

Test OAuth by visiting the login URL in a browser:

https://your-silex.com/api/connector/auth?type=storage&connectorId=gitlab

FTP connection failing

Verify FTP server is running:

telnet ftp-server.com 21

Check credentials and path:

ftp ftp-server.com
# Enter username and password
cd /public_html

Filesystem storage permissions

Ensure Silex process can read/write to the storage directory:

chmod 755 ./silex/storage
chown $USER:$USER ./silex/storage

In Docker, the container runs as root, so permissions are usually not an issue.

See also

Edit this page on GitLab