Deploying
Deploy Emberly with Docker Compose, Dokploy, Railpack/Nixpacks, or directly on a Linux server.
Pick whichever fits how you run servers. Docker Compose is the simplest and bundles PostgreSQL and Redis for you.
| Method | Good for |
|---|---|
| Docker Compose | A single server, with everything in one file |
| Dokploy | Dokploy users; deploys from a template or your fork |
| Railpack / Nixpacks | Railway, Coolify and other PaaS hosts |
| Linux server | Running with Bun and systemd, without containers |
Whatever you choose, put Emberly behind HTTPS (see Reverse Proxy) and set APP_URL to the public address.
Docker Compose
compose.yaml runs Emberly, PostgreSQL and Redis from published images, so you don't need the source code. Uploads are stored in a Docker volume.
Edit .env:
Then start it:
Emberly listens on port 3000. Set EMBERLY_PORT to use a different host port. Migrations run each time the container starts.
With S3 Storage
To store uploads in S3 instead of the local volume, compose.s3.yaml adds a RustFS server:
Set S3_SECRET_ACCESS_KEY and S3_PUBLIC_ENDPOINT in .env first. See Storage.
Updating
To run your own build instead, build the image from a clone of the repository and point Compose at it:
Dokploy
From the Template
The dokploy/ folder has a Dokploy template (docker-compose.yml and template.toml). It runs the published image with PostgreSQL and Redis, and generates AUTH_SECRET and the database password for you.
- In your Dokploy project, create a Compose service.
- Paste
dokploy/docker-compose.ymlas the compose file, or import the template. - Under Environment, set
APP_URL,AUTH_SECRETandPOSTGRES_PASSWORDif the template didn't. - Under Domains, add your domain for the
emberlyservice on port3000, with HTTPS on. - Deploy.
From Your Fork
To build from source instead, for example to run your own changes:
- Create PostgreSQL and Redis databases in Dokploy and copy their internal connection URLs.
- Create an Application pointing at your repository.
- Set Build Type to Dockerfile, with Docker File
Dockerfileand Docker Context Path.. - Add the environment variables:
- Under Advanced → Volumes, mount a volume at
/dataso local uploads survive redeploys. You can skip this if you use S3. - Add your domain on port
3000and deploy.
Railpack and Nixpacks
The repository includes railpack.json and nixpacks.toml, so hosts that build with either detect Emberly automatically. Both run migrations and then start the app.
Set at least APP_URL, AUTH_SECRET, DATABASE_URL and REDIS_URL.
These hosts usually don't keep files between deploys, so use S3 storage.
Linux Server
1. Install
You need Bun, Node.js 24, PostgreSQL 14+ and Redis 7+.
Fill in .env. See Environment Variables.
2. Build
3. Run with systemd
Create /etc/systemd/system/emberly.service:
bun run start reads .env from the repository root.
Running the Worker Separately
The background worker (emails, notifications, Discord alerts, OCR, malware scans) runs inside the app, so you don't need a second process. On busy instances you can move it to its own: set EMBERLY_RUN_EVENT_WORKER=false on the app and add a second service with ExecStart=/usr/bin/env bun run worker. Running the app on several servers is fine too; each picks up its share of the jobs.
Updating
Reverse Proxy
Dokploy and most PaaS hosts handle HTTPS for you. On your own server, use Caddy or Nginx.
Caddy
Nginx
New sign-in alerts and the devices list show where someone signed in from when your proxy adds location headers. Cloudflare does this automatically (CF-IPCountry, and CF-IPCity with its location headers turned on), as does Vercel. Without them, sign-ins still show the device and time, just not the place.
Then run sudo certbot --nginx -d files.example.com. client_max_body_size 0 leaves upload limits to Emberly.
After Deploying
- Open your domain and complete the Setup Wizard.
- Set up email in Admin → Settings → Integrations, so verification and password reset emails send.
- Upload a test file.
Health Checks
GET /api/health reports the database, Redis, storage and event queue. It needs no authentication; the Docker image uses it as its health check.
status is ok, degraded (something other than the database is failing) or down (the database is unreachable, returned with HTTP 503).
Backups
Back up the database and your uploads.
Uploads live in the emberly-data volume (Docker), in DATA_DIR (Linux server), or in your S3 bucket.
Troubleshooting
Admin → Overview shows the state of the database, Redis, storage, the event worker, email and Discord alerts. When reporting a bug, click Copy debug info there and paste it into the issue. It never includes keys, passwords or tokens.
| Problem | Check |
|---|---|
AUTH_SECRET is not set on start | Set AUTH_SECRET (openssl rand -base64 32) |
| Signed in but sent back to the login page | APP_URL must be the exact public address, including https:// |
| Emails, notifications or Discord alerts never arrive | Admin → Overview shows whether an event worker is running. If EMBERLY_RUN_EVENT_WORKER=false, run bun run worker |
| Uploads disappear after a redeploy | Mount a volume at /data, or use S3 |
| Uploads from Flicker or ShareX fail with S3 | S3_PUBLIC_ENDPOINT must be reachable from users' machines |
| Emails don't send | Check the email settings in Admin → Settings → Integrations |