The workflow ran on every push to every branch and deployed nothing. It echoed the raw Vault login response, the Kanidm API token response and the OIDC token response to the job log, dumped the environment, and configured kubectl with --insecure-skip-tls-verify. Deployment is handled by gitops-update.yaml. Docs updated to describe that flow; T1 marked done in the cleanup task list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
193 lines
5.6 KiB
Markdown
193 lines
5.6 KiB
Markdown
# Deployment Guide
|
|
|
|
## Local Development
|
|
|
|
### Prerequisites
|
|
|
|
- **Python 3.13+** (required by `pyproject.toml`)
|
|
- **[uv](https://docs.astral.sh/uv/)** — Fast Python package manager
|
|
- Google Sheets API credentials (service account JSON)
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
git clone <repo-url>
|
|
cd fuj-management
|
|
|
|
# Install dependencies
|
|
uv sync
|
|
|
|
# Configure credentials
|
|
mkdir -p .secret
|
|
cp /path/to/credentials.json .secret/fuj-management-bot-credentials.json
|
|
|
|
# Optional: Set Fio API token for richer bank data
|
|
export FIO_API_TOKEN=your_token_here
|
|
|
|
# Start the web dashboard
|
|
make web
|
|
# → Flask server at http://localhost:5001
|
|
```
|
|
|
|
### Makefile Targets
|
|
|
|
| Target | Command | Description |
|
|
|--------|---------|-------------|
|
|
| `help` | `make help` | List all available targets |
|
|
| `venv` | `make venv` | Sync virtual environment with pyproject.toml |
|
|
| `fees` | `make fees` | Print fee calculation table |
|
|
| `match` | `make match` | (Legacy) Direct bank matching |
|
|
| `web` | `make web` | Start Flask dashboard on port 5001 |
|
|
| `sync` | `make sync` | Sync last 30 days of bank transactions |
|
|
| `sync-2026` | `make sync-2026` | Sync full year 2026 transactions |
|
|
| `infer` | `make infer` | Auto-fill Person/Purpose in the sheet |
|
|
| `reconcile` | `make reconcile` | Print CLI balance report |
|
|
| `test` | `make test` | Run test suite |
|
|
| `test-v` | `make test-v` | Run tests with verbose output |
|
|
| `image` | `make image` | Build Docker image |
|
|
| `run` | `make run` | Run Docker container locally |
|
|
|
|
The Makefile includes **automatic venv management**: targets that need Python depend on `.venv/.last_sync`, which triggers `uv sync` when `pyproject.toml` changes.
|
|
|
|
---
|
|
|
|
## Docker Container
|
|
|
|
### Building
|
|
|
|
```bash
|
|
make image
|
|
# → docker build -t fuj-management:latest -f build/Dockerfile .
|
|
```
|
|
|
|
### Dockerfile Details
|
|
|
|
**Base image**: `python:3.13-alpine`
|
|
|
|
**Build stages**:
|
|
1. Install system packages (`bash`, `tzdata`)
|
|
2. Set timezone to `Europe/Prague`
|
|
3. Install Python dependencies via pip
|
|
4. Copy application files (`app.py`, `scripts/`, `templates/`, `Makefile`)
|
|
5. Copy entrypoint script
|
|
|
|
**Exposed port**: 5001
|
|
|
|
**Health check**: `wget -q -O /dev/null http://localhost:5001/` every 60s
|
|
|
|
### Running Locally via Docker
|
|
|
|
```bash
|
|
make run
|
|
# → docker run -it --rm -p 5001:5001 fuj-management:latest
|
|
|
|
# With credentials and environment:
|
|
docker run -it --rm \
|
|
-p 5001:5001 \
|
|
-v $(pwd)/.secret:/app/.secret:ro \
|
|
-e FIO_API_TOKEN=your_token \
|
|
-e BANK_ACCOUNT=CZ8520100000002800359168 \
|
|
fuj-management:latest
|
|
```
|
|
|
|
### Entrypoint
|
|
|
|
The `build/entrypoint.sh` script simply runs:
|
|
```bash
|
|
exec python3 /app/app.py
|
|
```
|
|
|
|
This uses Flask's built-in server directly. For a production deployment, consider adding gunicorn or waitress (noted as a TODO in the entrypoint).
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `BANK_ACCOUNT` | `CZ8520100000002800359168` | IBAN for QR code generation |
|
|
| `FIO_API_TOKEN` | *(none)* | Fio REST API token |
|
|
| `PYTHONUNBUFFERED` | `1` (set in Dockerfile) | Ensures real-time log output |
|
|
|
|
---
|
|
|
|
## CI/CD Pipeline
|
|
|
|
### Gitea Actions
|
|
|
|
The project uses two Gitea Actions workflows:
|
|
|
|
#### 1. Build and Push (`build.yaml`)
|
|
|
|
**Triggers**:
|
|
- Push of any tag
|
|
- Manual dispatch (with custom tag input)
|
|
|
|
**Steps**:
|
|
1. Checkout code
|
|
2. Login to Gitea container registry (`gitea.home.hrajfrisbee.cz`)
|
|
3. Build Docker image using `build/Dockerfile`
|
|
4. Push to `gitea.home.hrajfrisbee.cz/<owner>/<repo>:<tag>`
|
|
|
|
**Tag resolution**: Uses the git tag name. For manual dispatch, uses the provided input.
|
|
|
|
#### 2. GitOps image update (`gitops-update.yaml`)
|
|
|
|
**Triggers**:
|
|
- Completion of a successful "Build and Push" run
|
|
- Manual dispatch (with `tag`, `dry_run` and `uh_cli_version` inputs)
|
|
|
|
**Steps**:
|
|
1. Install `tea` and `uh-cli`
|
|
2. Resolve the image tag of the Go image that was just built
|
|
3. Open a PR in `kacerr/home-kubernetes` bumping the `fuj-management` Deployment (namespace `fuj`) to that image
|
|
|
|
The cluster picks the change up once that PR is merged. CI does not talk to the cluster directly.
|
|
|
|
> The earlier `kubernetes-deploy.yaml` workflow (Vault → Kanidm → `kubectl`) was removed on 2026-10-08. It never deployed anything and printed credentials to the job log.
|
|
|
|
**Required secrets**:
|
|
|
|
| Secret | Purpose |
|
|
|--------|---------|
|
|
| `REGISTRY_TOKEN` | Docker registry authentication |
|
|
| `GITOPS_TOKEN` | Gitea token with write and PR access to `home-kubernetes` |
|
|
|
|
### Infrastructure Topology
|
|
|
|
```
|
|
Gitea (git push / tag)
|
|
│
|
|
├── build.yaml → Docker Build → Gitea Container Registry
|
|
│ (gitea.home.hrajfrisbee.cz)
|
|
│
|
|
└── gitops-update.yaml → PR in home-kubernetes → K8s Cluster
|
|
```
|
|
|
|
This is a self-hosted infrastructure stack:
|
|
- **Gitea** for git hosting and CI/CD
|
|
- **HashiCorp Vault** for secret management
|
|
- **Kanidm** for identity/OIDC
|
|
- **Kubernetes** for container orchestration
|
|
|
|
---
|
|
|
|
## Credentials Management
|
|
|
|
### Google Sheets API
|
|
|
|
The system uses a **Google Cloud service account** for accessing the Payments Google Sheet. The credentials file must be:
|
|
- Stored at `.secret/fuj-management-bot-credentials.json`
|
|
- In Google Cloud service account JSON format
|
|
- The service account must be shared (as editor) on the target Google Sheet
|
|
|
|
For local development with OAuth2 (personal Google account), the system also supports the OAuth2 installed app flow — it will generate a `token.pickle` file on first use.
|
|
|
|
### Fio Bank API
|
|
|
|
Optional. Set the `FIO_API_TOKEN` environment variable. The token is generated in Fio internetbanking under Settings → API.
|
|
|
|
**Rate limit**: 1 request per 30 seconds per token.
|
|
|
|
---
|
|
|
|
*Deployment documentation generated from comprehensive code analysis on 2026-03-03.*
|