161ef94b4f
Check engine pin consistency / Dockerfile / CI pin consistency (push) Successful in 8s
Sirius CI/CD Pipeline / Detect Changes (push) Successful in 23s
Validate Docker Configuration / Validate Docker Compose Configuration (push) Successful in 47s
Sirius CI/CD Pipeline / Build API (${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Build UI (${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Engine Manifest (push) Has been cancelled
Sirius CI/CD Pipeline / Merge API Manifest (push) Has been cancelled
Sirius CI/CD Pipeline / Merge UI Manifest (push) Has been cancelled
Sirius CI/CD Pipeline / Build Engine (${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Build Infra (${{ matrix.service }}, ${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Infra Manifest (sirius-postgres) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Infra Manifest (sirius-rabbitmq) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Infra Manifest (sirius-valkey) (push) Has been cancelled
Sirius CI/CD Pipeline / Integration Test (push) Has been cancelled
Sirius CI/CD Pipeline / Public Stack Contract (push) Has been cancelled
Sirius CI/CD Pipeline / Dispatch Demo Deployment (sirius-demo branch) (push) Has been cancelled
Sirius CI/CD Pipeline / Dispatch Demo Canary (main branch) (push) Has been cancelled
Sirius CI/CD Pipeline / Guard Registry Namespace (push) Has been cancelled
429 lines
14 KiB
Markdown
429 lines
14 KiB
Markdown
---
|
|
title: "Docker Container Deployment Guide"
|
|
description: "Complete guide for deploying Sirius using prebuilt container images from GitHub Container Registry"
|
|
template: "TEMPLATE.guide"
|
|
version: "1.0.0"
|
|
last_updated: "2026-04-08"
|
|
author: "Development Team"
|
|
tags: ["docker", "deployment", "containers", "ghcr", "registry", "production"]
|
|
categories: ["deployment", "infrastructure"]
|
|
difficulty: "beginner"
|
|
prerequisites: ["docker", "docker-compose"]
|
|
related_docs:
|
|
- "README.terraform-deployment.md"
|
|
- "README.development.md"
|
|
- "README.docker-architecture.md"
|
|
dependencies: ["docker-compose.yaml"]
|
|
llm_context: "high"
|
|
search_keywords:
|
|
[
|
|
"docker",
|
|
"deployment",
|
|
"containers",
|
|
"ghcr",
|
|
"registry",
|
|
"production",
|
|
"images",
|
|
"compose",
|
|
]
|
|
---
|
|
|
|
# Docker Container Deployment Guide
|
|
|
|
## Purpose
|
|
|
|
This guide explains how to deploy Sirius using prebuilt container images from GitHub Container Registry (GHCR). This approach provides faster deployments (5-8 minutes vs 20-25 minutes) by eliminating on-instance Docker builds. The guide covers production deployments, image versioning, and fallback strategies.
|
|
|
|
## When to Use
|
|
|
|
- **Production deployments** - Deploying Sirius to production environments
|
|
- **Demo environments** - Setting up demo instances quickly
|
|
- **Staging environments** - Creating isolated testing environments
|
|
- **Quick deployments** - When you need fast deployment without building from source
|
|
- **CI/CD pipelines** - Automated deployments using prebuilt images
|
|
|
|
**Avoid when**:
|
|
|
|
- **Local development** - Use `docker-compose.dev.yaml` for local builds with hot reloading
|
|
- **Custom modifications** - When you need to modify source code before deployment
|
|
- **Offline environments** - When registry access is unavailable
|
|
|
|
## How to Use
|
|
|
|
### Quick Start
|
|
|
|
```bash
|
|
# Clone repository
|
|
git clone https://github.com/SiriusScan/Sirius.git
|
|
cd Sirius
|
|
|
|
# Generate startup config and secrets
|
|
docker compose -f docker-compose.installer.yaml run --rm sirius-installer
|
|
|
|
# Deploy with prebuilt images (default)
|
|
docker compose up -d
|
|
|
|
# Or specify a version tag
|
|
IMAGE_TAG=v0.4.1 docker compose up -d
|
|
|
|
# Optional: verify the public GHCR contract before pulling
|
|
bash scripts/verify-ghcr-public-access.sh "${IMAGE_TAG:-latest}"
|
|
```
|
|
|
|
### Prerequisites
|
|
|
|
- **Docker** >= 20.10.0
|
|
- **Docker Compose** >= 2.0.0
|
|
- **Internet access** to GitHub Container Registry (ghcr.io)
|
|
- **Git** (for cloning repository)
|
|
|
|
## Container Registry Integration
|
|
|
|
### GitHub Container Registry (GHCR)
|
|
|
|
Sirius images are automatically built and pushed to GitHub Container Registry on every push to the main branch. Images are available at:
|
|
|
|
- **UI**: `ghcr.io/siriusscan/sirius-ui:{tag}`
|
|
- **API**: `ghcr.io/siriusscan/sirius-api:{tag}`
|
|
- **Engine**: `ghcr.io/siriusscan/sirius-engine:{tag}`
|
|
- **Postgres**: `ghcr.io/siriusscan/sirius-postgres:{tag}`
|
|
- **RabbitMQ**: `ghcr.io/siriusscan/sirius-rabbitmq:{tag}`
|
|
- **Valkey**: `ghcr.io/siriusscan/sirius-valkey:{tag}`
|
|
|
|
`docker-compose.yaml` is the public-image deployment path for Sirius. If an unauthenticated `docker pull` against one of the image refs above returns `unauthorized`, the GHCR public-visibility contract is broken and operators should stop before rollout.
|
|
|
|
### Image Tagging Strategy
|
|
|
|
Images are tagged with the following strategy:
|
|
|
|
| Tag | Description | When Created |
|
|
| -------- | ------------------------ | ----------------------- |
|
|
| `latest` | Latest main branch build | On every push to main |
|
|
| `beta` | Beta release candidate | On main branch pushes |
|
|
| `v0.4.1` | Version-specific tag | After the `Publish Release Image Tags` workflow succeeds |
|
|
| `dev` | Development builds | On other branch pushes |
|
|
| `pr-123` | Pull request builds | On PR creation/updates |
|
|
|
|
### Image Availability
|
|
|
|
- **Public images**: No authentication required
|
|
- **Multi-architecture**: Images support `linux/amd64` and `linux/arm64`
|
|
- **Automatic updates**: Latest images are built automatically by CI/CD
|
|
- **Release contract**: A release tag is only valid for operators after the release-tag workflow publishes it, the anonymous GHCR verification step passes, and the public Compose smoke test succeeds. CI validates **`latest`** on every main push (`public-stack-contract` in `ci.yml`); **semver** tags are additionally checked when a GitHub Release is published and on a weekly schedule ([`verify-ghcr-release-tag.yml`](../../../.github/workflows/verify-ghcr-release-tag.yml)).
|
|
|
|
## Docker Compose Configuration
|
|
|
|
### Base Configuration (Production)
|
|
|
|
The default `docker-compose.yaml` uses prebuilt images:
|
|
|
|
```yaml
|
|
services:
|
|
sirius-ui:
|
|
image: ghcr.io/siriusscan/sirius-ui:${IMAGE_TAG:-latest}
|
|
pull_policy: always
|
|
# ... other configuration
|
|
|
|
sirius-api:
|
|
image: ghcr.io/siriusscan/sirius-api:${IMAGE_TAG:-latest}
|
|
pull_policy: always
|
|
# ... other configuration
|
|
|
|
sirius-engine:
|
|
image: ghcr.io/siriusscan/sirius-engine:${IMAGE_TAG:-latest}
|
|
pull_policy: always
|
|
# ... other configuration
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Control which images to use with the `IMAGE_TAG` environment variable:
|
|
|
|
```bash
|
|
# Use latest images (default)
|
|
docker compose up -d
|
|
|
|
# Use specific version
|
|
IMAGE_TAG=v0.4.1 docker compose up -d
|
|
|
|
# Use beta release
|
|
IMAGE_TAG=beta docker compose up -d
|
|
|
|
# Validate that the selected tag is publicly readable before rollout
|
|
bash scripts/verify-ghcr-public-access.sh "${IMAGE_TAG:-latest}"
|
|
```
|
|
|
|
`.env.production.example` leaves `IMAGE_TAG` blank so fresh installer runs inherit the Compose default (`latest`). Pin a release tag only after the publish workflow has validated that all six Sirius images exist for that tag.
|
|
|
|
### Development Override
|
|
|
|
For local development with source code changes, use the development override:
|
|
|
|
```bash
|
|
# Build locally with hot reloading
|
|
docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up -d --build
|
|
```
|
|
|
|
The `docker-compose.dev.yaml` file overrides the registry images with local builds, enabling:
|
|
|
|
- Hot reloading
|
|
- Volume mounts for source code
|
|
- Development-specific environment variables
|
|
- Debug logging
|
|
|
|
## Deployment Workflow
|
|
|
|
### Standard Production Deployment
|
|
|
|
1. **Clone repository**:
|
|
|
|
```bash
|
|
git clone https://github.com/SiriusScan/Sirius.git
|
|
cd Sirius
|
|
```
|
|
|
|
2. **Configure environment**:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.installer.yaml run --rm sirius-installer
|
|
# Optional: pass explicit values
|
|
# docker compose -f docker-compose.installer.yaml run --rm sirius-installer --non-interactive --no-print-secrets
|
|
```
|
|
|
|
3. **Deploy services**:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
4. **Verify deployment**:
|
|
|
|
```bash
|
|
docker compose ps
|
|
docker compose logs -f
|
|
```
|
|
|
|
5. **Check health**:
|
|
```bash
|
|
curl http://localhost:9001/health # API
|
|
curl http://localhost:3000/api/health # UI
|
|
```
|
|
|
|
### Maintainer Validation Path
|
|
|
|
Use the shared validation script to exercise the same public Compose path that operators use:
|
|
|
|
```bash
|
|
# Validate the default public stack (latest)
|
|
bash scripts/validate-public-compose-path.sh latest
|
|
|
|
# Validate a published release tag
|
|
bash scripts/validate-public-compose-path.sh v0.4.1
|
|
```
|
|
|
|
### Version-Specific Deployment
|
|
|
|
Deploy a specific version:
|
|
|
|
```bash
|
|
# Set version tag
|
|
export IMAGE_TAG=v0.4.1
|
|
|
|
# Confirm the compose-rendered GHCR images are public and readable
|
|
bash scripts/verify-ghcr-public-access.sh "$IMAGE_TAG"
|
|
|
|
# Pull and start services
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
### Updating Deployment
|
|
|
|
To update to the latest version:
|
|
|
|
```bash
|
|
# Pull latest images
|
|
docker compose pull
|
|
|
|
# Restart services with new images
|
|
docker compose up -d
|
|
```
|
|
|
|
## Fallback Strategy
|
|
|
|
### When Registry is Unavailable
|
|
|
|
If GitHub Container Registry is unavailable or images fail to pull, you can fall back to local builds:
|
|
|
|
1. **Use the committed source-build override**:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.yaml -f docker-compose.build.yaml up -d --build
|
|
```
|
|
|
|
**Note**: Local builds take significantly longer (20-25 minutes vs 5-8 minutes) and require more system resources.
|
|
|
|
## Secrets Hardening Overlays
|
|
|
|
For hardened deployments, Sirius includes optional overlay manifests:
|
|
|
|
- `docker-compose.secrets.yaml` for Compose secrets mounted at `/run/secrets/*`
|
|
- `docker-stack.swarm.yaml` for Swarm stack deployments
|
|
|
|
Example:
|
|
|
|
```bash
|
|
mkdir -p secrets
|
|
printf '%s' "your-postgres-password" > secrets/postgres_password.txt
|
|
printf '%s' "your-service-key" > secrets/sirius_api_key.txt
|
|
chmod 644 secrets/sirius_api_key.txt
|
|
printf '%s' "your-nextauth-secret" > secrets/nextauth_secret.txt
|
|
printf '%s' "your-admin-password" > secrets/initial_admin_password.txt
|
|
|
|
docker compose -f docker-compose.yaml -f docker-compose.secrets.yaml up -d
|
|
```
|
|
|
|
`sirius_api_key.txt` should stay **world-readable** (`644`) so bind-mounted `/run/secrets/sirius_api_key` is readable inside **sirius-api** / **sirius-ui** / **sirius-engine** (non-root UIDs).
|
|
|
|
## Troubleshooting
|
|
|
|
### Images Not Pulling
|
|
|
|
**Problem**: `docker compose pull` fails with authentication or network errors.
|
|
|
|
**Solutions**:
|
|
|
|
- Verify internet connectivity: `curl -I https://ghcr.io`
|
|
- Check image exists: Visit `https://github.com/SiriusScan/Sirius/pkgs/container/sirius-ui`
|
|
- Try pulling manually: `docker pull ghcr.io/siriusscan/sirius-ui:latest`
|
|
- Run the contract check: `bash scripts/verify-ghcr-public-access.sh "${IMAGE_TAG:-latest}"`
|
|
- If the script reports `Anonymous access denied`, the package is not publicly readable and the GHCR visibility workflow or token scope needs attention
|
|
- If the script reports `Manifest missing`, the requested tag was not published and you should verify the release-tag workflow completed successfully
|
|
- If the public Compose smoke test fails after pull succeeds, run `bash scripts/validate-public-compose-path.sh "${IMAGE_TAG:-latest}"` to reproduce the operator path and inspect the runtime contract failure
|
|
- Use fallback build strategy (see above)
|
|
|
|
### Wrong Version Deployed
|
|
|
|
**Problem**: Services are running an unexpected version.
|
|
|
|
**Solutions**:
|
|
|
|
- Check current IMAGE_TAG: `echo $IMAGE_TAG`
|
|
- Verify image tags: `docker compose images`
|
|
- Pull specific version: `IMAGE_TAG=v0.4.1 docker compose pull`
|
|
- Restart services: `docker compose up -d`
|
|
|
|
### Services Not Starting
|
|
|
|
**Problem**: Containers fail to start after pulling images.
|
|
|
|
**Solutions**:
|
|
|
|
- Check logs: `docker compose logs`
|
|
- Verify environment variables: `docker compose config`
|
|
- Check image compatibility: Ensure architecture matches (amd64/arm64)
|
|
- Verify dependencies: Ensure PostgreSQL, RabbitMQ, Valkey are running
|
|
|
|
### Performance Issues
|
|
|
|
**Problem**: Deployment is slower than expected.
|
|
|
|
**Solutions**:
|
|
|
|
- Check network speed: `docker pull` should be fast on good connections
|
|
- Verify image sizes: Large images take longer to pull
|
|
- Use specific version tags instead of `latest` for faster pulls
|
|
- Consider using image caching strategies
|
|
|
|
## Best Practices
|
|
|
|
### Security
|
|
|
|
- **Use specific version tags** in production (e.g., `v0.4.1`) instead of `latest`
|
|
- **Regularly update images** to get security patches
|
|
- **Scan images** for vulnerabilities using Docker security scanning
|
|
- **Use private registries** for sensitive deployments (if needed)
|
|
|
|
### Version Management
|
|
|
|
- **Pin versions** in production environments
|
|
- **Test updates** in staging before production
|
|
- **Document versions** deployed in each environment
|
|
- **Use semantic versioning** for releases
|
|
|
|
### Performance
|
|
|
|
- **Pre-pull images** before deployment to reduce startup time
|
|
- **Use image caching** to avoid redundant pulls
|
|
- **Monitor image sizes** and optimize Dockerfiles if needed
|
|
- **Use multi-stage builds** to reduce final image sizes
|
|
|
|
### Monitoring
|
|
|
|
- **Track deployment times** to measure improvements
|
|
- **Monitor registry availability** and fallback usage
|
|
- **Log image versions** deployed for audit trails
|
|
- **Alert on deployment failures** for quick response
|
|
|
|
## Comparison: Registry vs Local Builds
|
|
|
|
| Aspect | Registry Images | Local Builds |
|
|
| --------------------- | ----------------- | -------------------- |
|
|
| **Deployment Time** | 5-8 minutes | 20-25 minutes |
|
|
| **Resource Usage** | Low (pull only) | High (compilation) |
|
|
| **Network Required** | Yes (for pull) | No (after clone) |
|
|
| **Customization** | Limited | Full |
|
|
| **CI/CD Integration** | Automatic | Manual |
|
|
| **Best For** | Production, demos | Development, offline |
|
|
|
|
## Integration with CI/CD
|
|
|
|
### GitHub Actions
|
|
|
|
Images are automatically built and pushed by GitHub Actions on:
|
|
|
|
- Push to `main` branch → `latest` and `beta` tags
|
|
- Manual `Publish Release Image Tags` run → version-specific tag (e.g., `v0.4.1`)
|
|
- Pull requests → `pr-{number}` tags
|
|
|
|
### Deployment Automation
|
|
|
|
Example GitHub Actions workflow for deployment:
|
|
|
|
```yaml
|
|
name: Deploy Sirius
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Deploy with registry images
|
|
run: |
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
## Related Documentation
|
|
|
|
- [Terraform Deployment Guide](README.terraform-deployment.md) - AWS deployment using Terraform
|
|
- [Development Guide](../README.development.md) - Local development setup
|
|
- [Docker Architecture Guide](../architecture/README.docker-architecture.md) - Container architecture details
|
|
|
|
## Support
|
|
|
|
For issues with container deployment:
|
|
|
|
1. Check the troubleshooting section above
|
|
2. Review Docker logs: `docker compose logs`
|
|
3. Verify image availability on GitHub Container Registry
|
|
4. Create an issue in the Sirius repository
|
|
|
|
---
|
|
|
|
_This guide follows the Sirius Documentation Standard. For questions about documentation structure, see [ABOUT.documentation.md](../ABOUT.documentation.md)._
|