Only Once Share
self-hostingDockertutorial

How to Self-Host a Secret Sharing Tool with Docker

Self-hosting your secret sharing tool gives you complete control over your data. No third-party servers, no trust assumptions, no data leaving your infrastructure. Here's how to set up Only Once Share on your own server using Docker in under 10 minutes.

Why Self-Host?

  • Data sovereignty β€” Encrypted data never leaves your infrastructure
  • Compliance β€” Meet data residency requirements (GDPR, HIPAA, SOC 2)
  • Network isolation β€” Run on an internal network with no public internet exposure
  • Customization β€” Modify the code, branding, or configuration to your needs
  • No dependency β€” Your secret sharing doesn't go down if a SaaS provider has an outage

Prerequisites

  • A server (Linux recommended) with Docker and Docker Compose installed
  • At least 512MB RAM and 1GB disk space
  • Basic command-line knowledge

Step 1: Clone the Repository

git clone https://github.com/dhdtech/only-once-share.git
cd only-once-share

Step 2: Configure Environment Variables

Create a .env file with your configuration:

# Required
REDIS_URL=redis://redis:6379

# Optional: PostHog analytics (remove to disable)
# VITE_POSTHOG_KEY=your_key
# POSTHOG_API_KEY=your_key

# Optional: API URL (default works with Docker Compose)
# VITE_API_URL=http://localhost:5000

Step 3: Start the Stack

docker compose up -d

This starts three containers:

  • ui β€” React frontend served by Nginx on port 80
  • api β€” Flask API server on port 5000
  • redis β€” Redis data store for encrypted secrets

Step 4: Access the Application

Open http://your-server-ip in a browser. You should see the Only Once Share interface ready to use.

Production Configuration

Add HTTPS with a Reverse Proxy

For production use, place a reverse proxy (Nginx, Caddy, or Traefik) in front of the application to handle TLS/HTTPS. Caddy is the simplest option since it handles certificate management automatically:

# Caddyfile
ooshare.yourdomain.com {
    reverse_proxy localhost:80
}

Redis Persistence

By default, Docker Compose configures Redis with a persistent volume. Secrets are automatically deleted after their TTL expires, but the volume ensures secrets survive container restarts.

Resource Limits

For production, set resource limits in your Docker Compose override:

services:
  api:
    deploy:
      resources:
        limits:
          memory: 256M
  redis:
    deploy:
      resources:
        limits:
          memory: 128M

Security Considerations

  • Network access β€” If hosting internally, ensure only authorized networks can reach the application
  • Redis access β€” Never expose Redis to the public internet. The Docker Compose network keeps it internal by default
  • Updates β€” Regularly pull the latest version from GitHub for security patches
  • Monitoring β€” Monitor the /api/health endpoint for uptime checks

Architecture Overview

Understanding the architecture helps with custom deployments:

Browser β†’ Nginx (static UI) β†’ Flask API β†’ Redis
   ↑                                    ↓
   └── Encryption key in URL fragment β”€β”€β”˜
       (never sent to any server)

The Flask API is stateless β€” you can run multiple instances behind a load balancer for high availability. Redis is the only stateful component, storing encrypted blobs with TTL-based auto-expiration.

Conclusion

Self-hosting Only Once Share gives you the security of zero-knowledge encryption combined with the control of running on your own infrastructure. The Docker setup takes minutes and the entire stack runs on minimal resources. For organizations with data residency requirements or strict security policies, self-hosting is the ideal deployment model.

Share secrets securely β€” for free

Only Once Share uses AES-256-GCM encryption with zero-knowledge architecture. No account required.

Try Only Once Share
All posts