Skip to main content

Installation

The Docker installation runs the whole platform on one Linux server, as a Docker Compose stack. You do not write that stack yourself: octopize-deploy-tool asks you a few questions, generates every file (.env, docker-compose.yml, the Nginx configuration, the secrets and the Authentik setup), and starts it.

Before you start​

Go through the requirements shared by both self-hosted paths: hardware, registry credentials, domain name, TLS certificate, SMTP server and network flows. Then check the server itself:

  • Linux. Ubuntu 22.04 LTS or later is recommended.
  • A recent docker with the Compose plugin (as of writing, docker -v = 29.4.3 and docker compose version = v5.1.3), and curl.
  • The deploying user is in the docker group, see Docker's post-installation steps.
  • Python 3.13 or newer to run the deploy tool. Without it, run the tool from its Docker image.
Docker behind an HTTP proxy

If the Docker daemon or client uses an HTTP proxy, the Avatar containers silently fail to reach each other. Exclude the Compose subnet by adding "noProxy": "172.18.0.0/16" to the proxies.default block of /etc/docker/daemon.json or ~/.docker/config.json. The setting applies to newly created containers only.

Moving Docker's storage to a larger partition

Docker stores images in /var/lib/docker by default, and every upgrade adds images. To use another partition, set data-root in /etc/docker/daemon.json:

{
"data-root": "/data/docker"
}

Move the existing volumes there, then restart the daemon:

sudo systemctl daemon-reload
sudo systemctl restart docker
warning

Do not delete the avatar_postgres_data volume: it holds the database.

TLS certificate​

The deploy tool asks for the path of a PEM certificate (the full chain) and of its unencrypted private key. Give it absolute paths, and restrict access to the key:

chmod 600 /etc/ssl/avatar/server.key
chmod 644 /etc/ssl/avatar/fullchain.crt
Converting a PKCS#12 (.pfx) bundle to PEM
# Private key, then decrypted (Nginx needs an unencrypted key)
openssl pkcs12 -in certificate.pfx -nocerts -out server.encrypted.key
openssl rsa -in server.encrypted.key -out /etc/ssl/avatar/server.key

# Certificate and intermediate chain, concatenated into a full chain
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out server.crt
openssl pkcs12 -in certificate.pfx -cacerts -nokeys -chain -out chain.crt
cat server.crt chain.crt > /etc/ssl/avatar/fullchain.crt
Generating a self-signed certificate (test deployments only)

Once the deploy tool is installed:

octopize-deploy-tool tasks create-self-signed-cert \
--domain avatar.company.com \
--output-dir /etc/ssl/avatar

This writes fullchain.crt and server.key. Add --ip-address for IP SANs and --valid-days to change the 365-day default.

Install​

All commands use ./app/avatar as the deployment directory. Pick any directory, and use the same one for every later command.

1. Log in to the registry​

Run the docker login command that Octopize sent you. It looks like:

docker login -u='octopize+CUSTOMER_NAME' quay.io

2. Install the deploy tool​

pip install octopize-deploy-tool

Install it in a virtual environment: most distributions refuse installs into the system Python. You can also run it without installing it, with uv: uvx octopize-deploy-tool --help.

3. Generate the configuration​

octopize-deploy-tool install --app-root ./app/avatar

The tool asks for:

  • the public domain name, an environment name (for example mycompany-prod) and your organization name,
  • the paths to the TLS certificate and private key,
  • the SMTP server settings, or whether to use Octopize's mail service,
  • the email address of the Authentik administrator (akadmin),
  • whether to enable usage telemetry, and its credentials if you have them.

It generates every secret itself. Nothing is started yet. To install without prompts, see Installing without prompts.

4. Start the stack​

octopize-deploy-tool start --app-root ./app/avatar

The first start pulls the images, creates the Docker volumes and the databases, and sets up Authentik. It takes a few minutes.

5. Create the first users​

octopize-deploy-tool tasks create-users --app-root ./app/avatar \
--admins admin@company.com \
--users alice@company.com,bob@company.com

Each user receives an email with a link to set their password. See User management to add users later.

6. Verify the deployment​

octopize-deploy-tool tasks provision-admin --app-root ./app/avatar
octopize-deploy-tool verify --app-root ./app/avatar --test-email you@company.com

provision-admin creates the admin API key that verify uses. verify checks the API health and sends a test email. Then log in at https://<your-domain>/ with one of the accounts you created.

If a check fails, see Verification & Troubleshooting.

Where the configuration lives​

octopize-deploy-tool keeps the configuration in the deployment directory (./app/avatar in these pages):

./app/avatar/
├── user_config/ # yours: the tool never overwrites it
│ ├── config.example.yaml # commented reference, written by `install`
│ └── config.yaml # optional, your values
├── .deployment_states/ # one slot per configuration (v1, v2, …), kept for rollback
│ └── currently_deployed -> v2
└── generated_files/ # what Docker Compose runs: generated, do not edit
├── .env
├── docker-compose.yml
├── nginx/nginx.conf
├── authentik/
└── .secrets/

You set values in the questionnaire or in a YAML file under user_config/. The tool renders them into generated_files/. Do not edit generated_files/ by hand: every update regenerates it, and a manual edit blocks the next update until you resolve the conflict.

Changing a value​

Put only the values you want to change in a YAML file, and pass it to update. Everything else is carried forward:

change.yaml
SMTP_HOST: smtp.company.com
SMTP_PORT: 587
octopize-deploy-tool update --app-root ./app/avatar --from-config change.yaml
octopize-deploy-tool start --app-root ./app/avatar

update shows the diff before applying it. start recreates the containers that changed.

Installing without prompts​

To install without prompts, for example from automation, start from user_config/config.example.yaml. This minimal file is enough:

user_config/config.yaml
PUBLIC_URL: avatar.company.com
ENV_NAME: company-prod
ORGANIZATION_NAME: MyCompany
NGINX_SSL_CERTIFICATE_PATH: /etc/ssl/avatar/fullchain.crt
NGINX_SSL_CERTIFICATE_KEY_PATH: /etc/ssl/avatar/server.key
octopize-deploy-tool install --app-root ./app/avatar \
--from-config ./app/avatar/user_config/config.yaml --non-interactive

ORGANIZATION_NAME is required, although config.example.yaml does not list it.

Running the deploy tool from Docker​

If Python 3.13 is not available, or PyPI is blocked while quay.io is not, use the tool's image. It needs the Docker socket and the Compose plugin mounted:

export CP=$(docker info -f '{{range .ClientInfo.Plugins}}{{if eq .Name "compose"}}{{.Path}}{{end}}{{end}}')
docker run -it --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/docker.sock)" \
-v "$(pwd)/app/avatar:/app-root" -v /var/run/docker.sock:/var/run/docker.sock \
-v "$(which docker):/usr/local/bin/docker:ro" -v "$CP:$CP:ro" \
quay.io/octopize/deploy-tool:latest install --app-root /app-root

Replace install with any other command. At the prompts, type host paths (for example the TLS certificate), since Docker Compose reads them on the host. The deploy tool README has a ready-to-copy block for each command.

Next steps​