selfhostedworld.com logoselfhostedworld.com

Try describing what you need:

Safebucket logo

Safebucket

★ 991

A self-hosted alternative to Dropbox

Apache License 2.0Open Source — No Paywall8 Containers — 8 containers — heavy hosting footprintDocker · Compose · SourceNeeds Postgres2 documented maintainers

About

Safebucket is an open source file sharing platform designed for teams or organizations that need self-hosted control over storage and sharing behavior. It emphasizes a pluggable architecture in which...

Community Ratings

No ratings yet

Features

  • Direct uploads and downloads via presigned URLs
  • Swappable infrastructure components
  • OIDC SSO
  • local authentication
  • role-based access control
  • public share links
  • password-protected shares
  • download/view limits
  • real-time activity tracking
  • audit logs

Details

Last Updated
Oct 19, 2026
Created
Oct 4, 2024
Install Methods
dockerdocker-composesource
Requirements
GoReactDocker Compose
Authentication
oidc-ssolocal2fa
API
REST
Runtime / Stack
GoDocker
Privacy & Independence
No Cloud Required
User Model
Multi-User
Deployment

Deployment: Docker Compose ✓8 Containers — heavy hosting footprintRuns as 8 containers

Run Safebucket with Docker Compose

Compose file from the Safebucket project repository.

8 services · database: postgres · infra: postgres, valkey, nats · 4 unclassified (rustfs, aws-cli, mailpit, loki)

no resource limits declared

needs persistent storage (7 volumes)

deployments/local/full/docker-compose.yml · @ c5920d6 · scanned Sep 24, 2026

name: safebucket

services:
  safebucket:
    container_name: safebucket
    image: ghcr.io/safebucket/safebucket:latest
    environment:
      - APP__LOG_LEVEL=${APP__LOG_LEVEL}
      - APP__PROFILE=${APP__PROFILE}
      - APP__API_URL=${APP__API_URL}
      - APP__WEB_URL=${APP__WEB_URL}
      - APP__PORT=${APP__PORT}
      - APP__TRUSTED_PROXIES=${APP__TRUSTED_PROXIES}
      - APP__STATIC_FILES__ENABLED=${APP__STATIC_FILES__ENABLED}
      - APP__TOKEN_SECRET=${APP__TOKEN_SECRET}
      - APP__ADMIN_EMAIL=${APP__ADMIN_EMAIL}
      - APP__ADMIN_PASSWORD=${APP__ADMIN_PASSWORD}
      - APP__ALLOWED_ORIGINS=${APP__ALLOWED_ORIGINS}
      - APP__TRASH_RETENTION_DAYS=${APP__TRASH_RETENTION_DAYS}
      - APP__MFA_ENCRYPTION_KEY=${APP__MFA_ENCRYPTION_KEY}
      - APP__MFA_REQUIRED=${APP__MFA_REQUIRED}
      - APP__MAX_UPLOAD_SIZE=${APP__MAX_UPLOAD_SIZE}
      - DATABASE__TYPE=${DATABASE__TYPE}
      - DATABASE__POSTGRES__HOST=${DATABASE__POSTGRES__HOST}
      - DATABASE__POSTGRES__PORT=${DATABASE__POSTGRES__PORT}
      - DATABASE__POSTGRES__USER=${DATABASE__POSTGRES__USER}
      - DATABASE__POSTGRES__PASSWORD=${DATABASE__POSTGRES__PASSWORD}
      - DATABASE__POSTGRES__NAME=${DATABASE__POSTGRES__NAME}
      - DATABASE__POSTGRES__SSLMODE=${DATABASE__POSTGRES__SSLMODE}
      - DATABASE__HOST=${DATABASE__POSTGRES__HOST}
      - DATABASE__PORT=${DATABASE__POSTGRES__PORT}
      - DATABASE__USER=${DATABASE__POSTGRES__USER}
      - DATABASE__PASSWORD=${DATABASE__POSTGRES__PASSWORD}
      - DATABASE__NAME=${DATABASE__POSTGRES__NAME}
      - DATABASE__SSLMODE=${DATABASE__POSTGRES__SSLMODE}
      - CACHE__TYPE=${CACHE__TYPE}
      - CACHE__VALKEY__HOSTS=${CACHE__VALKEY__HOSTS}
      - CACHE__VALKEY__PASSWORD=${CACHE__VALKEY__PASSWORD}
      - STORAGE__TYPE=${STORAGE__TYPE}
      - STORAGE__RUSTFS__BUCKET_NAME=${STORAGE__RUSTFS__BUCKET_NAME}
      - STORAGE__RUSTFS__ENDPOINT=${STORAGE__RUSTFS__ENDPOINT}
      - STORAGE__RUSTFS__EXTERNAL_ENDPOINT=${STORAGE__RUSTFS__EXTERNAL_ENDPOINT}
      - STORAGE__RUSTFS__ACCESS_KEY=${STORAGE__RUSTFS__ACCESS_KEY}
      - STORAGE__RUSTFS__SECRET_KEY=${STORAGE__RUSTFS__SECRET_KEY}
      - EVENTS__TYPE=${EVENTS__TYPE}
      - EVENTS__QUEUES__NOTIFICATIONS__NAME=${EVENTS__QUEUES__NOTIFICATIONS__NAME}
      - EVENTS__QUEUES__BUCKET_EVENTS__NAME=${EVENTS__QUEUES__BUCKET_EVENTS__NAME}
      - EVENTS__QUEUES__OBJECT_DELETION__NAME=${EVENTS__QUEUES__OBJECT_DELETION__NAME}
      - EVENTS__JETSTREAM__HOST=${EVENTS__JETSTREAM__HOST}
      - EVENTS__JETSTREAM__PORT=${EVENTS__JETSTREAM__PORT}
      - NOTIFIER__TYPE=${NOTIFIER__TYPE}
      - NOTIFIER__SMTP__HOST=${NOTIFIER__SMTP__HOST}
      - NOTIFIER__SMTP__PORT=${NOTIFIER__SMTP__PORT}
      - NOTIFIER__SMTP__USERNAME=${NOTIFIER__SMTP__USERNAME}
      - NOTIFIER__SMTP__PASSWORD=${NOTIFIER__SMTP__PASSWORD}
      - NOTIFIER__SMTP__SENDER=${NOTIFIER__SMTP__SENDER}
      - NOTIFIER__SMTP__TLS_MODE=${NOTIFIER__SMTP__TLS_MODE}
      - NOTIFIER__SMTP__SKIP_VERIFY_TLS=${NOTIFIER__SMTP__SKIP_VERIFY_TLS}
      - ACTIVITY__TYPE=${ACTIVITY__TYPE}
      - ACTIVITY__LOKI__ENDPOINT=${ACTIVITY__LOKI__ENDPOINT}
      - AUTH__PROVIDERS__KEYS=${AUTH__PROVIDERS__KEYS}
      - AUTH__PROVIDERS__LOCAL__NAME=${AUTH__PROVIDERS__LOCAL__NAME}
      - AUTH__PROVIDERS__LOCAL__TYPE=${AUTH__PROVIDERS__LOCAL__TYPE}
      - AUTH__PROVIDERS__LOCAL__SHARING__ALLOWED=${AUTH__PROVIDERS__LOCAL__SHARING__ALLOWED}

    ports:
      - "8080:8080"
    networks:
      - safebucket-external
      - safebucket-internal
    restart: on-failure:3
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    depends_on:
      bucket-init:
        condition: service_completed_successfully
      database:
        condition: service_healthy

  bucket:
    container_name: bucket
    image: rustfs/rustfs:1.0.0-alpha.84
    environment:
      - RUSTFS_ACCESS_KEY=${STORAGE__RUSTFS__ACCESS_KEY}
      - RUSTFS_SECRET_KEY=${STORAGE__RUSTFS__SECRET_KEY}
      - RUSTFS_NOTIFY_MQTT_ENABLE_PRIMARY=true
      - RUSTFS_NOTIFY_MQTT_BROKER_PRIMARY=mqtt://nats:1883
      - RUSTFS_NOTIFY_MQTT_TOPIC_PRIMARY=${EVENTS__QUEUES__BUCKET_EVENTS__NAME}
      - RUSTFS_NOTIFY_MQTT_QOS_PRIMARY=2
      - RUSTFS_NOTIFY_MQTT_QUEUE_DIR_PRIMARY=/data/.rustfs/events
    ports:
      - "9000:9000"
    volumes:
      - "rustfs_data:/data"
    healthcheck:
      test: [ "CMD-SHELL", "curl -f http://localhost:9000/health && curl -f http://localhost:9001/rustfs/console/health" ]
      interval: 3s
      timeout: 2s
      retries: 10
      start_period: 2s
    networks:
      - safebucket-external
      - safebucket-internal
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    depends_on:
      - nats

  bucket-init:
    container_name: bucket-init
    image: amazon/aws-cli:latest
    environment:
      - AWS_ACCESS_KEY_ID=${STORAGE__RUSTFS__ACCESS_KEY}
      - AWS_SECRET_ACCESS_KEY=${STORAGE__RUSTFS__SECRET_KEY}
      - AWS_RETRY_MODE=standard
      - AWS_MAX_ATTEMPTS=5
      - AWS_REGION=us-east-1
      - BUCKET_NAME=${STORAGE__RUSTFS__BUCKET_NAME}
      - ENDPOINT_URL=http://bucket:9000
    entrypoint: [ "/bin/sh", "-c" ]
    command:
      - |
        echo "Configuring RustFS buckets via aws-cli..."

        # Wait for RustFS to be ready
        echo "Waiting for RustFS to be ready..."
        for bucket in $${BUCKET_NAME} loki-data loki-ruler; do
          while ! aws s3api head-bucket --bucket $${bucket} --endpoint-url $${ENDPOINT_URL} 2>/dev/null; do
            echo "Checking if bucket $${bucket} exists... if not creating it."
            aws s3api create-bucket --bucket $${bucket} --endpoint-url $${ENDPOINT_URL} 2>/dev/null || true
            sleep 2
          done
          echo "Bucket $${bucket} is ready."
        done

        echo "Applying CORS policy..."
        aws s3api put-bucket-cors --bucket $${BUCKET_NAME} --endpoint-url $${ENDPOINT_URL} --cors-configuration '{"CORSRules":[{"AllowedHeaders":["*"],"AllowedMethods":["GET","PUT","POST","DELETE","HEAD"],"AllowedOrigins":["*"],"ExposeHeaders":["ETag"]}]}'

        echo "Adding bucket notification events for MQTT target..."
        aws s3api put-bucket-notification-configuration --bucket $${BUCKET_NAME} --endpoint-url $${ENDPOINT_URL} --notification-configuration '{"QueueConfigurations":[{"QueueArn":"arn:rustfs:sqs:us-east-1:primary:mqtt","Events":["s3:ObjectCreated:*","s3:ObjectRemoved:*","s3:ObjectAccessed:*"]}]}'

        echo "Buckets configured successfully."
    depends_on:
      bucket:
        condition: service_healthy
      nats:
        condition: service_started
    networks:
      - safebucket-internal
    restart: "no"
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"

  database:
    container_name: database
    image: postgres:18
    volumes:
      - "postgresql_data:/var/lib/postgresql"
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    shm_size: 128mb
    environment:
      POSTGRES_USER: ${DATABASE__POSTGRES__USER}
      POSTGRES_PASSWORD: ${DATABASE__POSTGRES__PASSWORD}
      POSTGRES_DB: ${DATABASE__POSTGRES__NAME}
    healthcheck:
      test: [ "CMD-SHELL", "psql -U ${DATABASE__POSTGRES__USER} -d ${DATABASE__POSTGRES__NAME} -c 'SELECT 1' || exit 1" ]
      interval: 2s
      timeout: 3s
      retries: 10
      start_period: 5s
    networks:
      - safebucket-internal

  valkey:
    container_name: valkey
    image: valkey/valkey:9
    command: [ "valkey-server", "--requirepass", "${CACHE__VALKEY__PASSWORD}" ]
    networks:
      - safebucket-internal
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    shm_size: 128mb
    volumes:
      - "valkey_data:/data"

  mailpit:
    image: axllent/mailpit:v1.30
    container_name: mailpit
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    volumes:
      - "mail_data:/data"
    ports:
      - "8025:8025"
      - "1025:1025"
    environment:
      MP_MAX_MESSAGES: 500
      MP_DATABASE: /data/mailpit.db
    networks:
      - safebucket-external
      - safebucket-internal

  nats:
    image: nats:2.14-alpine
    container_name: nats
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    command: [ "-c", "/etc/nats/nats.conf" ]
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - "nats_data:/data"
      - ./config/nats.conf:/etc/nats/nats.conf:ro
    networks:
      - safebucket-internal

  loki:
    container_name: loki
    image: grafana/loki:3.7.6
    command: "-config.file=/etc/loki/config.yaml"
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "1"
    volumes:
      - ./config/loki.yaml:/etc/loki/config.yaml
    depends_on:
      bucket:
        condition: service_healthy
    healthcheck:
      test: [ "CMD", "loki", "-health" ]
      interval: 5s
      timeout: 5s
      retries: 5
      start_period: 10s
    networks:
      - safebucket-internal

networks:
  safebucket-external:
    driver: bridge
  safebucket-internal:
    internal: true

volumes:
  postgresql_data:
  rustfs_data:
  mail_data:
  valkey_data:
  nats_data:

This file may be out of date. Check the Safebucket documentation for current setup steps.

Track your self-hosted stack

Bookmark software to try, rate tools you've used, and keep your collection in one place.

Metadata extracted from README on Jun 7, 2026

Related Software

Cloudreve logo

Cloudreve

28.9k
Cloudreve is a self-hosted file management system with multi-cloud storage support.
File SynchronizationCopyleft LicenseWeb File Managers+4
3 Containers
Details
ShareX logo

ShareX

40.2k
A screen capture, file sharing, and productivity tool.
Video EditingFully FOSSCopyleft License+3
Fully FOSS
Details
OnionShare logo

OnionShare

7.2k
OnionShare is an open source tool for securely and anonymously sharing files, hosting websites, and chatting over the Tor network.
Simple File UploadsCopyleft LicenseP2P File Sharing+1
Details
Sharry logo

Sharry

1.4k
Sharry is a self-hosted web application for uploading files and generating shareable URLs for others to download or upload files.
Simple File UploadsCopyleft LicenseWeb File Managers+2
2 Containers
Details
Chibisafe logo

Chibisafe

2.8k
Chibisafe is a self-hosted file uploader service that generates shareable links for uploaded files, photos, documents, and other content.
Simple File UploadsFile & Object StorageMedia Management+5
Details
Gokapi logo

Gokapi

2.9k
Gokapi is a self-hosted file sharing service and alternative to Firefox Send with expiring shares, encryption, and cloud storage support.
Simple File UploadsCopyleft LicenseFile & Object Storage+2
Single Container
Details
transfer.sh logo

transfer.sh

15.9k
Easy and fast file sharing from the command line with a self-hosted server for uploads and downloads.
Simple File UploadsFile & Object StorageSelf Hosting Solutions+2
Telemetry: Opt-Out
Details
FileGator logo

FileGator

3.1k
FileGator is a self-hosted web file manager for managing files and folders, with multi-user access and support for multiple storage backends.
Web File ManagersPermissive LicenseFile & Object Storage+2
Details
Zipline logo

Zipline

3.5k
A self-hosted file upload server for sharing files, shortening URLs, and managing upload-related assets.
Simple File UploadsFile & Object StorageSelf Hosting Solutions+4
Details
ProjectSend logo

ProjectSend

2.0k
A self-hosted client portal for sharing files privately with clients, partners, and teams.
Simple File UploadsWeb File ManagersFile & Object Storage+2
Details
Plik logo

Plik

1.8k
Plik is a self-hosted temporary file upload system for sharing files, similar to WeTransfer.
Simple File UploadsPermissive LicenseFile & Object Storage+2
Details
miniserve logo

miniserve

7.9k
miniserve is a small cross-platform CLI tool for serving files and directories over HTTP.
Web File ManagersSimple File UploadsFile & Object Storage+3
Details