amfora.

THE FIELD GUIDE

From first install
to final handoff.

Practical documentation for running Amfora and using it to send, collect and manage files.

01 / Start here

A private file workspace you operate

Amfora keeps file metadata in SQLite and stores objects through an S3 compatible storage layer. The image includes a private MinIO service for a zero configuration starting point, and can use an external S3 compatible provider when that better fits your infrastructure.

Send

Upload files, create a share, and send a browser link. Add a password, expiry or view limit, and send recipient email notifications.

Receive

Publish a receive link so people can upload without an Amfora account. Set limits before sharing it.

Control

Manage users, folders, links, branding, two factor authentication, and optional OAuth2/OIDC providers.

02 / Install

Start with Docker Compose

You need Docker with Compose v2 and a running Docker engine. Run this command from a directory without an existing amfora folder:

curl -fsSL https://amfora.solutionmax.net/get | sh

The installer script checks Docker and Compose, creates an amfora directory with a compose file pinned to the current release, pulls ghcr.io/solutionmax/amfora (amd64 and arm64) and starts it. Existing Amfora directories, containers or data volumes are refused. It does not install Docker or configure HTTPS.

To inspect the script before running it:

curl -fsSL https://amfora.solutionmax.net/get -o amfora-get.sh
less amfora-get.sh
sh amfora-get.sh

To build the release yourself, add --source: the installer clones the release tag and builds it, which also needs Git, Bash and Buildx 0.30 or later. The build reuses layers in a dedicated Amfora builder and keeps unused cache near a 4 GB target; make clean only reclaims build cache.

Open http://localhost:5487. The first start creates the SQLite database, seeds configuration, and makes the first account created on an empty database an administrator. Later accounts are ordinary users unless an administrator creates or promotes them.

The sample Compose file publishes the web interface on 5487 and bundled storage on 9379. The API listens on 3333 inside the container and is left unpublished because the bundled web app reaches it through its server side proxy.

For access from another computer, change STORAGE_URL from localhost to the storage address that computer can reach. For public use, complete the HTTPS setup below before sharing the instance.

03 / Production

Give the app and storage clear HTTPS addresses

Use a trusted reverse proxy for both the web interface and the browser facing storage endpoint. A split domain deployment can look like this:

https://app.example.com    → container port 5487
https://files.example.com  → container port 9379

Set the values that describe that public arrangement:

environment:
  SECURE_SITE: "true"
  STORAGE_URL: "https://files.example.com"

STORAGE_URL is the URL used by a browser, not the address one container uses to reach another. The storage hostname must forward to the internal storage service and accept the browser’s upload and download requests. Keep the API on the private container network unless you operate another authenticated API client.

A minimal Caddy example

For Caddy running on the same host, bind the application ports to localhost in Compose. Replace the domains below with your own and point their DNS records at that host.

ports:
  - "127.0.0.1:5487:5487"
  - "127.0.0.1:9379:9379"
app.example.com {
    reverse_proxy 127.0.0.1:5487
}
files.example.com {
    reverse_proxy 127.0.0.1:9379
}

The product website at amfora.solutionmax.net is separate from your Amfora application. These example domains do not provide a hosted Amfora service.

Forward the original host and protocol through the proxy. SECURE_SITE=true enables secure cookies. Configure HSTS at your HTTPS reverse proxy. Set TRUST_PROXY=false when the API is exposed without a trusted proxy in front of it.

04 / Storage

Choose bundled or external S3 compatible storage

Bundled storage

Leave ENABLE_S3=false (the default) to run the included MinIO service. Set STORAGE_URL to the public URL that browsers can reach. The Compose example uses http://127.0.0.1:9379 for local use. The bucket is private and the container writes its generated credentials under the persistent application directory.

External storage

Set ENABLE_S3=true and provide the external endpoint and credentials. The endpoint and bucket must be reachable and permitted for the browser requests represented by generated upload and download URLs.

ENABLE_S3=true
S3_ENDPOINT=s3.example.com
S3_PORT=443
S3_USE_SSL=true
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
S3_REGION=us-east-1
S3_BUCKET_NAME=amfora-files
S3_FORCE_PATH_STYLE=false

Use S3_FORCE_PATH_STYLE=true for providers such as MinIO. If a provider rejects the SDK checksum, set S3_DISABLE_CHECKSUMS=true as documented by that provider. Keep S3_REJECT_UNAUTHORIZED=true unless you have a deliberate certificate exception.

Limits and URL lifetime

A new installation seeds a 1 GiB maximum file size and 10 GiB maximum storage per user. Administrators can adjust those values in Settings. PRESIGNED_URL_EXPIRATION controls the default generated storage URL lifetime in seconds and defaults to 3600.

05 / Daily work

Send a link or collect files through a form

Your workspace

The application opens at sign in, or your dashboard when you are already signed in. The dashboard gives you a starting point for files, shares and upload requests. Use folders to organize files before creating a share. Profile manages your personal details and account security; administration controls are available to administrators.

Send files

  1. Sign in and open My files.
  2. Upload files or create folders.
  3. Select the items, create a share, and set its restrictions.
  4. Copy the generated /s/<alias> link.

A share can have a password, expiration date, maximum view count, and recipient email notifications. Recipient entries do not restrict access to a public share. Its owner can later edit the contents, notification recipients, password, expiry, or alias from Shares. A recipient opens the link in a browser; a protected share asks for its password before files are available.

Copy a link or export its QR code

Use the share menu to copy its link. Open the QR code action to display or download a PNG that points to the same URL. After changing an alias or application hostname, generate a new QR code and replace any older copies. Anyone with the link or code can reach the share, subject to its restrictions.

Receive files

  1. Open Receive files and create a receive share.
  2. Choose optional file count, size, type, password, expiry, name, and email requirements.
  3. Copy the generated /r/<alias> link.

The sender uploads from the public receive page without an Amfora account. The owner reviews the received files in Reverse shares.

06 / Administration

Keep access and identity in the workspace

Administrators can invite users, list and deactivate accounts, change roles, set storage limits, customize the installation, configure SMTP, and manage external login providers. Invite links are one time registration links.

Make it feel like your brand

Open Customization to set the application name, description, logo, accent color, font and corner radius. All of it is stored on the server, so every visitor sees the same brand; the logo also replaces the mark in link previews and the favicon. Check the result in both light and dark themes, on mobile, and on a public upload and download page. Use Settings for storage limits, language, email and authentication configuration.

Brandpack: run it under your own name

Free installations show "Powered by Amfora" on the public pages. A brandpack is a signed key that removes that credit and unlocks two more settings: a background image for the public pages and custom CSS. Paste the key under Customization → Brandpack and press Activate; the installation verifies the signature itself with a public key that ships in the source, so nothing has to reach SolutionMAX for it to work. Removing the key brings the credit back and keeps the stored background and CSS for the next activation.

Custom CSS is admin-only and sanitised on the server: imports, external URLs, expressions and behaviours are removed and the size is capped at 20 kB. The background image is converted to WebP, resized to 2400 px wide and served from /api/app/background. Details for operators and vendors are in docs/BRANDPACK.md.

Two factor authentication

Each user can enable TOTP in their profile, verify setup with an authenticator, save backup codes, and remove trusted devices. A 2FA login verifies the password first and then accepts a TOTP or unused backup code.

OAuth2 and OIDC

External login is optional. The seeded providers are Google, Discord, GitHub, Auth0, Kinde, Zitadel, Authentik, Frontegg and Pocket ID. Additional compatible OIDC providers can be configured. Match callback URLs and client settings at both ends. Keep password authentication enabled until an external provider has been tested; disabling it also disables password reset.

Password recovery

Password reset requires password authentication and a working SMTP configuration. Responses deliberately do not reveal whether an email address exists. For operator recovery, the container includes an interactive reset tool:

docker compose exec amfora sh -lc 'cd /app/amfora-app && ./reset-password.sh'
docker compose exec amfora sh -lc 'cd /app/amfora-app && ./reset-password.sh --list'

Download page cover and link previews

Under Customization, Download page, upload one image to use as the cover at the top of every download page. The same image is the preview in WhatsApp, Slack and similar apps; a separate default link preview image is used when no cover is set. Files from a share are never used for either.

Play video and audio on download pages is off by default. While it is off, visitors see no play or Preview button for video and audio and the server refuses to stream those files to them; they download instead.

07 / Operate

Back up before you upgrade

Bundled storage backups

Back up the complete persistent /app/server directory, including prisma/amfora.db, minio-data, and generated storage credentials. Stop the container or use a filesystem snapshot consistent for the database and objects.

External storage backups

Back up the SQLite database and the external S3 bucket through that provider’s supported process. Keep the database and object backup points close enough to restore a consistent workspace.

Updating

Your files and settings live in the persistent volume; an update only replaces the image. In the amfora directory, set the new version in docker-compose.yaml and run:

docker compose pull
docker compose up -d

Startup applies the Prisma schema and seeds missing configuration and provider records. Older database filenames are migrated to prisma/amfora.db; an existing internal bucket is preserved when no explicit bucket override is supplied. Verify a test share and download afterwards, and keep the previous image until the new one runs so you can switch back.

The admin area shows when a newer release is out. To let the host install signed releases for you with one click, set up over the air updates once. Every release is on the releases page.

08 / Troubleshooting

Check the boundary where the request stops

The page loads but uploads fail.
Confirm that STORAGE_URL is browser reachable, forwards to the storage service, and accepts the storage requests. Then inspect docker compose logs -f amfora.
The API starts but storage is unavailable.
For bundled storage, wait for initialization and check for .minio-credentials in the persistent directory. For external S3, verify every S3_* value and bucket permission.
HTTPS redirects or cookies behave incorrectly.
Check the forwarded host and protocol, set SECURE_SITE=true for HTTPS, and set TRUST_PROXY=false when no trusted proxy is present.
Password reset email does not arrive.
Enable SMTP in Settings, verify the host, port, credentials, sender, and TLS mode, and run the admin SMTP test action.
An upgrade appears empty.
Check that the original persistent volume is mounted. Do not create a new bucket or rename the storage directory by hand; preserve the bucket recorded in .minio-credentials.

09 / About Amfora

A self hosted workspace for the handoff.

Amfora is a self hosted file workspace for sending files, collecting uploads, and managing access. This guide covers the installation, storage, sharing, and administration workflows that keep a handoff moving.

The application source is publicly available on GitHub. No account or access request is required. Amfora has its own visual identity and ongoing improvements. Its upstream attribution is preserved in NOTICE. It is licensed under the Apache License 2.0. Bundled MinIO and mc are separate, unmodified AGPL-3.0 programs. See LICENSE, NOTICE and the bundled program license.

Fonts: Bricolage Grotesque and Plus Jakarta Sans, distributed under the SIL Open Font License. Font license files are included with the source repository.