Deployment configuration tool for Octopize Avatar platform
Project description
Octopize Avatar Deployment Tool
This package provides the octopize-deploy-tool CLI for operating a self-hosted Octopize Avatar
deployment. It bundles deployment templates for each release so it works without fetching files
from GitHub.
Available commands:
install— first-time setup: collects configuration interactively and generates all deployment files under a versioned app root directory.update— reconfigure an existing deployment: re-runs the configuration wizard seeded from the current state and regenerates the deployment files.migrate— migrates an existing flat deployment (from the legacy layout) to the new versioned directory structure.start— creates required Docker volumes and starts the deployment stack withdocker compose up.stop— suspends all running services withdocker compose stop, preserving containers and volumes for a fast restart.generate-env— generates per-component.envfiles for local development.authentik-migrate— migrates existing user data from CSV exports into authentik, the identity provider bundled with Avatar.
Installation
Option 1 — uvx (no install required, recommended for one-shot use)
uv can run the tool directly from PyPI without a permanent install.
If you don't have uv yet:
curl -LsSf https://astral.sh/uv/install.sh | sh
Then run any command directly:
uvx octopize-deploy-tool install --app-root ./app/avatar
Option 2 — virtual environment
Modern Linux distributions and macOS prevent installing packages into the system Python (PEP 668 — "externally managed environment"). A virtual environment avoids that:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install octopize-deploy-tool
octopize-deploy-tool install --app-root ./app/avatar
Option 3 — global pip
If your system Python allows global installs:
pip install octopize-deploy-tool
Verify the CLI is available:
octopize-deploy-tool --help
Option 4 — Docker (if PyPI is not accessible)
If PyPI is blocked in your environment (air-gapped networks, corporate proxies, or registries that allow quay.io but not PyPI), a pre-built Docker image is available:
docker pull quay.io/octopize/deploy-tool:latest
See the Docker section below for full usage examples for each command.
Quick Start
Set up a new deployment in two steps:
-
Run the configuration wizard to generate all deployment files:
octopize-deploy-tool install --app-root ./app/avatar
-
Start the deployment:
octopize-deploy-tool start --app-root ./app/avatar
Commands: When to Use What
| Command | Use when |
|---|---|
install |
Setting up a new Avatar deployment for the first time |
update |
Upgrading an existing deployment to a newer version of the Avatar application |
migrate |
Moving a deployment set up with the legacy layout to the new versioned structure |
start |
Bringing a configured deployment live, or restarting after a host reboot |
stop |
Suspending the running stack temporarily (preserves data; fast to restart) |
install
Use install when you are setting up Avatar for the first time. It runs the full configuration
wizard, collects all required values interactively (or from a seed config file), generates all
deployment files under a versioned directory tree, and leaves the deployment ready to start.
octopize-deploy-tool install --app-root ./app/avatar
To pre-populate answers from a YAML config file:
octopize-deploy-tool install \
--app-root ./app/avatar \
--from-config config.yaml \
--non-interactive
Common install options:
--app-root PATH Root directory for the deployment (default: current directory)
--from-config PATH YAML seed config to pre-populate answers
--non-interactive Run without prompts; fails fast if any required value is missing
--verbose Show detailed progress output
update
Use update when you are upgrading to a newer version of the Avatar application. It carries your
existing configuration forward unchanged, re-renders the deployment files using the new templates
bundled in the updated deploy tool, diffs the result against the currently running files, and
applies the changes.
octopize-deploy-tool update --app-root ./app/avatar
After update, run start to apply the new files to the running stack:
octopize-deploy-tool start --app-root ./app/avatar
Need to change a configuration value (URL, TLS certificate, email settings, …)?
updateis not the right tool for that — it carries existing values forward without re-asking questions. To go through the configuration wizard again, use:octopize-deploy-tool configure --fresh --app-root ./app/avatar
Common update options:
--app-root PATH Root directory for the deployment (default: current directory)
--non-interactive Run without prompts
--verbose Show detailed progress output
migrate
Use migrate when you have a deployment that was generated by the legacy flat layout (a directory
containing .env and .secrets/) and want to bring it under the new versioned directory
structure. migrate reads the existing .env and .secrets/ files to pre-seed all configuration
values so you do not have to re-enter them.
octopize-deploy-tool migrate \
--app-root ./app/avatar-new \
--from-legacy ./app/avatar-old
After migrate, run start to bring the migrated deployment live:
octopize-deploy-tool start --app-root ./app/avatar-new
Common migrate options:
--app-root PATH Root directory for the new versioned deployment (default: current directory)
--from-legacy DIR Path to the existing flat deployment directory (required)
--non-interactive Run without prompts
--verbose Show detailed progress output
start
Use start to create the required Docker volumes and bring the deployment stack live. Run it after
install, migrate, or update. start is idempotent — if a volume already exists it is left
unchanged, making it safe to re-run after a host reboot.
octopize-deploy-tool start --app-root ./app/avatar
Common start options:
--app-root PATH Root directory for the deployment (default: current directory)
--verbose Show detailed progress output
stop
Use stop to suspend the running stack without removing containers or volumes. This is the
complement of start — services can be brought back up quickly with start without losing
any data.
octopize-deploy-tool stop --app-root ./app/avatar
Common stop options:
--app-root PATH Root directory for the deployment (default: current directory)
--verbose Show detailed progress output
Docker
If you don't have Python installed, you can use the published Docker image instead:
quay.io/octopize/deploy-tool:latest
Note on file ownership: For commands that write files to a bind-mounted directory, run the container with
--user "$(id -u):$(id -g)"so generated files are owned by your host user.
install
Interactive:
docker run -it --rm \
--user "$(id -u):$(id -g)" \
-v "$(pwd)/avatar:/app-root" \
quay.io/octopize/deploy-tool:latest install --app-root /app-root
Non-interactive, seed config inside the app-root:
docker run --rm \
--user "$(id -u):$(id -g)" \
-v "$(pwd)/avatar:/app-root" \
quay.io/octopize/deploy-tool:latest install \
--app-root /app-root \
--from-config /app-root/config.yaml \
--non-interactive
Non-interactive, seed config stored outside the app-root:
Mount the directory containing the config file as a separate read-only volume:
docker run --rm \
--user "$(id -u):$(id -g)" \
-v "$(pwd)/avatar:/app-root" \
-v "$(pwd)/config:/input:ro" \
quay.io/octopize/deploy-tool:latest install \
--app-root /app-root \
--from-config /input/config.yaml \
--non-interactive
Important — enter host paths during configuration: When the wizard asks for filesystem paths — such as the path to your TLS certificate or private key — enter the path where that file exists on your host machine, not the path inside this container.
For example, if your TLS certificate lives at
/etc/ssl/avatar/server.crton the host, enter/etc/ssl/avatar/server.crtat the prompt. Docker Compose will mount those paths from the host when it starts the Avatar services.If your TLS certificate is not mounted into the deploy tool container — that is, you are running the deploy tool itself inside Docker and you enter a host-side certificate path that does not exist inside the deploy tool container — add
--skip-tls-path-validationto bypass the existence check:docker run --rm \ --user "$(id -u):$(id -g)" \ -v "$(pwd)/avatar:/app-root" \ -v "$(pwd)/config:/input:ro" \ quay.io/octopize/deploy-tool:latest install \ --app-root /app-root \ --from-config /input/config.yaml \ --non-interactive \ --skip-tls-path-validation
update
Mount the existing app-root. If your --from-config override file lives outside the app-root,
add a second read-only mount (same pattern as install):
docker run -it --rm \
--user "$(id -u):$(id -g)" \
-v "$(pwd)/avatar:/app-root" \
quay.io/octopize/deploy-tool:latest update --app-root /app-root
migrate
Mount both the new app-root and the legacy deployment directory as a separate read-only volume.
The --from-legacy path must point to its container-side location:
docker run -it --rm \
--user "$(id -u):$(id -g)" \
-v "$(pwd)/avatar-new:/app-root" \
-v "$(pwd)/avatar-old:/legacy:ro" \
quay.io/octopize/deploy-tool:latest migrate \
--app-root /app-root \
--from-legacy /legacy
start
start calls Docker directly (to create volumes and run docker compose up), so the host Docker
socket must be mounted:
docker run --rm \
-v "$(pwd)/avatar:/app-root" \
-v /var/run/docker.sock:/var/run/docker.sock \
quay.io/octopize/deploy-tool:latest start --app-root /app-root
Note:
--useris omitted here because the process needs access to the Docker socket. If you see a permission error, add--group-add $(stat -c '%g' /var/run/docker.sock)to grant the container access to the socket's group on the host.
stop
Like start, stop calls Docker directly and requires the host Docker socket:
docker run --rm \
-v "$(pwd)/avatar:/app-root" \
-v /var/run/docker.sock:/var/run/docker.sock \
quay.io/octopize/deploy-tool:latest stop --app-root /app-root
Non-Interactive Usage
Provide a YAML configuration file to skip interactive prompts. Any value not covered by the config file will use the built-in default.
Example seed config:
PUBLIC_URL: avatar.example.com
ENV_NAME: prod
ORGANIZATION_NAME: MyCompany
Then run:
octopize-deploy-tool install \
--app-root ./app/avatar \
--from-config config.yaml \
--non-interactive
Generated Files
The install command writes deployment files under a versioned directory tree:
./app/avatar/
├── .deployment_states/
│ └── v1/
│ ├── deployment_state.yaml
│ └── generated/ # reference copy of rendered files (read-only)
├── customer_inputs/ # operator-owned configuration overrides
└── generated_files/ # what Docker Compose actually uses
├── .env
├── docker-compose.yml
├── nginx/nginx.conf
├── authentik/
│ ├── octopize-avatar-blueprint.yaml
│ ├── custom-templates/
│ └── branding/
└── .secrets/
Each subsequent update or migrate run adds a new versioned slot (e.g. v2/), keeping a full
history of prior states.
The generate-env command writes component .env files directly to their resolved destinations:
./avatar-local/
├── api/.env
└── web/.env
Typical Deployment Workflow
-
Generate configuration:
octopize-deploy-tool install --app-root ./app/avatar
-
Review the generated files:
ls ./app/avatar/generated_files/ cat ./app/avatar/generated_files/.env ls -la ./app/avatar/generated_files/.secrets/
-
Add any required TLS certificates for production.
-
Start the services:
octopize-deploy-tool start --app-root ./app/avatar
-
Verify the deployment:
octopize-deploy-tool verify --app-root ./app/avatar --test-email your@email.com
This checks the Avatar API health (
/health/config-full-check) and runs an Authentik email delivery test. Pass--test-emailwith an address you can receive mail at to confirm SMTP is working.
generate-env
Use generate-env to create per-component .env files for local development without generating
the full deployment bundle.
Example:
octopize-deploy-tool generate-env \
--component api \
--api-output-path ./avatar-local/api/.env \
--component web \
--web-output-path ./avatar-local/web/.env
Common generate-env options:
--config FILE YAML configuration file to load
--non-interactive Run without prompts, using config/defaults
--verbose Show detailed progress output
--component NAME Generate only the selected component (repeatable; defaults to all)
--api-output-path PATH Override the API env output path for this run
--web-output-path PATH Override the web env output path for this run
--python-client-output-path PATH
Override the python_client env output path for this run
--output-path COMPONENT=PATH
Repeatable generic output-path override
--target NAME Load named URLs from the environments config section
--api-url URL Override the API URL
--storage-url URL Override the storage public URL
--sso-url URL Override the SSO provider URL
Troubleshooting
Services fail to start after start
Check that Docker is running and the generated files are present:
ls ./app/avatar/generated_files/
docker compose -f ./app/avatar/generated_files/docker-compose.yml ps
docker compose -f ./app/avatar/generated_files/docker-compose.yml logs -f
Existing containers cause bind-mount or startup issues
Stop and remove old containers and volumes, then restart:
docker compose -f ./app/avatar/generated_files/docker-compose.yml down --volumes --remove-orphans
octopize-deploy-tool start --app-root ./app/avatar
Verbose output for debugging
Add --verbose to any command to see detailed progress and template rendering output:
octopize-deploy-tool install --app-root ./app/avatar --verbose
Migrating Users to authentik
When upgrading from an older Avatar deployment that managed users directly in the Avatar API
database, use octopize-deploy-tool authentik-migrate to import those users into authentik.
Overview
The tool reads three CSV exports from the Avatar database and creates the equivalent users, groups, and group assignments in authentik via its REST API:
| Source CSV | authentik entity |
|---|---|
organizations.csv |
Groups (one per org) |
licenses.csv |
Group attributes.license |
users.csv |
Users with attributes.role |
Users that already have an authentik_id value in the CSV are automatically skipped, making the
tool safe to run incrementally.
Extracting CSV Data
Exec into the API container and export the required tables:
docker compose exec -it api bash
cd /app/avatar
python bin/dbtool.py shell
Then in the pgcli shell:
\copy (SELECT * FROM licenses) TO '/tmp/licenses.csv' WITH CSV HEADER
\copy (SELECT * FROM users) TO '/tmp/users.csv' WITH CSV HEADER
\copy (SELECT * FROM organizations) TO '/tmp/organizations.csv' WITH CSV HEADER
Usage
Dry run — preview all operations without making any changes:
octopize-deploy-tool authentik-migrate \
--users /tmp/users.csv \
--orgs /tmp/organizations.csv \
--licenses /tmp/licenses.csv \
--dry-run
Full migration — execute against a live authentik instance:
octopize-deploy-tool authentik-migrate \
--users /tmp/users.csv \
--orgs /tmp/organizations.csv \
--licenses /tmp/licenses.csv \
--authentik-url https://avatar.example.com/sso \
--authentik-token YOUR_API_TOKEN
The authentik URL is the /sso path of your Avatar instance. The API token is generated
automatically by the deploy tool and stored in the .env file.
Every run writes a JSONL log (migration_log.jsonl by default). If some operations fail, retry
just the failed ones:
octopize-deploy-tool authentik-migrate \
--from-log migration_log.jsonl \
--failed-only \
--authentik-url https://avatar.example.com/sso \
--authentik-token YOUR_API_TOKEN
Getting an authentik API Token
- Log in to your authentik instance
- Navigate to Admin → Tokens & App passwords
- Create a token with the following permissions:
core:groups:createcore:users:createcore:groups:update(for user assignments)
Migration CLI Reference
octopize-deploy-tool authentik-migrate [options]
--users PATH Path to users CSV file
--orgs PATH Path to organizations CSV file
--licenses PATH Path to licenses CSV file
--authentik-url URL Base URL of the authentik instance
(e.g. https://avatar.example.com/sso)
--authentik-token TOK API token for authentik
--dry-run Preview operations without executing
--log PATH JSONL log output path (default: migration_log.jsonl)
--from-log PATH Replay operations from a previous log instead of CSV
--failed-only With --from-log, only replay previously-failed ops
Further Information
- Source repository: https://github.com/octopize/avatar
- Deployment documentation: https://docs.octopize.io/docs/deploying/self-hosted
- Network topology reference: docs/network-topology.md
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 octopize_deploy_tool-2.9.0.tar.gz.
File metadata
- Download URL: octopize_deploy_tool-2.9.0.tar.gz
- Upload date:
- Size: 893.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3579d681f2c0f8613f56ebf71bc3af6b7a6507fefe26c4e7fa072562d392f81
|
|
| MD5 |
c008d1103e9dcfbc0d80d7be2b336951
|
|
| BLAKE2b-256 |
dbe5b01cd50689d8e4f3479f65c3ff4d560285c83445e8c21cd60c559fd68ff0
|
File details
Details for the file octopize_deploy_tool-2.9.0-py3-none-any.whl.
File metadata
- Download URL: octopize_deploy_tool-2.9.0-py3-none-any.whl
- Upload date:
- Size: 243.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bc2b89c961d1d3f1894f123dcf901c6edbfc0c4d2b7e4d5ff8e0411aa52c912
|
|
| MD5 |
2c21ac199a24bb6238c3d3202148cb28
|
|
| BLAKE2b-256 |
0c660895103c7973fbe10f3dbf5d449f4ba783d12378c7ec4c1fca793893bb35
|