Self-host Firefox Sync on Cloudron
-
Are you using Firefox? Did you know you can self-host the sync server on Cloudron? (you know ... because you can). I have just tested this, and it works between Firefox on Ubuntu and Android.
Here is a tutorial for anyone interested:
Replication Guide: Adapting Syncstorage-RS for Cloudron
This guide explains how to take the original mozilla-services/syncstorage-rs repository and adapt it for a single-container deployment on Cloudron with PostgreSQL.
1. Create the Manifest (
CloudronManifest.json)Cloudron requires a manifest file to understand the application requirements. Create this file in the root of the repository.
CloudronManifest.json:{ "manifestVersion": 2, "title": "Syncstorage-RS", "author": "Mozilla Services", "description": "Firefox Sync storage server built with Rust", "version": "0.21.1", "httpPort": 8000, "addons": { "postgresql": { "version": "14.9" } }, "healthCheckPath": "/__heartbeat__" }
2. Create the Start Script (
cloudron-entrypoint.sh)Cloudron provides database credentials through environment variables (
CLOUDRON_POSTGRESQL_*). We need a script to bridge these variables into the format expected by Syncstorage-RS.cloudron-entrypoint.sh:#!/bin/bash set -eu # Default values SYNC_HOST="${SYNC_HOST:-0.0.0.0}" SYNC_PORT="${SYNC_PORT:-8000}" SYNC_MASTER_SECRET="${SYNC_MASTER_SECRET:-}" # 1. Detect Cloudron PostgreSQL addon if [ -z "${CLOUDRON_POSTGRESQL_HOST:-}" ]; then echo "Error: PostgreSQL addon not found. Please ensure it is installed." >&2 exit 1 fi # 2. Convert Cloudron vars to Syncstorage connection strings # We use the same DB for both storage and token management POSTGRES_USER="${CLOUDRON_POSTGRESQL_USERNAME}" POSTGRES_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" POSTGRES_HOST="${CLOUDRON_POSTGRESQL_HOST}" POSTGRES_PORT="${CLOUDRON_POSTGRESQL_PORT}" POSTGRES_DATABASE="${CLOUDRON_POSTGRESQL_DATABASE}" export SYNC_SYNCSTORAGE__DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DATABASE}" export SYNC_TOKENSERVER__DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DATABASE}" export SYNC_TOKENSERVER__RUN_MIGRATIONS="true" # 3. Validate required config if [ -z "$SYNC_MASTER_SECRET" ]; then echo "Error: SYNC_MASTER_SECRET must be set in the Cloudron Environment tab." >&2 exit 1 fi # 4. Start the application exec /app/bin/syncserver "$@"
3. Adapt the Dockerfile (
Dockerfile.cloudron)The original Dockerfile often uses modern features like Docker BuildKit (e.g.,
--mount=type=cacheor--chmodin COPY) which might not be supported in all environments. We created a "clean" version that works with standard Docker.Key Changes Made:
- Set Defaults: Set
SYNCSTORAGE_DATABASE_BACKENDandTOKENSERVER_DATABASE_BACKENDtopostgresat the top of the file. - Remove BuildKit mounts: Removed all instances of
--mount=type=cache...fromRUNcommands to allow building without BuildKit enabled. - Remove inline chmod: Changed
COPY --chmod=0755to standardCOPYfollowed by aRUN chmod +xcommand. - Inject Start Script: Added the
cloudron-entrypoint.shand set it as theENTRYPOINT.
Fragment of changes in the final stage:
# ... after all builds ... COPY --from=builder /app/bin /app/bin COPY cloudron-entrypoint.sh /app/cloudron-entrypoint.sh # BuildKit-compatible chmod replacement RUN chmod +x /app/cloudron-entrypoint.sh USER app:app ENTRYPOINT ["/app/cloudron-entrypoint.sh"]
4. Building and Pushing
To build the image using the new Dockerfile and push it to Cloudron:
# 1. Build locally docker build -f Dockerfile.cloudron -t syncstorage-rs:cloudron . # 2. Push to Cloudron Registry docker tag syncstorage-rs:cloudron CLOUDRON_IP:5000/syncstorage-rs:cloudron docker push CLOUDRON_IP:5000/syncstorage-rs:cloudron
5. Summary of logic
- Single Container: We package the Rust binary and its Python dependencies into one image.
- PostgreSQL Integration: Instead of separate containers for Sync and Token databases, we point both services to the single PostgreSQL database provided by Cloudron.
- Auto-Migrations: We set
SYNC_TOKENSERVER__RUN_MIGRATIONS="true"so the database schema is created automatically on the first start. - Security: The
SYNC_MASTER_SECRETis the only manual configuration required, ensuring data is encrypted at rest.
- Set Defaults: Set