--- title: Index url: https://containers.supanadit.com/index.md --- # Containers **Transparent, reproducible alternatives to Bitnami containers** A collection of production-ready Docker containers for databases, message brokers, observability, and big data — every image built with forge from a declarative forge.toml manifest and supervised by ezx. No setup.sh, no shell entrypoints, no mystery layers: fully reproducible, reviewable builds that run as non-root and are simple enough to operate without being a Docker expert. - **Registry:** ghcr.io/supanadit/containers - **License:** MIT License - **Repository:** - **Docs:** ## What it does Production-ready images for PostgreSQL, MariaDB, Kafka, Grafana, Prometheus, and more — each built from a declarative forge.toml manifest and supervised by a single Go binary. No setup.sh, no shell entrypoints, no root processes. An open alternative to Bitnami. ## The problem Most community container images ask you to trust them blindly. Entrypoints buried in setup.sh with implicit ordering and no review trail. Applications running as root because nobody got around to chowning. Config generated by sed one-liners that break on the first edge case. Build layers that recompile the world whenever one ARG changes. Health checks that return 200 while the app is still bootstrapping. These containers are built differently — declaratively, from source, with supervision built in. ## Features - **Declarative builds with forge** — Every image is assembled by forge from a forge.toml manifest: apt packages, pinned source downloads with checksums, compiled binaries, users, and cleanup as an ordered, dependency-resolved op list. - **Supervised by ezx** — A single Go binary stays PID 1: it forwards signals, reaps zombies, rotates logs, probes readiness, and drops privileges per process. The application never runs unsupervised. - **JavaScript entrypoints, zero shell** — Each container ships a small module set (env, validation, directories, config, runtime, health API) that validates, writes config, and starts the app. No bash to break at 3 a.m. - **Non-root by default** — Every application runs as its own dedicated user via process.user/process.group. /opt/containers/{data,config,logs,run,backup} is pre-created and pre-owned so volumes just work. - **Composite health endpoints** — Each image exposes a shared health server with app-specific probes plus a composite endpoint, so orchestrators see real readiness instead of a TCP handshake. - **Env-var driven configuration** — One env.js per container is the single source of truth for every variable. Config files are generated at boot from typed values — env.bool, env.int — never sed-edited. - **Checksum-verified downloads** — forge, ezx, JDK tarballs, and every pinned binary are downloaded and checksum-verified during the build. The supply chain is explicit and auditable. - **Tested in CI, per container** — Every container has compose-based test suites that assert the app answers on its own protocol, the composite health endpoint is healthy, the app runs as a non-root user, and ezx is PID 1. - **TLS and clustering ready** — Where the upstream app supports it, the container does too — PostgreSQL with TLS, etcd clusters, Kafka in KRaft mode, MinIO distributed — configured with plain environment variables. - **Working examples included** — The documentation site carries per-container guides — TLS, clustering, KRaft, pgBackRest — plus ready-made compose scenarios you can copy verbatim. ## The containers ### Databases - **postgresql** — PostgreSQL with optional TLS, composite health probing, and scheduled pgBackRest backups built in. - **mariadb** — MariaDB with scheduled backups, strict validation at boot, and a dedicated non-root daemon user. - **pgpool-ii** — Pgpool-II connection pooling and load balancing for PostgreSQL, using upstream launchers under ezx supervision. - **maxscale** — MariaDB MaxScale proxy for routing, filtering, and high availability in front of MariaDB clusters. ### Messaging & Coordination - **apache-kafka** — Apache Kafka in KRaft mode — no ZooKeeper required — with scheduled maintenance jobs and KRaft bootstrapping. - **apache-zookeeper** — Apache ZooKeeper ensemble node with generated dynamic configuration and fail-fast environment validation. - **etcd** — etcd built from source with a Go toolchain, cluster flags driven entirely by environment variables. ### Storage - **minio** — MinIO object storage compiled from upstream source, single-node or distributed layouts. ### Observability - **prometheus** — Prometheus with config generated at boot from environment variables and composite health probing. - **grafana** — Grafana dashboards with provisioning and datasource configuration handled by the entrypoint. - **grafana-loki** — Grafana Loki log aggregation, single-node or scalable, with S3-compatible storage support. - **grafana-mimir** — Grafana Mimir for long-term Prometheus metrics, in single-binary or clustered layouts. - **grafana-tempo** — Grafana Tempo distributed tracing backend with single-node and microservice compositions. - **grafana-alloy** — Grafana Alloy telemetry collector for pipelines that feed Loki, Mimir, and Tempo. - **grafana-pyroscope** — Grafana Pyroscope continuous profiling storage with single and multi-instance compositions. - **thanos** — Thanos for global Prometheus views — sidecar and store patterns covered by compose examples. ### Big Data & Workflow - **apache-airflow** — Apache Airflow with scheduler, webserver, and workers orchestrated as separate supervised nodes. - **apache-cassandra** — Apache Cassandra with rack/DC-aware seed configuration generated from environment variables. - **apache-flink** — Apache Flink with JobManager and TaskManager as supervised processes behind one entrypoint. - **apache-spark** — Apache Spark with master and worker nodes configured declaratively and health-checked. ### Web - **wordpress** — WordPress on Apache with generated wp-config.php, tuned php.ini, and MariaDB pairing in the examples. ## How it works Every container follows the same contract: a declarative forge.toml build, a JavaScript entrypoint with no shell, and an ezx supervisor that stays PID 1 for the lifetime of the container. Packages, checksum-verified sources, and pinned variables flow into forge, which resolves the manifest into a DAG and builds the image in parallel, ordered operations. At run time the ezx entrypoint validates the environment and writes config, then the supervisor stays PID 1: it drops privileges, forwards signals, and probes the composite health endpoint for the whole lifetime of the container. --- title: Containers url: https://containers.supanadit.com/containers.md --- # Containers — Catalog A collection of production-ready Docker containers for databases, message brokers, observability, and big data — every image built with forge from a declarative forge.toml manifest and supervised by ezx. No setup.sh, no shell entrypoints, no mystery layers: fully reproducible, reviewable builds that run as non-root and are simple enough to operate without being a Docker expert. Images are published as `ghcr.io/supanadit/containers/:`. ## Catalog ### Databases - **postgresql** — PostgreSQL with optional TLS, composite health probing, and scheduled pgBackRest backups built in. Image: `ghcr.io/supanadit/containers/postgresql` - **mariadb** — MariaDB with scheduled backups, strict validation at boot, and a dedicated non-root daemon user. Image: `ghcr.io/supanadit/containers/mariadb` - **pgpool-ii** — Pgpool-II connection pooling and load balancing for PostgreSQL, using upstream launchers under ezx supervision. Image: `ghcr.io/supanadit/containers/pgpool-ii` - **maxscale** — MariaDB MaxScale proxy for routing, filtering, and high availability in front of MariaDB clusters. Image: `ghcr.io/supanadit/containers/maxscale` ### Messaging & Coordination - **apache-kafka** — Apache Kafka in KRaft mode — no ZooKeeper required — with scheduled maintenance jobs and KRaft bootstrapping. Image: `ghcr.io/supanadit/containers/apache-kafka` - **apache-zookeeper** — Apache ZooKeeper ensemble node with generated dynamic configuration and fail-fast environment validation. Image: `ghcr.io/supanadit/containers/apache-zookeeper` - **etcd** — etcd built from source with a Go toolchain, cluster flags driven entirely by environment variables. Image: `ghcr.io/supanadit/containers/etcd` ### Storage - **minio** — MinIO object storage compiled from upstream source, single-node or distributed layouts. Image: `ghcr.io/supanadit/containers/minio` ### Observability - **prometheus** — Prometheus with config generated at boot from environment variables and composite health probing. Image: `ghcr.io/supanadit/containers/prometheus` - **grafana** — Grafana dashboards with provisioning and datasource configuration handled by the entrypoint. Image: `ghcr.io/supanadit/containers/grafana` - **grafana-loki** — Grafana Loki log aggregation, single-node or scalable, with S3-compatible storage support. Image: `ghcr.io/supanadit/containers/grafana-loki` - **grafana-mimir** — Grafana Mimir for long-term Prometheus metrics, in single-binary or clustered layouts. Image: `ghcr.io/supanadit/containers/grafana-mimir` - **grafana-tempo** — Grafana Tempo distributed tracing backend with single-node and microservice compositions. Image: `ghcr.io/supanadit/containers/grafana-tempo` - **grafana-alloy** — Grafana Alloy telemetry collector for pipelines that feed Loki, Mimir, and Tempo. Image: `ghcr.io/supanadit/containers/grafana-alloy` - **grafana-pyroscope** — Grafana Pyroscope continuous profiling storage with single and multi-instance compositions. Image: `ghcr.io/supanadit/containers/grafana-pyroscope` - **thanos** — Thanos for global Prometheus views — sidecar and store patterns covered by compose examples. Image: `ghcr.io/supanadit/containers/thanos` ### Big Data & Workflow - **apache-airflow** — Apache Airflow with scheduler, webserver, and workers orchestrated as separate supervised nodes. Image: `ghcr.io/supanadit/containers/apache-airflow` - **apache-cassandra** — Apache Cassandra with rack/DC-aware seed configuration generated from environment variables. Image: `ghcr.io/supanadit/containers/apache-cassandra` - **apache-flink** — Apache Flink with JobManager and TaskManager as supervised processes behind one entrypoint. Image: `ghcr.io/supanadit/containers/apache-flink` - **apache-spark** — Apache Spark with master and worker nodes configured declaratively and health-checked. Image: `ghcr.io/supanadit/containers/apache-spark` ### Web - **wordpress** — WordPress on Apache with generated wp-config.php, tuned php.ini, and MariaDB pairing in the examples. Image: `ghcr.io/supanadit/containers/wordpress` ## Categories - **Databases** — Run on their own protocol, health-checked and backed up. - **Messaging & Coordination** — KRaft Kafka, ZooKeeper, and etcd — clustering by environment variable. - **Storage** — Object storage built from source with distributed layouts. - **Observability** — The full Grafana LGTM stack plus Prometheus and Thanos. - **Big Data & Workflow** — Airflow, Cassandra, Flink, and Spark as supervised node sets. - **Web** — WordPress with generated configuration and tuned PHP. --- title: Install url: https://containers.supanadit.com/install.md --- # Containers — Install & Quickstart Images are published to GHCR per container. Pull one, mount the volume tree, and it boots with sane defaults. Registry: `ghcr.io/supanadit/containers` Tags: per-container, `-rX.Y.Z` (optionally prefixed with the upstream version, e.g. `wordpress-apache-6.9-r5`). Browse tags at ## Pull a container ```sh docker pull ghcr.io/supanadit/containers/postgresql: ``` ## Run PostgreSQL The /opt/containers tree is pre-created and pre-owned — mount straight onto it: ```sh docker run -d --name pg \ -p 5432:5432 \ -e POSTGRESQL_PASSWORD=secret \ -v pgdata:/opt/containers/data \ ghcr.io/supanadit/containers/postgresql: # the entrypoint registers a composite health endpoint on its shared health server ``` ## Or take a full example stack Ready-made compose scenarios and per-container guides live in the documentation: ```sh open https://docs.containers.supanadit.com/postgresql ``` ## Volume layout Every container uses the same tree, pre-created and owned by the application user: - `/opt/containers/data` — persistent data - `/opt/containers/config` — generated and mounted configuration - `/opt/containers/logs` — log output - `/opt/containers/run` — runtime state - `/opt/containers/backup` — backup targets ## Status & License License: MIT License — © 2026 Supan Adit Pratama. --- title: Faq url: https://containers.supanadit.com/faq.md --- # Containers — FAQ ## 1. What is this collection? A set of production-ready Docker containers — PostgreSQL, MariaDB, Kafka, etcd, MinIO, the Grafana observability stack, Airflow, Spark, and more — intended as a transparent alternative to Bitnami images. Every build and runtime decision is visible in the repository. ## 2. What makes these different from other community images? Nothing is hidden in shell scripts. Builds are declared in a forge.toml manifest executed by forge; the entrypoint is a small set of JavaScript modules executed by ezx, a Go supervisor that stays PID 1. Applications run as dedicated non-root users, downloads are checksum-verified, and every container ships compose-based CI tests. ## 3. Where do the images live? On GHCR under ghcr.io/supanadit/containers/, tagged per container as -rX.Y.Z (sometimes prefixed with the upstream version, e.g. wordpress-apache-6.9-r5). Pull the tag that matches your container. ## 4. How do I configure a container? With environment variables only. Each container declares its variables in a single env.js module, validates them at boot, and generates the application config file from them. Invalid environments fail fast — before any side effect. ## 5. Where are the volume paths? Every container uses the same tree: /opt/containers/data, config, logs, run, and backup, pre-created and owned by the application user in the image. Mount your volumes directly onto those paths. ## 6. Is there an example for my use case? Yes — the documentation site at docs.containers.supanadit.com has per-container guides and compose scenarios, including TLS setups, etcd and Kafka clusters, and S3-backed observability stacks. ## 7. What licence is this under? MIT. The forge build tool and the ezx supervisor are separate open-source projects of the same author.