# Deployment Patterns ## GitOps Pattern For production deployments, we recommend a GitOps approach where your deployment configuration is tracked in version control. ### Overview - **spec.yml is your source of truth**: Maintain it in your operator repository - **Don't regenerate on every restart**: Run `deploy init` once, then customize and commit - **Use restart for updates**: The restart command respects your git-tracked spec.yml ### Workflow 1. **Initial setup**: Run `deploy init` once to generate a spec.yml template 2. **Customize and commit**: Edit spec.yml with your configuration (hostnames, resources, etc.) and commit to your operator repo 3. **Deploy from git**: Use the committed spec.yml for deployments 4. **Update via git**: Make changes in git, then restart to apply ```bash # Initial setup (run once) laconic-so --stack my-stack deploy init --output spec.yml # Customize for your environment vim spec.yml # Set hostname, resources, etc. # Commit to your operator repository git add spec.yml git commit -m "Add my-stack deployment configuration" git push # On deployment server: deploy from git-tracked spec laconic-so deploy create \ --spec-file /path/to/operator-repo/spec.yml \ --deployment-dir my-deployment laconic-so deployment --dir my-deployment start ``` ### Updating Deployments When you need to update a deployment: ```bash # 1. Make changes in your operator repo vim /path/to/operator-repo/spec.yml git commit -am "Update configuration" git push # 2. On deployment server: pull and restart cd /path/to/operator-repo && git pull laconic-so deployment --dir my-deployment restart ``` The `restart` command: - Pulls latest code from the stack repository - Uses your git-tracked spec.yml (does NOT regenerate from defaults) - Syncs the deployment directory - Restarts services ### Anti-patterns **Don't do this:** ```bash # BAD: Regenerating spec on every deployment laconic-so --stack my-stack deploy init --output spec.yml laconic-so deploy create --spec-file spec.yml ... ``` This overwrites your customizations with defaults from the stack's `commands.py`. **Do this instead:** ```bash # GOOD: Use your git-tracked spec git pull # Get latest spec.yml from your operator repo laconic-so deployment --dir my-deployment restart ``` ## Private Registry Authentication For deployments using images from private container registries (e.g., GitHub Container Registry), configure authentication in your spec.yml: ### Configuration Add an `image-registry` section to your spec.yml: ```yaml image-registry: server: ghcr.io username: your-org-or-username token-env: REGISTRY_TOKEN ``` **Fields:** - `server`: The registry hostname (e.g., `ghcr.io`, `docker.io`, `gcr.io`) - `username`: Registry username (for GHCR, use your GitHub username or org name) - `token-env`: Name of the environment variable containing your API token/PAT ### Token Environment Variable The `token-env` pattern keeps credentials out of version control. Set the environment variable when running `deployment start`: ```bash export REGISTRY_TOKEN="your-personal-access-token" laconic-so deployment --dir my-deployment start ``` For GHCR, create a Personal Access Token (PAT) with `read:packages` scope. ### Ansible Integration When using Ansible for deployments, pass the token from a credentials file: ```yaml - name: Start deployment ansible.builtin.command: cmd: laconic-so deployment --dir {{ deployment_dir }} start environment: REGISTRY_TOKEN: "{{ lookup('file', '~/.credentials/ghcr_token') }}" ``` ### How It Works 1. laconic-so reads the `image-registry` config from spec.yml 2. Creates a Kubernetes `docker-registry` secret named `{deployment}-registry` 3. The deployment's pods reference this secret for image pulls