Migrate from MinIO to SeaweedFS

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-02-17 15:46:27 +01:00
parent 5684984755
commit afd92fd938
14 changed files with 249 additions and 86 deletions

View File

@@ -72,7 +72,7 @@ probod:
bucket: "probod"
access-key-id: "probod"
secret-access-key: "thisisnotasecret"
endpoint: "http://127.0.0.1:9000"
endpoint: "http://127.0.0.1:8333"
notifications:
mailer:

View File

@@ -20,12 +20,12 @@ services:
PG_DATABASE: "probod"
PG_POOL_SIZE: "100"
# AWS/MinIO S3 storage
# S3-compatible storage (SeaweedFS)
AWS_REGION: "us-east-1"
AWS_BUCKET: "probod"
AWS_ACCESS_KEY_ID: "probod"
AWS_SECRET_ACCESS_KEY: "thisisnotasecret"
AWS_ENDPOINT: "http://minio:9000"
AWS_ENDPOINT: "http://seaweedfs:8333"
# Observability - Metrics & Tracing
METRICS_ADDR: "probo:8081"
@@ -48,7 +48,7 @@ services:
depends_on:
postgres:
condition: service_healthy
minio:
seaweedfs:
condition: service_started
chrome:
condition: service_started
@@ -75,19 +75,23 @@ services:
timeout: 5s
retries: 5
minio:
image: "quay.io/minio/minio"
entrypoint: "sh"
command: |
-c 'mkdir -p /var/lib/minio/probod && minio server --json --console-address :9001 /var/lib/minio'
seaweedfs:
image: "chrislusf/seaweedfs:4.13"
command: >
server
-s3
-s3.config=/etc/seaweedfs/s3.json
-s3.port=8333
-volume.max=100
-master.volumeSizeLimitMB=1024
-dir=/data
ports:
- "9000:9000"
- "9001:9001"
- "8333:8333"
- "9333:9333"
- "8888:8888"
volumes:
- "minio-data:/var/lib/minio:rw"
environment:
MINIO_ROOT_USER: "probod"
MINIO_ROOT_PASSWORD: "thisisnotasecret"
- "./compose/seaweedfs/s3.json:/etc/seaweedfs/s3.json:ro"
- "seaweedfs-data:/data:rw"
chrome:
image: "chromedp/headless-shell:140.0.7259.2"
@@ -109,4 +113,4 @@ services:
volumes:
probo-data:
postgres-data:
minio-data:
seaweedfs-data:

View File

@@ -20,19 +20,23 @@ services:
timeout: 5s
retries: 5
minio:
image: "quay.io/minio/minio"
entrypoint: "sh"
command: |
-c 'mkdir -p /var/lib/minio/probod && mkdir -p /var/lib/minio/probod-test && minio server --json --console-address :9001 /var/lib/minio'
seaweedfs:
image: "chrislusf/seaweedfs:latest"
command: >
server
-s3
-s3.config=/etc/seaweedfs/s3.json
-s3.port=8333
-volume.max=100
-master.volumeSizeLimitMB=1024
-dir=/data
ports:
- "9000:9000"
- "9001:9001"
- "8333:8333"
- "9333:9333"
- "8888:8888"
volumes:
- "minio-data:/var/lib/minio:rw"
environment:
MINIO_ROOT_USER: "probod"
MINIO_ROOT_PASSWORD: "thisisnotasecret"
- "./compose/seaweedfs/s3.json:/etc/seaweedfs/s3.json:ro"
- "seaweedfs-data:/data:rw"
grafana:
image: "grafana/grafana:latest"
@@ -154,7 +158,7 @@ services:
volumes:
postgres-data:
minio-data:
seaweedfs-data:
grafana-data:
prometheus-data:
tempo-data:

21
compose/seaweedfs/s3.json Normal file
View File

@@ -0,0 +1,21 @@
{
"identities": [
{
"name": "probod",
"credentials": [
{
"accessKey": "probod",
"secretKey": "thisisnotasecret"
}
],
"actions": [
"Admin",
"Read",
"Write",
"List",
"Tagging",
"Lock"
]
}
]
}

View File

@@ -14,7 +14,7 @@ Before deploying Probo, ensure you have:
1. **Kubernetes Cluster** - Version 1.23+
2. **Helm** - Version 3.8+
3. **PostgreSQL Database** - Managed service (AWS RDS, GCP Cloud SQL, Azure Database, etc.)
4. **S3 Storage** - AWS S3 or S3-compatible storage (GCS, DigitalOcean Spaces, MinIO, etc.)
4. **S3 Storage** - AWS S3 or S3-compatible storage (GCS, DigitalOcean Spaces, SeaweedFS, etc.)
## Install
@@ -48,7 +48,7 @@ helm install my-probo ./charts/probo \
--set postgresql.auth.postgresUser="probod" \
--set postgresql.auth.postgresPassword="your-db-password" \
--set postgresql.auth.database="probod" \
--set minio.enabled=true \
--set seaweedfs.enabled=true \
--set s3.bucket="your-bucket-name" \
--set s3.accessKeyId="your-access-key" \
--set s3.secretAccessKey="your-secret-key"
@@ -431,15 +431,15 @@ spec:
| s3.region | string | `"us-east-1"` | S3 region |
| s3.bucket | string | `"probod"` | S3 bucket name |
| s3.endpoint | string | `""` | S3 endpoint (leave empty for AWS S3, set for S3-compatible storage) |
| s3.accessKeyId | string | `""` | **REQUIRED** (when minio.enabled=false) S3 access key |
| s3.secretAccessKey | string | `""` | **REQUIRED** (when minio.enabled=false) S3 secret key |
| minio.enabled | bool | `true` | Enable included MinIO for demo purposes (NOT for production) |
| minio.mode | string | `"standalone"` | MinIO mode |
| minio.persistence.enabled | bool | `false` | Enable MinIO persistence |
| minio.resources.requests.memory | string | `"128Mi"` | MinIO memory request |
| minio.primary.enabled | bool | `true` | Enable MinIO primary node |
| minio.auth.rootUser | string | `"probod"` | MinIO root username |
| minio.auth.rootPassword | string | `"probod"` | MinIO root password |
| s3.accessKeyId | string | `""` | **REQUIRED** (when seaweedfs.enabled=false) S3 access key |
| s3.secretAccessKey | string | `""` | **REQUIRED** (when seaweedfs.enabled=false) S3 secret key |
| seaweedfs.enabled | bool | `true` | Enable included SeaweedFS for demo purposes (NOT for production) |
| seaweedfs.image.repository | string | `"chrislusf/seaweedfs"` | SeaweedFS container image repository |
| seaweedfs.image.tag | string | `"latest"` | SeaweedFS image tag |
| seaweedfs.persistence.enabled | bool | `false` | Enable SeaweedFS persistence |
| seaweedfs.persistence.size | string | `"10Gi"` | SeaweedFS persistent volume size |
| seaweedfs.auth.accessKey | string | `"probod"` | SeaweedFS S3 access key |
| seaweedfs.auth.secretKey | string | `"probod"` | SeaweedFS S3 secret key |
| chrome.enabled | bool | `true` | Deploy Chrome headless in the cluster for PDF generation |
| chrome.replicaCount | int | `1` | Number of Chrome replicas |
| chrome.image.repository | string | `"chromedp/headless-shell"` | Chrome container image repository |

View File

@@ -1,9 +0,0 @@
dependencies:
- name: minio
repository: https://charts.min.io/
version: 5.4.0
- name: kubernetes-ingress
repository: https://haproxytech.github.io/helm-charts
version: 1.45.1
digest: sha256:86861ee988df3673c6306ff42719f09d12ce22e2d48a0db757ad4365d204bd85
generated: "2025-10-31T10:17:36.108938+01:00"

View File

@@ -18,10 +18,6 @@ maintainers:
icon: https://github.com/getprobo/probo/blob/main/.github/cover_v3.png
dependencies:
- name: minio
condition: minio.enabled
repository: https://charts.min.io/
version: 5.4.0 # Latest stable version
- name: kubernetes-ingress
alias: haproxy-ingress
condition: haproxy-ingress.enabled

View File

@@ -7,7 +7,7 @@ This Helm chart deploys Probo - an open-source SOC-2 compliance platform - on Ku
- Kubernetes 1.23+
- Helm 3.8+
- External PostgreSQL database (AWS RDS, GCP Cloud SQL, Azure Database, etc.)
- S3 or S3-compatible object storage (AWS S3, GCS, DigitalOcean Spaces, MinIO, etc.)
- S3 or S3-compatible object storage (AWS S3, GCS, DigitalOcean Spaces, SeaweedFS, etc.)
- OpenSSL installed (for generating secrets)
## Installing the Chart

View File

@@ -48,8 +48,8 @@
{{- end }}
💾 Object Storage:
{{- if .Values.minio.enabled }}
Using MinIO: {{ include "probo.fullname" . }}-minio:9000
{{- if .Values.seaweedfs.enabled }}
Using SeaweedFS: {{ include "probo.fullname" . }}-seaweedfs:8333
Bucket: {{ .Values.s3.bucket }}
{{- else }}
Using S3 storage
@@ -64,8 +64,8 @@
{{- if not .Values.ingress.tls }}
⚠️ TLS is not enabled! Enable it for production by configuring ingress.tls
{{- end }}
{{- if or .Values.postgresql.enabled .Values.minio.enabled }}
⚠️ Using internal PostgreSQL or MinIO - FOR TESTING ONLY!
{{- if or .Values.postgresql.enabled .Values.seaweedfs.enabled }}
⚠️ Using internal PostgreSQL or SeaweedFS - FOR TESTING ONLY!
For production, disable these and use external managed services.
{{- end }}

View File

@@ -118,8 +118,8 @@ PostgreSQL password (from subchart or external config)
S3 endpoint
*/}}
{{- define "probo.s3.endpoint" -}}
{{- if .Values.minio.enabled }}
{{- printf "http://%s-minio:9000" .Release.Name }}
{{- if .Values.seaweedfs.enabled }}
{{- printf "http://%s-seaweedfs:8333" (include "probo.fullname" .) }}
{{- else }}
{{- .Values.s3.endpoint }}
{{- end }}
@@ -129,10 +129,10 @@ S3 endpoint
S3 access key
*/}}
{{- define "probo.s3.accessKeyId" -}}
{{- if .Values.minio.enabled }}
{{- .Values.minio.auth.rootUser | required "minio.auth.rootUser is required when minio.enabled=true" }}
{{- if .Values.seaweedfs.enabled }}
{{- .Values.seaweedfs.auth.accessKey | required "seaweedfs.auth.accessKey is required when seaweedfs.enabled=true" }}
{{- else }}
{{- .Values.s3.accessKeyId | required "s3.accessKeyId is required when minio.enabled=false" }}
{{- .Values.s3.accessKeyId | required "s3.accessKeyId is required when seaweedfs.enabled=false" }}
{{- end }}
{{- end }}
@@ -140,10 +140,10 @@ S3 access key
S3 secret key
*/}}
{{- define "probo.s3.secretAccessKey" -}}
{{- if .Values.minio.enabled }}
{{- .Values.minio.auth.rootPassword | required "minio.auth.rootPassword is required when minio.enabled=true" }}
{{- if .Values.seaweedfs.enabled }}
{{- .Values.seaweedfs.auth.secretKey | required "seaweedfs.auth.secretKey is required when seaweedfs.enabled=true" }}
{{- else }}
{{- .Values.s3.secretAccessKey | required "s3.secretAccessKey is required when minio.enabled=false" }}
{{- .Values.s3.secretAccessKey | required "s3.secretAccessKey is required when seaweedfs.enabled=false" }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,136 @@
{{- if .Values.seaweedfs.enabled }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "probo.fullname" . }}-seaweedfs
labels:
{{- include "probo.labels" . | nindent 4 }}
app.kubernetes.io/component: seaweedfs
stringData:
s3.json: |
{
"identities": [
{
"name": {{ .Values.seaweedfs.auth.accessKey | quote }},
"credentials": [
{
"accessKey": {{ .Values.seaweedfs.auth.accessKey | quote }},
"secretKey": {{ .Values.seaweedfs.auth.secretKey | quote }}
}
],
"actions": ["Admin", "Read", "Write", "List", "Tagging", "Lock"]
}
]
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "probo.fullname" . }}-seaweedfs
labels:
{{- include "probo.labels" . | nindent 4 }}
app.kubernetes.io/component: seaweedfs
spec:
replicas: 1
selector:
matchLabels:
{{- include "probo.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: seaweedfs
template:
metadata:
labels:
{{- include "probo.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: seaweedfs
spec:
containers:
- name: seaweedfs
image: "{{ .Values.seaweedfs.image.repository }}:{{ .Values.seaweedfs.image.tag }}"
imagePullPolicy: {{ .Values.seaweedfs.image.pullPolicy }}
args:
- server
- -s3
- -s3.config=/etc/seaweedfs/s3.json
- -s3.port=8333
- -volume.max=100
- -master.volumeSizeLimitMB=1024
- -dir=/data
ports:
- name: s3
containerPort: 8333
protocol: TCP
- name: master
containerPort: 9333
protocol: TCP
- name: filer
containerPort: 8888
protocol: TCP
livenessProbe:
httpGet:
path: /cluster/status
port: master
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /cluster/status
port: master
initialDelaySeconds: 5
periodSeconds: 5
resources:
{{- toYaml .Values.seaweedfs.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/seaweedfs
readOnly: true
- name: data
mountPath: /data
volumes:
- name: config
secret:
secretName: {{ include "probo.fullname" . }}-seaweedfs
- name: data
{{- if .Values.seaweedfs.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ include "probo.fullname" . }}-seaweedfs
{{- else }}
emptyDir: {}
{{- end }}
{{- if .Values.seaweedfs.persistence.enabled }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "probo.fullname" . }}-seaweedfs
labels:
{{- include "probo.labels" . | nindent 4 }}
app.kubernetes.io/component: seaweedfs
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.seaweedfs.persistence.size }}
{{- if .Values.seaweedfs.persistence.storageClass }}
storageClassName: {{ .Values.seaweedfs.persistence.storageClass | quote }}
{{- end }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "probo.fullname" . }}-seaweedfs
labels:
{{- include "probo.labels" . | nindent 4 }}
app.kubernetes.io/component: seaweedfs
spec:
type: ClusterIP
ports:
- port: 8333
targetPort: s3
protocol: TCP
name: s3
selector:
{{- include "probo.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: seaweedfs
{{- end }}

View File

@@ -215,9 +215,9 @@ postgresql:
# ...
# -----END CERTIFICATE-----
# MinIO configuration
# Disable included MinIO for production - use external S3 instead
minio:
# SeaweedFS configuration
# Disable included SeaweedFS for production - use external S3 instead
seaweedfs:
enabled: false
# S3 storage configuration (REQUIRED)

View File

@@ -307,37 +307,48 @@ postgresql:
# S3 storage configuration
# For production: Use external S3 (AWS S3, GCS, etc.)
# For testing: Enable the included MinIO chart
# For testing: Enable the included SeaweedFS chart
s3:
# External S3 configuration (used when minio.enabled=false)
# External S3 configuration (used when seaweedfs.enabled=false)
region: "us-east-1"
bucket: "probod"
# For AWS S3, leave endpoint empty
# For S3-compatible storage (MinIO, DigitalOcean Spaces, etc.), set the endpoint
# For S3-compatible storage (SeaweedFS, DigitalOcean Spaces, etc.), set the endpoint
endpoint: ""
accessKeyId: "" # REQUIRED when minio.enabled=false: S3 access key
secretAccessKey: "" # REQUIRED when minio.enabled=false: S3 secret key
accessKeyId: "" # REQUIRED when seaweedfs.enabled=false: S3 access key
secretAccessKey: "" # REQUIRED when seaweedfs.enabled=false: S3 secret key
# Use path-style URLs (required for Azure Blob Storage and some S3-compatible services)
# When true: https://endpoint/bucket/key
# When false (default): https://bucket.endpoint/key
usePathStyle: false
# MinIO configuration
# Enable included MinIO for testing/development (NOT for production)
minio:
# -- enabled included Minio operator for s3 resource demo purposes
# SeaweedFS configuration
# Enable included SeaweedFS for testing/development (NOT for production)
seaweedfs:
# -- Enable included SeaweedFS for S3-compatible object storage
enabled: true
mode: standalone
image:
repository: chrislusf/seaweedfs
tag: "latest"
pullPolicy: IfNotPresent
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
persistence:
enabled: false
resources:
requests:
memory: 128Mi
primary:
enabled: true
size: 10Gi
storageClass: ""
auth:
rootUser: probod
rootPassword: probod
accessKey: probod
secretKey: probod
# Headless Chrome for PDF generation
chrome:

View File

@@ -48,7 +48,7 @@ probod:
bucket: "probod-test"
access-key-id: "probod"
secret-access-key: "thisisnotasecret"
endpoint: "http://127.0.0.1:9000"
endpoint: "http://127.0.0.1:8333"
notifications:
mailer: