Metadata-Version: 2.4
Name: octopize.deploy_tool
Version: 2.6.0
Summary: Deployment configuration tool for Octopize Avatar platform
Project-URL: Homepage, https://octopize.io
Project-URL: Documentation, https://docs.octopize.io/docs/deploying/self-hosted
Project-URL: Repository, https://github.com/octopize/avatar
Project-URL: Issues, https://github.com/octopize/avatar/issues
Author-email: Octopize <contact@octopize.io>
License: MIT
Keywords: avatar,configuration,deployment,octopize
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Installation/Setup
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.13
Requires-Dist: httpx>=0.28.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: pandas>=3.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0.0
Provides-Extra: dev
Requires-Dist: pyright>=1.1.402; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# 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 subcommands:

- **`deploy`** — generates the Docker Compose configuration files needed to run the platform.
- **`generate-env`** — generates per-component `.env` files for local development.
- **`authentik-migrate`** — migrates existing user data from CSV exports into
  [authentik](https://goauthentik.io/), the identity provider bundled with Avatar.

## Installation

### Option 1 — uvx (no install required, recommended for one-shot use)

[uv](https://docs.astral.sh/uv/) can run the tool directly from PyPI without a permanent install.
If you don't have `uv` yet:

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Then run any command directly:

```bash
uvx octopize-deploy-tool deploy --output-dir ./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:

```bash
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install octopize-deploy-tool
octopize-deploy-tool deploy --output-dir ./app/avatar
```

### Option 3 — global pip

If your system Python allows global installs:

```bash
pip install octopize-deploy-tool
```

Verify the CLI is available:

```bash
octopize-deploy-tool deploy --help
```

## Docker

If you don't have Python installed, you can use the published Docker image instead.

### Interactive mode

Mount a local directory to receive the generated files and pass `-it` for the interactive prompts:

```bash
docker run -it --rm \
  --user "$(id -u):$(id -g)" \
  -v "$(pwd)/avatar:/output" \
  quay.io/octopize/deploy-tool:latest deploy --output-dir /output
```

### Non-interactive mode

Provide a config file via the mounted volume:

```bash
docker run --rm \
  --user "$(id -u):$(id -g)" \
  -v "$(pwd)/avatar:/output" \
  quay.io/octopize/deploy-tool:latest deploy \
    --output-dir /output/config \
    --config /output/config.yaml \
    --non-interactive
```

> **Note:** For bind-mounted output directories, run the container with `--user "$(id -u):$(id -g)"` so generated files are owned by your host user.

## Quick Start

Generate a Docker deployment configuration interactively:

```bash
octopize-deploy-tool deploy --output-dir ./app/avatar
```

Then start the deployment:

```bash
cd ./app/avatar
docker compose down --volumes --remove-orphans
docker compose up -d
```

## Commands

```text
octopize-deploy-tool deploy [options]
octopize-deploy-tool generate-env [options]
octopize-deploy-tool authentik-migrate [options]
```

Running the CLI without a subcommand is not supported — use `--help` on a subcommand:

```bash
octopize-deploy-tool deploy --help
octopize-deploy-tool generate-env --help
octopize-deploy-tool authentik-migrate --help
```

### `deploy`

Use `deploy` to generate a full Docker Compose deployment.

Example:

```bash
octopize-deploy-tool deploy --output-dir ./app/avatar
```

Common `deploy` options:

```text
--output-dir DIR           Output directory for generated files
--config FILE              YAML configuration file to load
--non-interactive          Run without prompts, using config/defaults
--save-config              Save the resolved configuration to deployment-config.yaml
--verbose                  Show detailed progress output
--mode {production,dev}    Generate production or dev deployment assets
```

### `generate-env`

Use `generate-env` to create per-component `.env` files for local development without generating
the full deployment bundle.

Example:

```bash
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:

```text
--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
```

## Non-Interactive Usage

You can provide configuration through a YAML file:

```yaml
PUBLIC_URL: avatar.example.com
ENV_NAME: prod
ORGANIZATION_NAME: MyCompany
```

Then run:

```bash
octopize-deploy-tool deploy \
  --output-dir ./app/avatar \
  --config config.yaml \
  --non-interactive
```

## Generated Files

The `deploy` command typically writes:

```text
./app/avatar/
├── .env
├── docker-compose.yml
├── nginx/nginx.conf
├── authentik/
│   ├── octopize-avatar-blueprint.yaml
│   ├── custom-templates/
│   └── branding/
└── .secrets/
```

The `generate-env` command writes component env files directly to their resolved destinations,
for example:

```text
./avatar-local/
├── api/.env
└── web/.env
```

## Typical Deployment Workflow

1. Generate configuration:

   ```bash
   octopize-deploy-tool deploy --output-dir ./app/avatar
   ```

2. Review the generated files:

   ```bash
   cd ./app/avatar
   cat .env
   ls -la .secrets/
   ```

3. Add any required TLS certificates for production.

4. Start the services:

   ```bash
   docker compose up -d
   ```

5. Verify the deployment:

   ```bash
   docker compose ps
   docker compose logs -f
   ```

## Troubleshooting

### Bundled templates fail to provision or validate

Retry with verbose output:

```bash
octopize-deploy-tool deploy --output-dir ./app/avatar --verbose
```

### Existing containers cause bind-mount or startup issues

Clean up old containers and volumes before retrying:

```bash
docker compose down --volumes --remove-orphans
docker compose up -d
```

## 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:

```bash
docker compose exec -it api bash
cd /app/avatar
python bin/dbtool.py shell
```

Then in the pgcli shell:

```sql
\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:

```bash
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:

```bash
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:

```bash
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

1. Log in to your authentik instance
2. Navigate to **Admin** → **Tokens & App passwords**
3. Create a token with the following permissions:
   - `core:groups:create`
   - `core:users:create`
   - `core:groups:update` (for user assignments)

### Migration CLI Reference

```text
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](docs/network-topology.md)
