diff --git a/Dockerfile b/Dockerfile index 7174717a9..5386b759e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,9 +11,14 @@ RUN useradd -m probo && \ rm -rf /var/lib/apt/lists/* COPY probod /usr/local/bin/probod +COPY entrypoint.sh /usr/local/bin/entrypoint.sh + RUN chmod +x /usr/local/bin/probod && \ - setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/probod + chmod +x /usr/local/bin/entrypoint.sh && \ + setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/probod && \ + mkdir -p /etc/probod && \ + chown probo:probo /etc/probod USER probo -ENTRYPOINT ["probod"] +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..3d2b21b91 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,185 @@ +services: + probo: + image: "ghcr.io/getprobo/probo:latest" + environment: + # Required secrets (use secure values in production) + PROBOD_ENCRYPTION_KEY: "thisisnotasecretAAAAAAAAAAAAAAAAAAAAAAAAAAA=" + AUTH_COOKIE_SECRET: "this-is-a-secure-secret-for-cookie-signing-at-least-32-bytes" + AUTH_PASSWORD_PEPPER: "this-is-a-secure-pepper-for-password-hashing-at-least-32-bytes" + TRUST_AUTH_TOKEN_SECRET: "this-is-a-secure-secret-for-trust-token-signing-at-least-32-bytes" + + # Application settings + PROBOD_HOSTNAME: "localhost:8080" + API_ADDR: "localhost:8080" + API_CORS_ALLOWED_ORIGINS: "http://localhost:8080,http://localhost:5173" + + # PostgreSQL database + PG_ADDR: "postgres:5432" + PG_USERNAME: "postgres" + PG_PASSWORD: "postgres" + PG_DATABASE: "probod" + PG_POOL_SIZE: "100" + + # AWS/MinIO S3 storage + AWS_REGION: "us-east-1" + AWS_BUCKET: "probod" + AWS_ACCESS_KEY_ID: "probod" + AWS_SECRET_ACCESS_KEY: "thisisnotasecret" + AWS_ENDPOINT: "http://minio:9000" + + # Observability - Metrics & Tracing + METRICS_ADDR: "probo:8081" + TRACING_ADDR: "tempo:4317" + + # Email notifications + SMTP_ADDR: "mailpit:1025" + SMTP_TLS_REQUIRED: "false" + MAILER_SENDER_NAME: "Probo" + MAILER_SENDER_EMAIL: "no-reply@notification.getprobo.com" + + # Chrome for PDF generation + CHROME_DP_ADDR: "chrome:9222" + ports: + - "8080:8080" + - "8081:8081" + - "8443:8443" + volumes: + - "probo-data:/data" + depends_on: + - postgres + - minio + - chrome + + + postgres: + image: "postgres:17.4" + shm_size: "1g" + command: > + postgres -c "shared_buffers=4GB" + -c "max_connections=200" + -c "log_statement=all" + ports: + - "5432:5432" + volumes: + - "./compose/postgres:/docker-entrypoint-initdb.d:ro" + - "postgres-data:/var/lib/postgresql/data:rw" + environment: + POSTGRES_USER: "postgres" + POSTGRES_PASSWORD: "postgres" + + 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' + ports: + - "9000:9000" + - "9001:9001" + volumes: + - "minio-data:/var/lib/minio:rw" + environment: + MINIO_ROOT_USER: "probod" + MINIO_ROOT_PASSWORD: "thisisnotasecret" + + grafana: + image: "grafana/grafana:latest" + ports: + - "3001:3000" + volumes: + - "./compose/grafana/provisioning:/etc/grafana/provisioning:ro" + - "grafana-data:/var/lib/grafana:rw" + environment: + GF_AUTH_ANONYMOUS_ENABLED: "true" + GF_AUTH_ANONYMOUS_ORG_ROLE: "Admin" + GF_AUTH_DISABLE_LOGIN_FORM: "true" + GF_USERS_DEFAULT_THEME: "light" + + prometheus: + image: "prom/prometheus:latest" + volumes: + - "./compose/prometheus/prometheus.yaml:/etc/prometheus/prometheus.yml" + - "prometheus-data:/prometheus" + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--web.console.libraries=/etc/prometheus/console_libraries" + - "--web.console.templates=/etc/prometheus/consoles" + - "--web.enable-lifecycle" + - "--web.enable-remote-write-receiver" + - "--web.listen-address=:9191" + ports: + - "9191:9191" + + loki: + image: "grafana/loki:latest" + ports: + - "3100:3100" + command: + - "-config.file=/etc/loki/local-config.yaml" + + tempo: + image: "grafana/tempo:latest" + command: + - "-config.file=/etc/tempo.yaml" + ports: + - "4317:4317" + volumes: + - "./compose/tempo/tempo.yaml:/etc/tempo.yaml:ro" + - "tempo-data:/var/tempo:rw" + + mailpit: + image: "axllent/mailpit:latest" + ports: + - "1025:1025" # SMTP server + - "8025:8025" # Web UI + environment: + - "MP_DISABLE_VERSION_CHECK=true" + - "MP_VERBOSE=false" + - "MP_SMTP_AUTH_ACCEPT_ANY=true" + - "MP_ENABLE_PROMETHEUS=true" + - "MP_SMTP_AUTH_ALLOW_INSECURE=true" + + chrome: + image: "chromedp/headless-shell:140.0.7259.2" + ports: + - "9222:9222" + command: + - "--headless" + - "--disable-gpu" + - "--disable-dev-shm-usage" + - "--hide-scrollbars" + - "--mute-audio" + - "--no-default-browser-check" + - "--no-first-run" + - "--disable-background-networking" + - "--disable-background-timer-throttling" + - "--disable-extensions" + + pebble: + image: "letsencrypt/pebble:latest" + ports: + - "14000:14000" # ACME server + - "15000:15000" # Management interface + environment: + PEBBLE_VA_NOSLEEP: "1" # Don't sleep during validation for faster testing + PEBBLE_WFE_NONCEREJECT: "0" # Don't reject reused nonces + PEBBLE_VA_ALWAYS_VALID: "1" # Skip actual HTTP/DNS validation for local dev + command: pebble -config /test/config/pebble-config.json -dnsserver 127.0.0.1:8053 + volumes: + - "./compose/pebble:/test/config:ro" + + pebble-challtestsrv: + image: "letsencrypt/pebble-challtestsrv:latest" + ports: + - "8055:8055" # HTTP-01 challenge test server + - "8053:8053" # DNS server + - "8056:8056" # Management API + command: pebble-challtestsrv -dns01 ":8053" -http01 ":8055" -management ":8056" + +volumes: + probo-data: + postgres-data: + minio-data: + grafana-data: + prometheus-data: + tempo-data: diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 000000000..0f60842e1 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,127 @@ +#!/bin/bash +set -e + +# Configuration file path +CONFIG_FILE="${CONFIG_FILE:-/etc/probod/config.yml}" + +# Check if config file already exists (e.g., mounted from ConfigMap) +if [ -f "$CONFIG_FILE" ]; then + echo "Using existing configuration file at: $CONFIG_FILE" +else + echo "Generating configuration file from environment variables at: $CONFIG_FILE" + + # Create directory if it doesn't exist + mkdir -p "$(dirname "$CONFIG_FILE")" + + cat > "$CONFIG_FILE" <> "$CONFIG_FILE" <