Deploy sbomify using Docker Compose with cryptographic image verification.
Tools:
- Docker & Docker Compose
- cosign v2.0.0+ (install guide)
External Services:
- Keycloak (required) - Authentication provider, must be configured before deploying
- S3 Storage (required) - AWS S3, MinIO, or compatible service with 2 buckets
Included Services:
- PostgreSQL 17 - Production-ready database
- Redis 8 - Cache and message broker
Use external database/Redis only if you need HA or managed services.
# 1. Download files
curl -O https://raw.githubusercontent.com/sbomify/sbomify/master/docker-compose.yml
curl -O https://raw.githubusercontent.com/sbomify/sbomify/master/bin/deploy.sh
curl -O https://raw.githubusercontent.com/sbomify/sbomify/master/Caddyfile
chmod +x deploy.sh
# 2. Configure
cat > override.env << 'EOF'
SBOMIFY_TAG=latest
APP_BASE_URL=https://your-domain.com
# Generate secrets (run these commands and paste the output below):
# openssl rand -base64 32
# openssl rand -base64 32
SECRET_KEY=PASTE_GENERATED_SECRET_HERE
SIGNED_URL_SALT=PASTE_GENERATED_SALT_HERE
# Keycloak (setup externally first)
KEYCLOAK_SERVER_URL=https://keycloak.example.com/
KEYCLOAK_CLIENT_ID=sbomify
KEYCLOAK_CLIENT_SECRET=your-secret
KEYCLOAK_REALM=sbomify
KC_HOSTNAME_URL=https://keycloak.example.com/
# S3 Storage
AWS_ENDPOINT_URL_S3=https://s3.example.com
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=key
AWS_SECRET_ACCESS_KEY=secret
AWS_MEDIA_ACCESS_KEY_ID=media-key
AWS_MEDIA_SECRET_ACCESS_KEY=media-secret
AWS_SBOMS_ACCESS_KEY_ID=sboms-key
AWS_SBOMS_SECRET_ACCESS_KEY=sboms-secret
AWS_MEDIA_STORAGE_BUCKET_NAME=sbomify-media
AWS_MEDIA_STORAGE_BUCKET_URL=https://s3.example.com/sbomify-media
AWS_SBOMS_STORAGE_BUCKET_NAME=sbomify-sboms
AWS_SBOMS_STORAGE_BUCKET_URL=https://s3.example.com/sbomify-sboms
EOF
# 3. Deploy
./deploy.sh
# 4. Verify
docker compose psThe deploy script:
- Pulls and verifies the image signature
- Deploys all services
- Cleans up unused resources
Production: Use a reverse proxy (nginx/Caddy) for SSL termination. App runs on port 8000.
The included Caddyfile provides automatic HTTPS with Let's Encrypt:
Features:
- Automatic TLS certificate provisioning and renewal
- HTTP/2 and HTTP/3 support
- Security headers (HSTS, XSS protection, etc.)
- Health checks and failover
- Cloudflare proxy support
- On-demand TLS for custom domains
Configuration:
Add to your override.env:
# Caddy Configuration
APP_DOMAIN=sbomify.example.com
ACME_EMAIL=admin@example.com
ACME_CA=https://acme-v02.api.letsencrypt.org/directory # Production
# ACME_CA=https://acme-staging-v02.api.letsencrypt.org/directory # Staging/testing
LOG_LEVEL=INFOThe Caddyfile will:
- Serve your app on port 80/443
- Automatically obtain and renew SSL certificates
- Redirect HTTP to HTTPS
- Proxy requests to the Django backend
- Block external access to internal API endpoints
Note: Ensure ports 80 and 443 are open in your firewall for ACME challenges.
# Application
APP_BASE_URL=https://your-domain.com
# Generate with: openssl rand -base64 32
SECRET_KEY=your-generated-secret-key
# Generate with: openssl rand -base64 32
SIGNED_URL_SALT=your-generated-salt
# Keycloak
KEYCLOAK_SERVER_URL=https://keycloak.example.com/
KEYCLOAK_CLIENT_ID=sbomify
KEYCLOAK_CLIENT_SECRET=secret
KEYCLOAK_REALM=sbomify
KC_HOSTNAME_URL=https://keycloak.example.com/
# S3
AWS_ENDPOINT_URL_S3=https://s3.example.com
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=key
AWS_SECRET_ACCESS_KEY=secret
AWS_MEDIA_ACCESS_KEY_ID=key
AWS_MEDIA_SECRET_ACCESS_KEY=secret
AWS_SBOMS_ACCESS_KEY_ID=key
AWS_SBOMS_SECRET_ACCESS_KEY=secret
AWS_MEDIA_STORAGE_BUCKET_NAME=bucket
AWS_MEDIA_STORAGE_BUCKET_URL=https://s3.example.com/bucket
AWS_SBOMS_STORAGE_BUCKET_NAME=bucket
AWS_SBOMS_STORAGE_BUCKET_URL=https://s3.example.com/bucket# Version
SBOMIFY_TAG=latest # or v1.2.3
# External database (default: uses included PostgreSQL)
DATABASE_HOST=postgres.example.com
DATABASE_NAME=sbomify
DATABASE_USER=sbomify
DATABASE_PASSWORD=password
# External Redis (default: uses included Redis)
REDIS_HOST=redis.example.com:6379
# Features
BILLING=FalseDOCKER_TAG=v1.3.0 ./deploy.shDOCKER_TAG=v1.2.0 ./deploy.shdocker compose logs -f
docker compose logs -f sbomify-backenddocker compose up -d --scale sbomify-backend=3 --scale sbomify-worker=2docker compose exec sbomify-backend python manage.py migrate
docker compose exec sbomify-backend python manage.py createsuperuserdocker compose exec sbomify-db pg_dump -U sbomify sbomify > backup.sql# Check cosign version (need v2.0.0+)
cosign version
# Test network access
curl -I https://rekor.sigstore.devCommon causes: outdated cosign, network issues, unsigned image (only master/tags are signed).
docker compose logs sbomify-backend
docker compose config # Check env varsdocker compose exec sbomify-backend env | grep KEYCLOAK
docker compose exec sbomify-backend curl -f $KEYCLOAK_SERVER_URL/realms/$KEYCLOAK_REALMdocker compose exec sbomify-backend env | grep AWSConfigure before deploying sbomify:
- Create Realm: Name
sbomify - Create Client:
- Client ID:
sbomify - Client type: OpenID Connect
- Client authentication: Enabled
- Valid redirect URIs:
https://your-domain.com/* - Valid web origins:
https://your-domain.com
- Client ID:
- Get Client Secret: From admin console → Clients → sbomify → Credentials
Create two buckets before deploying:
- Media bucket (
sbomify-media): Public read access - SBOM bucket (
sbomify-sboms): Private access
Example bucket policy for media:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::sbomify-media/*"
}]
}If you prefer not to use the deploy script:
docker pull sbomifyhub/sbomify:latest
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' sbomifyhub/sbomify:latest | cut -d'@' -f2)
# Verify (optional)
cosign verify-attestation \
--type https://slsa.dev/provenance/v1 \
--certificate-identity-regexp "^https://github.com/sbomify/sbomify/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"sbomifyhub/sbomify@${DIGEST}"
# Deploy
docker compose --env-file ./override.env up -d --force-recreate --remove-orphans
docker system prune -f