Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ config/clients/*
!config/clients/.gitkeep
!config/clients/example.yaml

# Docker env file with real credentials
docker/.env

# OS
.DS_Store
Thumbs.db
15 changes: 15 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copy to docker/.env and fill in before running docker compose.
# Never commit docker/.env to version control.

# XWiki database password (choose a strong password)
XWIKI_DB_PASSWORD=change-me-xwiki

# Redmine database password (choose a strong password)
REDMINE_DB_PASSWORD=change-me-redmine

# Redmine secret key base — generate with: openssl rand -hex 64
REDMINE_SECRET_KEY_BASE=change-me-generate-with-openssl-rand-hex-64

# qms-kit runtime credentials (used by the adapters, not by docker compose)
XWIKI_PASSWORD=Admin
REDMINE_API_KEY=your-redmine-api-key-from-my-account
80 changes: 80 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
services:

# ---------------------------------------------------------------------------
# XWiki — document management layer
# ---------------------------------------------------------------------------
xwiki:
image: xwiki:16-postgres-tomcat
container_name: qms-xwiki
depends_on:
xwiki-db:
condition: service_healthy
environment:
DB_HOST: xwiki-db
DB_DATABASE: xwiki
DB_USER: xwiki
DB_PASSWORD: ${XWIKI_DB_PASSWORD}
ports:
- "8080:8080"
volumes:
- xwiki-data:/usr/local/xwiki
restart: unless-stopped

xwiki-db:
image: postgres:16-alpine
container_name: qms-xwiki-db
environment:
POSTGRES_DB: xwiki
POSTGRES_USER: xwiki
POSTGRES_PASSWORD: ${XWIKI_DB_PASSWORD}
volumes:
- xwiki-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U xwiki"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

# ---------------------------------------------------------------------------
# Redmine — records and tracking layer
# ---------------------------------------------------------------------------
redmine:
image: redmine:5-alpine
container_name: qms-redmine
depends_on:
redmine-db:
condition: service_healthy
environment:
REDMINE_DB_POSTGRES: redmine-db
REDMINE_DB_DATABASE: redmine
REDMINE_DB_USERNAME: redmine
REDMINE_DB_PASSWORD: ${REDMINE_DB_PASSWORD}
REDMINE_SECRET_KEY_BASE: ${REDMINE_SECRET_KEY_BASE}
ports:
- "3000:3000"
volumes:
- redmine-data:/usr/src/redmine/files
restart: unless-stopped

redmine-db:
image: postgres:16-alpine
container_name: qms-redmine-db
environment:
POSTGRES_DB: redmine
POSTGRES_USER: redmine
POSTGRES_PASSWORD: ${REDMINE_DB_PASSWORD}
volumes:
- redmine-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U redmine"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

volumes:
xwiki-data:
xwiki-db-data:
redmine-data:
redmine-db-data:
117 changes: 98 additions & 19 deletions docs/setup.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,116 @@
# Setup Guide

> TODO: Full installation walkthrough will be written once the self-hosted adapter is complete.
Complete walkthrough from zero to first QMS deployment on the self-hosted stack (XWiki + Redmine).

## Prerequisites

- Docker and Docker Compose installed
- Python 3.12+
- `uv` package manager (`pip install uv`)
- **Docker + Docker Compose** ≥ 24 / v2 — [docs.docker.com](https://docs.docker.com/get-docker/)
- **Python** ≥ 3.12 — [python.org](https://www.python.org/downloads/)
- **uv** (latest) — `pip install uv`

## Quick Start (Self-hosted)
## Step 1 — Clone and install

```bash
# 1. Clone the repository
git clone https://github.com/gerfru/qms-kit.git
cd qms-kit

# 2. Install dependencies
uv sync
```

## Step 2 — Start the self-hosted stack

```bash
# Copy the env template and fill in passwords
cp docker/.env.example docker/.env
# edit docker/.env — set real passwords and generate REDMINE_SECRET_KEY_BASE:
# openssl rand -hex 64

docker compose -f docker/docker-compose.yml up -d
```

First startup takes 2–5 minutes while XWiki and Redmine initialize their databases.

**Verify both services are up:**

# 3. Copy and fill in the client overlay
cp config/selfhosted.yaml config/clients/acme.yaml
# edit config/clients/acme.yaml with your org details, XWiki URL, Redmine URL
| Service | URL | Default credentials |
|---------|----------------------------------------|---------------------|
| XWiki | <http://localhost:8080> | Admin / Admin |
| Redmine | <http://localhost:3000> | admin / admin |

> Change default passwords immediately after first login.

## Step 3 — One-time Redmine setup (manual)

Custom field *definitions* cannot be created via the Redmine API — they must be set up once through the web UI.

Follow [docs/redmine-setup.md](redmine-setup.md) to create the required trackers and custom fields.

After setup: go to **My account → API access key** in Redmine and copy the key into `docker/.env` as `REDMINE_API_KEY`.

## Step 4 — Create a client overlay

```bash
cp config/clients/example.yaml config/clients/acme.yaml
```

# 4. Start the self-hosted stack
docker compose -f adapters/selfhosted/docker-compose.yml up -d
Edit `config/clients/acme.yaml`:

# 5. Run the one-time Redmine manual setup (custom field definitions)
# See docs/redmine-setup.md
```yaml
organisation:
name: "Acme GmbH"
short: "ACM"
quality_officer: "Jane Smith"
management: "John Doe"

selfhosted:
xwiki:
base_url: "http://localhost:8080"
space_key: "QMS"
username: "Admin"
redmine:
base_url: "http://localhost:3000"
project_key: "qms-acme"
tracker_mapping:
nc: "Nonconformity"
capa: "CAPA"
audit: "Internal Audit"
kpi: "KPI Measurement"
```

## Step 5 — Dry-run (recommended first)

```bash
export XWIKI_PASSWORD=Admin
export REDMINE_API_KEY=<your-key>

qms-kit deploy --target selfhosted --config config/clients/acme.yaml --dry-run
```

This renders all templates and validates the config without touching XWiki or Redmine.
Expected output: `Dry run complete — N template(s) rendered, nothing deployed.`

## Step 6 — Deploy

```bash
qms-kit deploy --target selfhosted --config config/clients/acme.yaml
```

The command will:

1. Create the QMS space in XWiki and upsert all document pages
2. Create the QMS project in Redmine and seed scaffold issues per tracker

## Stopping and cleaning up

```bash
# Stop containers (data volumes preserved)
docker compose -f docker/docker-compose.yml down

# 6. Deploy the QMS scaffold
python -m cli deploy --target selfhosted --config config/clients/acme.yaml
# Full reset including all data volumes
docker compose -f docker/docker-compose.yml down -v
```

## Next Steps
## Next steps

See [Configuration Reference](configuration.md) for all available options.
- [Configuration Reference](configuration.md) — all YAML keys explained
- [Redmine Setup](redmine-setup.md) — manual tracker and custom field setup
- [Architecture](architecture.md) — how the layers fit together