Surek
Surek is a Docker Compose orchestration tool for self-hosted services.
It manages Caddy reverse proxy for your containers with automatic HTTPS, backs up Docker volumes to S3-compatible storage, and includes Portainer and Netdata for container management and server monitoring.
Features
- Reverse proxy: Automatic Caddy configuration with Let's Encrypt HTTPS
- Volume backups: Scheduled backups to S3-compatible storage with optional encryption
- Shared networking: All stacks on a common network for easy inter-service communication
- Interactive TUI: Terminal UI for managing stacks and backups
- GitHub integration: Pull stacks from public or private repositories
Installation
Surek requires Python 3.12+, Docker with Compose plugin, and a domain pointed to your server.
If you have Surek v1 installed, remove it first:
npm uninstall -g surek
# or
sudo npm uninstall -g surek
Then install v2:
# Using uv (recommended)
uv tool install surek
# Using pip
pip install surek
If your Docker requires sudo, install and run Surek with sudo as well.
Shell Completion
Enable tab completion for commands and stack names:
surek --install-completion
Restart your shell after installation.
Concepts
How Surek Works
Surek acts as a layer on top of Docker Compose. Main entity in Surek is "stack". Stack is a collection of related services. Each stack lives in its own directory under stacks/.
Minimally, stack consist of config file surek.stack.yml which describes where files should be pulled from (GitHub or local filesystem), which services should be exposed and on which subdomains, what volumes should be included or excluded in backup.
Another important piece is docker-compose.yml. If you're pulling project from GitHub and it already has docker-compose.yml in the repository (and you're happy with configuration in it), you can use it. Surek allows you to pass environment variables to containers directly in stack config, but if you need bigger customization you'll need to write your own docker-compose.yml.
Good news is: you can write your compose file as you used to. Surek doesn't require any special format except couple of conventions (see below).
Surek then will use stack config and docker-compose.yml to deploy described services according to config and expose them on pre-defined subdomains, and will take care of backup.
System Stack
Surek includes a special system stack that provides core infrastructure:
- Caddy - Reverse proxy with automatic HTTPS
- Portainer - Web UI for container management (optional)
- Netdata - Server monitoring dashboard (optional)
- Backup - Scheduled volume backups to S3 (if configured)
You'll need to start the system stack before deploying your own stacks.
Quick Start
Surek works great with LLM agents. So if you'd prefer to outsource the work to them, here is prompt template for you. Just add to it what you want to deploy.
Deploy <you service name and details> using `surek`.
Surek is a Docker Compose orchestration tool for self-hosted services. Run `surek --help-readme` to get quickstart documentation or `surek --help-llm` to get full documentation. Check whether current folder is already initialized as Surek project. Initialize if not. If you require additional data from me (like root domain) —pause and ask. Then create new stack and configure it according to deployed service. Make no mistake.
You can make your favorite LLM agent do the work for you. Agents can get complete Surek documentation by running surek --help-llm. Just tell it what you want to deploy and let metal head figure out the rest. Here is prompt template for you.
Initialize a new Surek project. This creates surek.yml where you'll configure your root domain, default credentials, and optional backup settings.
surek init
If you need to edit this configuration later, just edit surek.yml file. Now start the system stack. This launches Caddy (reverse proxy), Portainer, and Netdata. Required before deploying your own stacks.
surek start system
Visit portainer.<your domain> within 5 minutes after first start to complete setup or it will lock you out and require removing volume and re-installing it.
Next step is to create your first stack. You can use interactive wizard to prefil basic info. This scaffolds a stack directory with surek.stack.yml and optionally a docker-compose.yml.
surek new
Or you can manually create the folder stacks/my-stack and surek.stack.yml inside it.
After configuring your stack, deploy it. This pulls sources (if stack source is GitHub), transforms the compose file, and starts containers.
Content of stack folder will be available to be used in your docker-compose.yml. You can use this to provide additional files that can be used by stack (e.g. service-specific configuration files). For stacks pulled from GitHub, content of stack folder will be recursively merged with repository content. You can use this to provide additional files or override existing files in the repository.
surek deploy my-stack
If your stack exposes any public services, you can now visit respective subdomain and see your service running.
Check the status of all stacks, or launch the interactive TUI for a dashboard view.
surek status
# Or launch TUI
surek
Configuration schemas
Main Config (surek.yml)
Create this file in your project directory:
# Required: Root domain for all services
root_domain: example.com
# Required: Default auth in "user:password" format
default_auth: admin:${SUREK_PASSWORD}
# Optional: S3 backup configuration
backup:
# Optional: GPG password; omit to upload backups unencrypted
password: ${BACKUP_PASSWORD}
s3_endpoint: s3.example.com
s3_bucket: my-backups
s3_access_key: ${AWS_ACCESS_KEY}
s3_secret_key: ${AWS_SECRET_KEY}
# Optional: scratch space for backup and restore features (absolute path)
temp_dir: /mnt/backup-tmp
# Optional: GitHub access for private repos
github:
pat: ${GITHUB_PAT}
# Optional: Enable/disable system services
system_services:
portainer: true
netdata: true
# Optional: default log rotation for services that don't set their own
log_rotation:
enabled: true
driver: json-file
max_size: 10m
max_file: 3
Stack Config (stacks/<name>/surek.stack.yml)
name: my-app
# Source: local files or GitHub
source:
type: local
# OR
# type: github
# slug: owner/repo#branch
# Path to compose file (default: ./docker-compose.yml)
compose_file_path: ./docker-compose.yml
# Public endpoints for reverse proxy
public:
- domain: app.<root>
target: myapp:8080
auth: <default_auth> # Optional: basic auth
# Environment variables
env:
shared:
- TZ=UTC
by_container:
myapp:
- DATABASE_URL=postgres://...
# Backup settings
backup:
exclude_volumes:
- cache_data
Commands
| Command | Description |
|---|---|
surek |
Launch interactive TUI |
surek init |
Create surek.yml interactively |
surek new |
Create a new stack interactively |
surek schema |
Generate JSON schemas for editor autocompletion |
surek deploy <stack> |
Deploy a stack (use system for system containers) |
surek deploy <stack> --pull |
Deploy and force re-pull sources and Docker images |
surek start <stack> |
Start an already deployed stack |
surek stop <stack> |
Stop a running stack |
surek status |
Show status of all stacks |
surek status --stats |
Include CPU/memory usage (slower) |
surek info <stack> |
Show detailed stack information |
surek logs <stack> [service] |
View stack logs (-f to follow) |
surek validate <path> |
Validate a stack config |
surek reset <stack> |
Stop stack and delete all its data |
surek prune |
Remove unused Docker resources |
surek prune --volumes |
Also remove unused volumes |
surek backup list |
List all backups |
surek backup run |
Trigger immediate backup |
surek backup restore |
Restore from backup |
Note: The system stack name is reserved for Surek's system containers (Caddy, Portainer, Netdata, Backup). Use surek start system, surek stop system, etc.
Template Variables
Use these in stack configs (e.g. in public.domain, public.auth, env) or docker-compose.yml:
| Variable | Description |
|---|---|
<root> |
Root domain from surek.yml |
<default_auth> |
Default auth (user:password) |
<default_user> |
Username from default_auth |
<default_password> |
Password from default_auth |
<backup_password> |
Backup encryption password |
<backup_s3_endpoint> |
S3 endpoint URL |
<backup_s3_bucket> |
S3 bucket name |
<backup_s3_access_key> |
S3 access key |
<backup_s3_secret_key> |
S3 secret key |
Directory Structure
project/
├── surek.yml # Main configuration
├── stacks/ # User-defined stacks
│ └── my-app/
│ ├── surek.stack.yml
│ └── docker-compose.yml
└── surek-data/ # Generated (add to .gitignore)
├── projects/ # Deployed stack files
└── volumes/ # Bound volumes for backup
Writing Compose Files
When writing Docker Compose files for Surek:
-
Use named volumes: Surek can reliably backup only named volumes without additional configuration (like custom driver). Bind mounts or volumes with custom configuration will still work, but won't be backed up.
-
Unique service names: since all stacks share same network, each of services in your
docker-compose.ymlhave to have unique name. For example, if you have two separate web apps both of which use Postgres, and you want to use separate Postgres instance for each, you have to give each of them unique name, they can't both bepostgres. You can name them something likepostgres-fooandpostgres-bar. -
No port exposure needed: Caddy will route incoming traffic directly through shared network, so there is no need to expose ports from container (though doing that won't brake anything either).
Examples
See the example-stacks folder for sample configurations.
LLM Integration
For AI assistants, run surek --help-llm to get complete documentation.
Backward Compatibility
Surek v2 is fully backward compatible with v1 configuration files. All existing surek.yml and surek.stack.yml files work without modification. Source code for v1 can be found in v1 branch.
Development
# Install dependencies
uv sync
# Run from source
uv run surek
# Install local copy as a tool
uv tool install -e .
# Type checking
uv run mypy src/surek
# Linting
uv run ruff check src/surek
Publishing to PyPI
uv build
uv publish
Metadata
Release files for surek 2.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| surek-2.1.0.tar.gz | 70.6 kB | Without provenance | Details for surek-2.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| surek-2.1.0-py3-none-any.whl | Python 3 | none | any | Details for surek-2.1.0-py3-none-any.whl |
Total release size: 157.9 kB
Release files / surek-2.1.0.tar.gz
| Download URL | surek-2.1.0.tar.gz |
|---|---|
| Size | 70.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
646fef152622689edfec51bb7996458a42dbcdb077e3380a628767080a0a936e
|
|
BLAKE2b-256 checksum How to use checksums |
278b65b3da53210f50bb73d543e1020fc0f23fb21e1c9d24eb15d0ee00a39923
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / surek-2.1.0-py3-none-any.whl
| Download URL | surek-2.1.0-py3-none-any.whl |
|---|---|
| Size | 87.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e17423184e927a9af57e9f9a52c30e60c6d66f04bdf84c68a6dcc43ae52706f9
|
|
BLAKE2b-256 checksum How to use checksums |
63fbc771eba357f602dd7c9e7b612c0cfe132acd9de8e0cd618fae4142aae9b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for surek 2.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.