Self-Hosting OneTimeSecret with Docker Compose
What Is OneTimeSecret?
OneTimeSecret lets you share sensitive information through self-destructing links. Paste a password, API key, or private message — get a link that can only be viewed once, then it’s permanently deleted. No accounts needed for sharing. It replaces onetimesecret.com and similar services, keeping your secrets on your own infrastructure. Official site.
Updated March 2026: Verified with latest Docker images and configurations.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 512 MB of free RAM
- 1 GB of free disk space
- A domain name (recommended for HTTPS)
Docker Compose Configuration
Create a docker-compose.yml file:
services:
onetimesecret:
image: onetimesecret/onetimesecret:v0.24.1
container_name: onetimesecret
restart: unless-stopped
ports:
- "3000:3000"
environment:
# Required: encryption key — generate with: openssl rand -hex 32
SECRET: "change_me_run_openssl_rand_hex_32"
# Required: your domain (used in generated links)
HOST: "secrets.example.com"
# Required: Redis connection
REDIS_URL: "redis://ots-redis:6379/0"
# Enable HTTPS links (set true behind reverse proxy)
SSL: "true"
depends_on:
ots-redis:
condition: service_healthy
ots-redis:
image: redis:7.4-alpine
container_name: ots-redis
restart: unless-stopped
volumes:
- ots-redis-data:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
ots-redis-data:
Generate the SECRET value before starting:
# Generate a secure encryption key
openssl rand -hex 32
# Output example: a1b2c3d4e5f6... (64 characters)
# Paste this value into the SECRET environment variable
Start the stack:
docker compose up -d
Initial Setup
- Open
http://your-server-ip:3000in your browser - You’ll see the OneTimeSecret interface — paste any text and click “Create a secret link”
- Share the generated link — the recipient can view it exactly once, then it’s permanently deleted
- No account needed for basic sharing
Create an Admin Account
To manage secrets and view metadata, create an account through the web interface:
- Click “Sign Up” in the navigation
- Enter an email and password
- Logged-in users can set custom TTL values and view their secret history
Configuration
Environment Variables
| Variable | Required | Description |
|---|---|---|
SECRET | Yes | Encryption key (run openssl rand -hex 32) |
HOST | Yes | Your domain name for generated links |
REDIS_URL | Yes | Redis connection string |
SSL | Recommended | Set true for HTTPS links |
AUTH_REQUIRED | No | Require login to create secrets (default: false) |
UI_ENABLED | No | Disable web UI for API-only (default: true) |
TTL_OPTIONS | No | Available TTL options in seconds (default: 1800 43200 86400 259200) |
TTL Options
Default expiry options are 30 minutes, 12 hours, 24 hours, and 3 days. Customize with space-separated seconds:
environment:
TTL_OPTIONS: "300 3600 86400 604800" # 5min, 1hr, 1day, 7days
API Usage
Create secrets programmatically:
# Create a secret via API
curl -X POST "https://secrets.example.com/api/v1/share" \
-u "your-email:your-api-key" \
-d "secret=my-super-secret-password&ttl=3600"
# Response includes the secret_key for building the link
# Link format: https://secrets.example.com/secret/SECRET_KEY
Restricting Access
For internal use only, require authentication:
environment:
AUTH_REQUIRED: "true" # Only logged-in users can create secrets
Reverse Proxy
HTTPS is strongly recommended for a secret-sharing service. Set SSL: "true" in the environment and place behind a reverse proxy. See Reverse Proxy Setup.
Example Caddy config:
secrets.example.com {
reverse_proxy onetimesecret:3000
}
Backup
Redis data is the only persistent state. Back up the Redis volume:
# Trigger a Redis save
docker exec ots-redis redis-cli BGSAVE
# Copy the dump file
docker cp ots-redis:/data/dump.rdb ./ots-backup-$(date +%Y%m%d).rdb
See Backup Strategy for automated backup approaches.
Troubleshooting
”Connection Refused” to Redis
Symptom: OneTimeSecret fails to start with Redis connection error.
Fix: Ensure the Redis container is running and healthy: docker compose ps. Check that REDIS_URL uses the correct service name (ots-redis, not localhost). Verify both containers are on the same Docker network.
Generated Links Show Wrong Domain
Symptom: Secret links use localhost or the wrong domain.
Fix: Set the HOST environment variable to your actual domain. Set SSL: "true" if behind HTTPS. Restart the container after changing.
Secrets Not Expiring
Symptom: Secrets remain accessible after TTL should have expired.
Fix: Redis handles TTL expiry. Check Redis is persisting correctly with docker exec ots-redis redis-cli INFO keyspace. Verify TTL_OPTIONS values are in seconds.
Resource Requirements
- RAM: ~80 MB idle (app + Redis), ~150 MB under load
- CPU: Very low
- Disk: Minimal — secrets auto-delete after viewing or TTL expiry
Verdict
OneTimeSecret is the simplest way to share passwords and secrets securely. The workflow is intuitive — paste, share link, done. For a secret-sharing tool, that simplicity is the entire value proposition. If you need encrypted pastebins for code or text, PrivateBin is more flexible. If you need one-time links with zero UI and maximum simplicity, Yopass is even more minimal. OneTimeSecret hits the sweet spot: clean UI, API support, and self-destructing secrets with custom TTL.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments