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:
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¶
- GitLab instance (gitlab.com or self-hosted)
- OAuth application registered in GitLab
- Environment variables set on your Silex server
OAuth app setup¶
On your GitLab instance:
- Go to Admin → Applications (or your profile → Settings → Applications)
- Click New application
- Fill in:
- Name: Silex
- Redirect URI:
https://your-silex.com/api/connector/login/callback?type=storage&connectorId=gitlab - Scopes:
api,write_repository,read_user - 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:
How it works¶
- Each user connects with their GitLab account
- Each website is a repository in their GitLab namespace
- Website data:
website.jsonin the repo - Website metadata:
.website.jsonin the repo - Assets:
assets/directory - Users see only their own repositories
Repository structure:
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¶
Or in Docker:
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:
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:
FTP connection failing¶
Verify FTP server is running:
Check credentials and path:
Filesystem storage permissions¶
Ensure Silex process can read/write to the storage directory:
In Docker, the container runs as root, so permissions are usually not an issue.
See also¶
- Server configuration
- Publishing connectors
- Publish to GitLab — Publishing workflow