Skip to content

Commit 89f9b13

Browse files
authored
Merge pull request #18 from srdp-hub/dev
Merging `dev` into `main`, using Github Flow from now on.
2 parents 02090e9 + 826f008 commit 89f9b13

27 files changed

Lines changed: 1937 additions & 240 deletions

.gitignore

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
# OSX
2+
.DS_Store
3+
14
# Environment variables
25
.env
6+
secrets.sh
37

48
# Local certificates and PAT for Zitadel
59
certs/
@@ -12,4 +16,9 @@ site/
1216
.terraform
1317
terraform.tfstate
1418
terraform.tfstate.backup
15-
.DS_Store
19+
kubeconfig.yaml
20+
21+
# Kubernetes
22+
values-prod.yaml
23+
charts/
24+

Justfile

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
set shell := ["bash", "-c"]
2+
set dotenv-load := false
3+
4+
namespace := "srdp"
5+
kubeconfig := justfile_directory() + "/kubernetes/opentofu/kubeconfig.yaml"
6+
7+
default: help
8+
9+
help:
10+
@just --list
11+
12+
# Local development
13+
local-tls:
14+
mkdir -p kubernetes/certs
15+
mkcert -cert-file kubernetes/certs/selfsigned.crt -key-file kubernetes/certs/selfsigned.key "auth.local.dev" "marimo.local.dev" "quarto.local.dev" "dagster.local.dev"
16+
kubectl create namespace {{namespace}} --dry-run=client -o yaml | kubectl apply -f -
17+
kubectl create secret tls custom-ingress-cert --namespace {{namespace}} --key kubernetes/certs/selfsigned.key --cert kubernetes/certs/selfsigned.crt --dry-run=client -o yaml | kubectl apply -f -
18+
19+
local-deploy:
20+
cd kubernetes/srdp-chart && helm dependency update
21+
cd kubernetes/srdp-chart && helm upgrade --install srdp . --namespace {{namespace}} --create-namespace -f values.yaml -f values-local.yaml
22+
23+
local-delete:
24+
helm uninstall srdp -n {{namespace}} || true
25+
kubectl delete pvc --all -n {{namespace}} || true
26+
27+
# Prod / infra
28+
prod-apply:
29+
cd kubernetes/opentofu && source ./secrets.sh && tofu apply -auto-approve
30+
31+
prod-destroy:
32+
just prod-uninstall || echo "Helm uninstall skipped (cluster may already be down)"
33+
cd kubernetes/opentofu && source ./secrets.sh && tofu destroy -auto-approve
34+
35+
prod-use-kubeconfig:
36+
cd kubernetes/opentofu && tofu output -raw kubeconfig > "{{kubeconfig}}" && echo "kubeconfig written to {{kubeconfig}}"
37+
38+
prod-get-values:
39+
@echo "Fetching dynamic values..."
40+
@if [ ! -f "{{kubeconfig}}" ]; then echo "kubeconfig not found, run 'just prod-use-kubeconfig' first"; exit 1; fi
41+
@KUBECONFIG="{{kubeconfig}}" kubectl get svc srdp-traefik -n {{namespace}} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' | xargs -I{} printf "LOAD_BALANCER_IP:\t%s\n" "{}"
42+
43+
prod-traefik-only:
44+
cd kubernetes && \
45+
if [ ! -f "{{kubeconfig}}" ]; then echo "kubeconfig not found, run 'just prod-use-kubeconfig' first"; exit 1; fi; \
46+
export KUBECONFIG="{{kubeconfig}}"; \
47+
helm upgrade --install srdp srdp-chart --namespace {{namespace}} --create-namespace -f srdp-chart/values-prod.yaml --set zitadel.enabled=false --set oauth2-proxy.enabled=false --set dagster.enabled=false --set marimo.enabled=false --set quarto.enabled=false
48+
49+
prod-auth-only:
50+
cd kubernetes && \
51+
if [ ! -f "{{kubeconfig}}" ]; then echo "kubeconfig not found, run 'just prod-use-kubeconfig' first"; exit 1; fi; \
52+
export KUBECONFIG="{{kubeconfig}}"; \
53+
helm upgrade srdp srdp-chart --namespace {{namespace}} --reset-values -f srdp-chart/values-prod.yaml --set zitadel.enabled=true --set oauth2-proxy.enabled=true --set dagster.enabled=false --set marimo.enabled=false --set quarto.enabled=false
54+
55+
prod-full:
56+
cd kubernetes && \
57+
if [ ! -f "{{kubeconfig}}" ]; then echo "kubeconfig not found, run 'just prod-use-kubeconfig' first"; exit 1; fi; \
58+
export KUBECONFIG="{{kubeconfig}}"; \
59+
helm upgrade srdp srdp-chart --namespace {{namespace}} --reset-values -f srdp-chart/values-prod.yaml
60+
61+
prod-uninstall:
62+
cd kubernetes && \
63+
if [ ! -f "{{kubeconfig}}" ]; then echo "kubeconfig not found, run 'just prod-use-kubeconfig' first"; exit 1; fi; \
64+
export KUBECONFIG="{{kubeconfig}}"; \
65+
echo "Deleting LoadBalancer service (releases Scaleway LB)..." && \
66+
kubectl delete svc srdp-traefik -n {{namespace}} --ignore-not-found && \
67+
echo "Waiting 30s for LB cleanup..." && sleep 30 && \
68+
helm uninstall srdp -n {{namespace}} || true && \
69+
kubectl delete jobs --all -n {{namespace}} --ignore-not-found && \
70+
kubectl delete pvc --all -n {{namespace}} --ignore-not-found

docs/01-prerequisites.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ icon: lucide/list-todo
77

88
Before you begin, ensure you have the following software installed on your local machine. This guide assumes you have a basic understanding of using the command line.
99

10-
### Core Tools
10+
Required tools
11+
- Git
12+
- Container runtime (Docker/Podman) for building the Marimo, Quarto, and srdp-etl (Dagster user code) images
13+
- Kubernetes cluster + `kubectl` (tested with 1.32+). For local work, `kind`, `minikube`, or `k3d` with LoadBalancer/NodePort access all work.
14+
- Helm 3.x
15+
- [`just`](https://github.com/casey/just) as a task runner for the common Helm/OpenTofu commands in this repo
16+
- [`mkcert`](https://github.com/FiloSottile/mkcert) to generate local TLS certificates for `*.local.dev`
17+
- [OpenTofu](https://opentofu.org/docs/intro/install/) for production infrastructure on Scaleway Kapsule
1118

12-
* **Git:** The project is managed with Git. You will need it to clone the repository.
13-
* [Install Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14-
15-
* **Docker and Docker Compose:** All services in this project are containerized using Docker. Docker Compose is used to orchestrate and run the multi-container setup.
16-
* The easiest way to get both is by installing **Docker Desktop** for your operating system. It includes Docker Engine, Docker CLI, and Docker Compose.
17-
* [Install Docker Desktop](https://www.docker.com/products/docker-desktop/)
18-
19-
* **A Code Editor:** You will need an editor to view and modify files.
19+
Notes
20+
- The `just` recipes use a Bash-compatible shell; on Windows, run them from Git Bash or WSL.
21+
- You need permission to create namespaces/secrets and, for cloud runs, to provision load balancers.

docs/02-configuration.md

Lines changed: 45 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,109 +7,79 @@ icon: lucide/locate-fixed
77

88
This guide will walk you through the steps to get the Single Repo Data Platform (SRDP) running on your local machine.
99

10-
### Step 1: Clone the Repository
11-
12-
First, clone this repository to a location of your choice on your computer.
13-
14-
Open your terminal, navigate to your development directory, and run:
10+
## 1) Clone the repo
1511

1612
```bash
1713
git clone git@github.com:dkapitan/srdp.git # or git clone https://github.com/dkapitan/srdp.git
18-
cd srdp/local
14+
cd srdp
1915
```
2016

21-
### Step 2: Configure Local Hostnames
22-
23-
To access the services using friendly names like `marimo.local.dev`, you need to edit your computer's `hosts` file. This file maps domain names to IP addresses. We will map our service domains to your local machine's IP, `127.0.0.1`.
24-
25-
**Why is this necessary?**
26-
When you type `marimo.local.dev` into your browser, this file tells the browser to send the request to your own computer instead of trying to find a public website on the internet. Traefik, our proxy, will then receive this request and route it to the correct Docker container.
27-
28-
---
29-
30-
#### On macOS or Linux:
17+
## 2) Point DNS at your cluster
3118

32-
1. Open a terminal.
33-
2. Run the following command to open the hosts file with `nano`, a simple text editor. You will be prompted for your password.
34-
```bash
35-
sudo nano /etc/hosts
36-
```
37-
38-
#### On Windows:
39-
40-
1. Press the Windows key, type `Notepad`, right-click on it, and select **"Run as administrator"**.
41-
2. In Notepad, go to `File` > `Open`.
42-
3. Navigate to `c:\Windows\System32\Drivers\etc\hosts`.
43-
4. You may need to change the file type filter in the bottom-right corner from "Text Documents (*.txt)" to **"All files (*.*)"** to see the `hosts` file.
44-
45-
---
46-
47-
#### Add the Following Line:
48-
49-
Add this single line to the **bottom** of the `hosts` file.
19+
The chart uses `*.local.dev` by default. Point those hostnames at the IP you will use to reach Traefik:
20+
- For NodePort/local clusters: `127.0.0.1` is usually fine.
21+
- For a LoadBalancer: use the external IP once Traefik comes up.
5022

23+
Add one line to your hosts file:
5124
```
52-
127.0.0.1 marimo.local.dev quarto.local.dev auth.local.dev
25+
127.0.0.1 auth.local.dev marimo.local.dev quarto.local.dev dagster.local.dev
5326
```
5427

55-
Save the file and exit the editor. (In `nano`, press `Ctrl+X`, then `Y`, then `Enter`). **You may need to restart your machine in order for changes to take effect.**
56-
57-
### Step 2b: Generate Certificates
58-
59-
You should generate local development certificates using [mkcert](https://github.com/FiloSottile/mkcert):
28+
## 3) Create a local TLS secret
6029

30+
Generate a certificate for the local domains and create the secret that the Helm chart expects.
6131
```bash
62-
mkcert -cert-file ./certs/selfsigned.crt -key-file ./certs/selfsigned.key "*.local.dev" "local.dev"
32+
mkdir -p kubernetes/certs
33+
mkcert -cert-file kubernetes/certs/selfsigned.crt -key-file kubernetes/certs/selfsigned.key \
34+
"auth.local.dev" "marimo.local.dev" "quarto.local.dev" "dagster.local.dev"
35+
36+
# Apply the secret into your target namespace (default here is srdp)
37+
kubectl create namespace srdp --dry-run=client -o yaml | kubectl apply -f -
38+
kubectl create secret tls custom-ingress-cert \
39+
--namespace srdp \
40+
--key kubernetes/certs/selfsigned.key \
41+
--cert kubernetes/certs/selfsigned.crt \
42+
--dry-run=client -o yaml | kubectl apply -f -
6343
```
6444

65-
**Make sure to put these certificates under /local/certs. The easies way to accomplish this is to run the previous comppand inside the /local/ directory.**
66-
67-
### Step 3: Launch the Services
68-
69-
Now you are ready to start all the services. Navigate to the root of the project directory in your terminal and run:
70-
45+
Or simply run:
7146
```bash
72-
docker-compose up --build -d
47+
just local-tls
7348
```
7449

75-
* `--build`: This flag tells Docker Compose to build the application images (for Marimo and Quarto) from their `Dockerfile`s before starting the services. You should use this the first time you run the command or after you've made changes to the application code.
76-
* `-d`: This runs the containers in "detached" mode, meaning they will run in the background and your terminal will be free to use.
77-
78-
**Note:** The first time you run this, Zitadel will be initialized but the database will be empty. You can log in as an admin using:
79-
80-
- **Username:** `zitadel-admin@zitadel.auth.local.dev`
81-
- **Password:** `Password1!`
82-
83-
After logging in, create a new project (e.g., "Protected Apps"). Then, create a new app with type **Web**, authentication method **Code**, and add the following redirect URIs:
50+
## 4) Build local container images
8451

85-
- `https://marimo.local.dev/oauth2/callback`
86-
- `https://quarto.local.dev/oauth2/callback`
52+
The Helm chart references three application images. For local development the pull policy is set to `Never`, so the images must exist in your local Docker/containerd cache:
8753

88-
And post logout URIs:
89-
90-
- `https://marimo.local.dev`
91-
- `https://quarto.local.dev`
54+
```bash
55+
docker build -t rg.nl-ams.scw.cloud/srdp-registry/marimo:v1.0 local/apps/marimo
56+
docker build -t rg.nl-ams.scw.cloud/srdp-registry/quarto:v1.0 local/apps/quarto
57+
docker build -t rg.nl-ams.scw.cloud/srdp-registry/srdp-etl:v1.0 kubernetes/apps/srdp-etl
58+
```
9259

93-
When the project is created, Zitadel will display a client ID and secret. Copy these and set them in your `.env` file under `/local/`:
60+
## 5) Fill in secrets and local values
9461

95-
```
96-
OIDC_CLIENT_ID=your-client-id
97-
OIDC_CLIENT_SECRET=your-client-secret
98-
```
62+
Update `kubernetes/srdp-chart/values-local.yaml` before installing:
63+
- set your own Zitadel master key, DB passwords, OAuth2 client values, and cookie secret
64+
- keep `custom-ingress-cert` (created above) or point to another TLS secret if you prefer.
9965

100-
After updating the `.env` file, run:
66+
## 6) Install the chart locally
10167

10268
```bash
103-
docker compose up --force-recreate
69+
cd kubernetes/srdp-chart
70+
helm dependency update
71+
helm upgrade --install srdp . \
72+
--namespace srdp --create-namespace \
73+
-f values.yaml \
74+
-f values-local.yaml
10475
```
10576

106-
OR
107-
77+
Or simply run:
10878
```bash
109-
docker compose down
110-
docker compose up --build
79+
just local-deploy
11180
```
11281

113-
**Important:** Do **not** run `docker compose down -v`, as the `-v` option will destroy existing data, including the project and app you created in Zitadel.
82+
To re-run with updated values, run the same `helm upgrade` command (or `just local-deploy`).
11483

84+
The chart deploys the full stack: Traefik, PostgreSQL (in-cluster via Bitnami Helm chart), Zitadel, OAuth2-Proxy, Dagster (webserver + daemon + user code), Marimo, and Quarto. PostgreSQL hosts both the `zitadel` and `dagster` databases, created automatically via `zitadel-db.primary.initdb.scripts`.
11585
**Congratulations! The local environment should now be up and running.** Proceed to the next section, **Usage & Verification**, to confirm that everything is working correctly.

docs/03-usage.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@ icon: lucide/circle-play
55

66
# Usage & Verification
77

8+
### Check the release
9+
- `helm list -n srdp`
10+
- `kubectl get pods,svc,ing -n srdp`
11+
12+
### Access services
13+
- Marimo: `https://marimo.local.dev`
14+
- Quarto: `https://quarto.local.dev`
15+
- Dagster: `https://dagster.local.dev`
16+
- Zitadel: `https://auth.local.dev`
17+
- Traefik dashboard (if enabled in values): `http://localhost:8080`
18+
19+
All apps (Marimo, Quarto, Dagster) are protected behind OAuth2-Proxy. Accessing any of them will redirect to Zitadel for OIDC login before granting access.
20+
21+
### Update or remove the release
22+
- Re-apply updated values: rerun the `helm upgrade --install ...` command from [02-configuration.md](./02-configuration.md) (or `just local-deploy`).
23+
- Remove everything: `helm uninstall srdp -n srdp`
24+
- If you also want to clear persistent data: `kubectl delete pvc --all -n srdp`
25+
- Or use the task runner: `just local-delete`
26+
27+
### Logs
28+
- Watch all pods: `kubectl logs -n srdp -l app.kubernetes.io/instance=srdp -f`
29+
- Specific service, e.g. Marimo: `kubectl logs -n srdp deploy/marimo -f`
30+
- Dagster webserver: `kubectl logs -n srdp deploy/srdp-dagster-webserver -f`
31+
- Dagster daemon: `kubectl logs -n srdp deploy/srdp-dagster-daemon -f`
832
Once you have completed the setup, you can verify that all services are running correctly by accessing them in your web browser.
933

1034
### Accessing Services

0 commit comments

Comments
 (0)