A self-hosted analytics and data engineering platform running on a single Ubuntu server.
The platform is orchestrated with Docker Compose and uses an abctl-managed Kubernetes (kind) cluster to run Airbyte.
It provides end-to-end ingestion, transformation, orchestration, and analytics with a clear separation between configuration, secrets, and runtime state.
- Airbyte
- Installed via
abctl - Runs inside a Kubernetes cluster (kind)
- Installed via
- PostgreSQL 16
- Primary analytical database
- Explicit schema and role separation
- dbt
- Containerized
- Executed via Airflow
- Generates documentation served by Nginx
- Airflow
- Scheduler, webserver, workers
- Triggers Airbyte syncs and dbt runs
- Metabase
- Read-only access to curated marts
- Nginx
- Routes all public traffic
- Terminates TLS using Let’s Encrypt (Certbot)
Public subdomains exposed via Nginx + Let’s Encrypt:
https://airflow.franklingreen.de– Airflow UIhttps://airbyte.franklingreen.de– Airbyte UI & API- health check:
https://airbyte.franklingreen.de/api/v1/health
- health check:
https://metabase.franklingreen.de– Metabase UIhttps://pgadmin.franklingreen.de– pgAdmin UIhttps://dbt-docs.franklingreen.de– dbt documentation site
- Airbyte namespace:
airbyte-abctl - Kubernetes cluster: kind
- Kind node container:
airbyte-abctl-control-plane
- Primary:
/root/.airbyte/abctl/abctl.kubeconfig
- Copied to:
/root/.kube/configfor standardkubectlusage
- Ingress controller: ingress-nginx (in-cluster)
- Ingress class:
nginx
Traffic flow:
Internet
→ Nginx (Docker, TLS termination)
→ kind NodePort
→ ingress-nginx
→ Airbyte services
NodePorts (ingress-nginx service):
- HTTP:
31374 - HTTPS:
31491
- Ingress name:
airbyte-franklingreen - Namespace:
airbyte-abctl - Required routes:
/→airbyte-abctl-airbyte-server-svc:8001/api/v1/connector_builder→airbyte-abctl-airbyte-connector-builder-server-svc:80
Important
If a host-specific ingress is defined, it must include a / route.
Otherwise, requests may fall through to the wildcard ingress and return 403.
- The
nginxcontainer must be attached to the Docker networkkind - This allows Nginx to reach:
airbyte-abctl-control-plane:31374
This is declared explicitly in docker-compose.yml as an external network.
- Airflow uses the public Airbyte base URL:
https://airbyte.<domain>
- No host port-forwarding is used (deprecated in this setup)
rawstagingmart
- Airbyte → writes to
raw - dbt → reads
raw, writesstagingandmart - Metabase → reads from
martonly
Roles are explicitly managed with schema-level privileges
(USAGE, SELECT, CREATE as appropriate).
data-platform/
├─ docker-compose.yml
├─ .env
├─ README.md
├─ airflow/
│ ├─ .env
│ ├─ dags/
│ ├─ plugins/
│ ├─ docs/
│ └─ logs/
├─ certbot/
│ ├─ conf/
│ ├─ logs/
│ └─ www/
├─ dbt/
│ └─ <PROJECT>/
│ ├─ analysis/
│ ├─ macros/
│ ├─ models/
│ ├─ seeds/
│ ├─ snapshots/
│ ├─ tests/
│ ├─ target/
│ ├─ profiles.yml
│ └─ dbt_project.yml
├─ kubernetes/
│ └─ airbyte/
│ └─ airbyte-ingress.yml
├─ nginx/
│ ├─ conf.d/
│ └─ www/
│ └─ dbt-docs/
├─ pgadmin/
│ └─ servers.json
└─ postgres/
└─ init/
Start:
docker compose up -dInspect:
docker compose ps
docker compose logs -f --tail=200 <service>Set kubeconfig:
export KUBECONFIG=/root/.airbyte/abctl/abctl.kubeconfigInspect cluster:
kubectl -n airbyte-abctl get pods
kubectl -n airbyte-abctl get svc
kubectl -n airbyte-abctl get ingress
kubectl -n ingress-nginx get svc ingress-nginx-controllerVerify Airbyte:
curl -i https://airbyte.franklingreen.de/api/v1/healthPipeline pattern:
- Airbyte sync ✅
- dbt run ✅
- dbt test ⏳
- dbt docs publish ✅
Notes:
dbt testshould fail the DAG on test failures- Prefer model/test selection via tags
A DAG exists to publish dbt docs to Nginx.
Stabilization target:
- atomic deploy (staging directory → final)
- Nginx serves a fully consistent docs site at all times
- Airbyte ingesting GitHub data from:
pandas-dev/pandas
- One dashboard with two cards:
- time series: commits / PRs / comments
- table: top repositories by PR count
- additional marts (lead time, backlog, contributor activity)
- dbt tests & documentation coverage
- expanded dashboards with insight metrics (e.g. PR lead time)
Fix:
export KUBECONFIG=/root/.airbyte/abctl/abctl.kubeconfig
cp /root/.airbyte/abctl/abctl.kubeconfig /root/.kube/config
chmod 600 /root/.kube/configCause:
- Host-specific ingress without
/route
Fix:
- Ensure
/routes toairbyte-abctl-airbyte-server-svc
Cause:
- Nginx not attached to Docker network
kind
Fix:
- Add
kindas an external network to the nginx service
- Secrets are never committed
.envfiles are ignored- Metabase uses read-only database access
- Postgres roles enforce schema boundaries