Service orchestration for OneTimeSecret: Podman Quadlets and systemd service management
Project description
ots-containers
Service orchestration CLI for OneTimeSecret infrastructure.
Dual-purpose management tool:
- Container orchestration: Containerized OTS deployments via Podman Quadlets (systemd integration)
- Service management: Native systemd services for dependencies (Valkey, Redis)
Installation
With pipx (Recommended)
pipx install git+https://github.com/onetimesecret/ots-containers.git
With pip
pip install git+https://github.com/onetimesecret/ots-containers.git
From source
git clone https://github.com/onetimesecret/ots-containers.git
cd ots-containers
pipx install .
Usage
ots-containers --help
ots-containers --version
Instance Types
Three container types with explicit systemd unit naming:
| Type | Unit Name | Identifier | Use |
|---|---|---|---|
--web |
onetime-web@{port} |
Port number | HTTP servers |
--worker |
onetime-worker@{id} |
Name/number | Background jobs |
--scheduler |
onetime-scheduler@{id} |
Name/number | Scheduled tasks |
Managing OTS Containers
# List all instances
ots-containers instances
ots-containers instances --json
# List by type
ots-containers instances --web
ots-containers instances --worker
ots-containers instances --scheduler
# Deploy instances
ots-containers instances deploy --web 7043 7044
ots-containers instances deploy --worker billing emails
ots-containers instances deploy --scheduler main
# Redeploy (regenerate quadlet and restart)
ots-containers instances redeploy # all running
ots-containers instances redeploy --web 7043 # specific
# Start/stop/restart
ots-containers instances start --web 7043
ots-containers instances stop --scheduler main
ots-containers instances restart # all running
# Status and logs
ots-containers instances status
ots-containers instances logs --web 7043 -f
ots-containers instances logs --scheduler main -f
# Enable/disable at boot
ots-containers instances enable --web 7043
ots-containers instances disable --scheduler main -y
# Interactive shell
ots-containers instances exec --web 7043
Managing systemd Services (Valkey, Redis)
# Initialize new service instance
ots-containers service init valkey 6379
ots-containers service init redis 6380 --bind 0.0.0.0
# Start/stop/restart
ots-containers service start valkey 6379
ots-containers service stop redis 6380
ots-containers service restart valkey 6379
# Status and logs
ots-containers service status valkey 6379
ots-containers service logs valkey 6379 --follow
# Enable/disable at boot
ots-containers service enable valkey 6379
ots-containers service disable redis 6380
# List available service packages
ots-containers service
Generating Cloud-Init Configurations
# Generate basic cloud-init config
ots-containers cloudinit generate > user-data.yaml
# Include PostgreSQL repository
ots-containers cloudinit generate --include-postgresql --postgresql-key /path/to/pgdg.asc
# Include Valkey repository
ots-containers cloudinit generate --include-valkey --valkey-key /path/to/valkey.gpg
# Validate configuration
ots-containers cloudinit validate user-data.yaml
Environment Variables
# Use a specific image tag
TAG=v0.23.0 ots-containers instances redeploy --web 7043
# Use a different image
IMAGE=ghcr.io/onetimesecret/onetimesecret TAG=latest ots-containers instances deploy --web 7044
Prerequisites
- Linux with systemd
- Podman installed and configured
- Python 3.11+
Server Setup
FHS-compliant directory structure:
OTS Container Configuration
/etc/onetimesecret/ # System configuration
├── config.yaml # Application configuration
├── auth.yaml # Authentication config
└── logging.yaml # Logging config
/etc/default/onetimesecret # Environment file (shared by all instances)
/etc/containers/systemd/ # Quadlet templates (managed by tool)
├── onetime-web@.container
├── onetime-worker@.container
└── onetime-scheduler@.container
/var/lib/onetimesecret/ # Runtime data
└── deployments.db # Deployment timeline (SQLite)
Service Configuration (Valkey/Redis)
/etc/valkey/ # Valkey system configuration
├── valkey.conf # Default config template
└── instances/ # Instance configs (created by tool)
├── 6379.conf
└── 6379-secrets.conf # Secrets file (mode 0640)
/var/lib/valkey/ # Runtime data
└── 6379/
└── dump.rdb
How It Works
Container Management
- Quadlet templates: Writes systemd unit templates to
/etc/containers/systemd/ - Environment: Reads from
/etc/default/onetimesecret - Secrets: Uses Podman secrets for sensitive values
- Timeline: Records deployments to SQLite for audit and rollback
Service Management
- Config files: Copies package defaults to instance-specific configs
- Secrets: Creates separate secrets files with restricted permissions
- Data directories: Creates per-instance data directories with correct ownership
- systemd: Manages services using package-provided templates
Troubleshooting
# Check instance status
ots-containers instances status
systemctl status onetime-web@7043
# View logs
ots-containers instances logs --web 7043 -f
journalctl -u onetime-web@7043 -f
# Unified log filtering (all instance types)
journalctl -t onetime -f
# List all onetime systemd units
systemctl list-units 'onetime-*'
# Verify Quadlet templates
cat /etc/containers/systemd/onetime-web@.container
# Reload systemd after manual changes
systemctl daemon-reload
Development
# Editable install
git clone https://github.com/onetimesecret/ots-containers.git
cd ots-containers
pip install -e ".[dev,test]"
# Run tests
pytest tests/
# Run with coverage (CI threshold: 70%)
pytest tests/ --cov=ots_containers --cov-fail-under=70
# Pre-commit hooks
pre-commit install
Running as root
# Use full path
sudo /home/youruser/.local/bin/ots-containers instances status
# Or create symlink
sudo ln -s /home/youruser/.local/bin/ots-containers /usr/local/bin/ots-containers
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rots-0.5.4.tar.gz.
File metadata
- Download URL: rots-0.5.4.tar.gz
- Upload date:
- Size: 373.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a659fb0c857d1d0807c44c5e5bb26db1957419d9d64934758832fe00c5edc75c
|
|
| MD5 |
9451112f042b1f46bfef2edb983c89ec
|
|
| BLAKE2b-256 |
4b1363e5eaee4517518474d733e0dc2c171b4c8ac988cd1663a9c252e97c1afb
|
Provenance
The following attestation bundles were made for rots-0.5.4.tar.gz:
Publisher:
release.yml on onetimesecret/rots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rots-0.5.4.tar.gz -
Subject digest:
a659fb0c857d1d0807c44c5e5bb26db1957419d9d64934758832fe00c5edc75c - Sigstore transparency entry: 1088910486
- Sigstore integration time:
-
Permalink:
onetimesecret/rots@f3f865e7a2f358b68846e093590edbe5a7ad1112 -
Branch / Tag:
refs/tags/v0.5.4 - Owner: https://github.com/onetimesecret
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f3f865e7a2f358b68846e093590edbe5a7ad1112 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rots-0.5.4-py3-none-any.whl.
File metadata
- Download URL: rots-0.5.4-py3-none-any.whl
- Upload date:
- Size: 143.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89cc625d8ddbcfbdd5439a0c6180469d07b07396847d318347503d118b6b632c
|
|
| MD5 |
81b27282ec9f01af8e06ea63a3f26eb6
|
|
| BLAKE2b-256 |
e2373aae0baed45a5b562bf79ca4353630565f15d790c49eb5665922b6bc5790
|
Provenance
The following attestation bundles were made for rots-0.5.4-py3-none-any.whl:
Publisher:
release.yml on onetimesecret/rots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rots-0.5.4-py3-none-any.whl -
Subject digest:
89cc625d8ddbcfbdd5439a0c6180469d07b07396847d318347503d118b6b632c - Sigstore transparency entry: 1088910542
- Sigstore integration time:
-
Permalink:
onetimesecret/rots@f3f865e7a2f358b68846e093590edbe5a7ad1112 -
Branch / Tag:
refs/tags/v0.5.4 - Owner: https://github.com/onetimesecret
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f3f865e7a2f358b68846e093590edbe5a7ad1112 -
Trigger Event:
push
-
Statement type: