GitHub - tzahifadida/oys-bitnami-builder: An interactive script to discover, build, and deploy Bitnami containers with multi-platform support and flexible output options.

4 min read Original article ↗

Bitnami Container Builder

An interactive script to discover, build, and deploy Bitnami containers with multi-platform support and flexible output options.

Features

  • 🔍 Interactive Menu - Browse and select from all available Bitnami containers
  • 🏗️ Multi-Platform Builds - Support for ARM64, AMD64, and other architectures
  • 📦 Dual Output Modes - Push to registries OR create portable OCI archives
  • 🤖 Automation Ready - Fully scriptable for CI/CD and cron jobs
  • 🔐 Registry Flexibility - Works with Docker Hub, private registries, and local registries
  • Smart Caching - Sparse Git clones and intelligent rebuild detection

Quick Start

# Clone and make executable
git clone <your-repo>
chmod +x oys-bitnami-builder.sh

# Interactive mode (default)
./oys-bitnami-builder.sh

# Show help
./oys-bitnami-builder.sh help

IMPORTANT NOTES

I have designed and built this with Claude, so there may be bugs like any sofware and this is a first version.

Prerequisites

Required

  • Docker with buildx support
  • Git
  • Bash 4.0+

Optional (for archive mode)

  • Skopeo - Required for OCI archive creation
  • Buildah - Optional, enables multi-arch manifest archives
  • curl - For registry connectivity testing

Installation Examples

macOS (Homebrew):

brew install docker git skopeo buildah

Ubuntu/Debian:

apt update && apt install -y docker.io git skopeo buildah curl

RHEL/CentOS:

yum install -y docker git skopeo buildah curl

Usage Modes

1. Interactive Menu (Default)

Browse and select from all available Bitnami containers:

=== Available Bitnami Containers ===

Choose a container to build:

  1) gitea                1/debian-12              (v1.21.5)
  2) nginx                1.25/debian-12           (v1.25.3)
  3) postgresql           15/debian-12             (v15.5.0)
  4) redis                7.2/debian-12            (v7.2.4)
  ...

Enter your choice (0-123):

2. Direct Build

# Build specific container
REPO=gitea SUBDIR=bitnami/gitea/1/debian-12 ./oys-bitnami-builder.sh build

# Non-interactive build
INTERACTIVE=false REPO=nginx SUBDIR=bitnami/nginx/1.25/debian-12 ./oys-bitnami-builder.sh build

3. List Available Containers

./oys-bitnami-builder.sh list

Configuration Options

Environment Variables

Variable Default Description
REGISTRY docker.io Target registry (docker.io, localhost:5000, registry.company.com)
NS tzahifadida Namespace/organization name
PLATFORMS linux/amd64,linux/arm64 Target platforms for multi-arch builds
OUTPUT_MODE push Output mode: push or archive
ARCHIVE_DIR ./archives Directory for OCI archives (archive mode only)
TAG_LATEST true Also create :latest tag
FORCE_REBUILD false Force rebuild even if image/archive exists
INTERACTIVE true Enable interactive prompts
REGISTRY_AUTH auto Authentication: auto, login, or none
CLEANUP_IMAGES false Remove local images after archiving
WORKDIR .bitnami-containers-src Local cache directory

Output Modes

Push Mode (Default)

Builds and pushes multi-platform images directly to a registry.

# Docker Hub
./oys-bitnami-builder.sh

# Private registry  
REGISTRY=registry.company.com ./oys-bitnami-builder.sh

# Local registry
REGISTRY=localhost:5000 ./oys-bitnami-builder.sh

Output:

  • Multi-platform manifests in registry
  • Automatic platform detection and building
  • Registry authentication handling

Archive Mode

Creates portable OCI archives using Skopeo, perfect for air-gapped environments.

# Create archives
OUTPUT_MODE=archive ./oys-bitnami-builder.sh

# Custom archive location
OUTPUT_MODE=archive ARCHIVE_DIR=/backup/containers ./oys-bitnami-builder.sh

Single Platform Output:

archives/
├── tzahifadida-nginx-1.25.3.tar
└── tzahifadida-nginx-latest.tar

Multi-Platform Output:

archives/
├── tzahifadida-nginx-1.25.3-linux-amd64.tar
├── tzahifadida-nginx-1.25.3-linux-arm64.tar
├── tzahifadida-nginx-1.25.3-multiarch.tar    # if buildah available
├── tzahifadida-nginx-latest-linux-amd64.tar
└── tzahifadida-nginx-latest-linux-arm64.tar

Registry Support

Docker Hub

# Default behavior
./oys-bitnami-builder.sh

# With custom namespace
NS=mycompany ./oys-bitnami-builder.sh

Private Registry

# HTTPS registry
REGISTRY=registry.company.com ./oys-bitnami-builder.sh

# HTTP registry with port
REGISTRY=localhost:5000 ./oys-bitnami-builder.sh

# Skip authentication prompts
REGISTRY=my-registry.com REGISTRY_AUTH=none ./oys-bitnami-builder.sh

Automation & CI/CD

Cron Job Examples

Daily builds (skip if exists):

# /etc/cron.d/container-builds
0 2 * * * user INTERACTIVE=false REPO=nginx SUBDIR=bitnami/nginx/1.25/debian-12 /path/to/oys-bitnami-builder.sh build

Weekly full rebuilds:

0 3 * * 0 user INTERACTIVE=false FORCE_REBUILD=true OUTPUT_MODE=archive REPO=gitea SUBDIR=bitnami/gitea/1/debian-12 /path/to/oys-bitnami-builder.sh build

CI/CD Pipeline Example

# GitHub Actions / GitLab CI example
build-containers:
  script:
    - export INTERACTIVE=false
    - export REGISTRY=registry.company.com
    - export REGISTRY_AUTH=none
    - export OUTPUT_MODE=archive
    - export FORCE_REBUILD=true
    - ./oys-bitnami-builder.sh build
  artifacts:
    paths:
      - archives/

Batch Building Script

#!/bin/bash
containers=(
  "nginx|bitnami/nginx/1.25/debian-12"
  "redis|bitnami/redis/7.2/debian-12" 
  "postgresql|bitnami/postgresql/15/debian-12"
)

for container in "${containers[@]}"; do
  IFS='|' read -r repo subdir <<< "$container"
  echo "Building $repo..."
  INTERACTIVE=false REPO="$repo" SUBDIR="$subdir" ./oys-bitnami-builder.sh build
done

Working with Archives

Loading Archives with Skopeo

# Load to local Docker daemon
skopeo copy oci-archive:tzahifadida-nginx-1.25.3.tar docker-daemon:nginx:1.25.3

# Load specific platform
skopeo copy oci-archive:tzahifadida-nginx-1.25.3-linux-amd64.tar docker-daemon:nginx:1.25.3

# Deploy to another registry
skopeo copy oci-archive:tzahifadida-nginx-1.25.3-linux-arm64.tar docker://prod-registry.com/nginx:1.25.3

# Copy between registries
skopeo copy oci-archive:tzahifadida-nginx-1.25.3-multiarch.tar docker://registry.company.com/nginx:1.25.3

Loading with Podman

podman load < tzahifadida-nginx-1.25.3.tar

Advanced Examples

Multi-Registry Deployment

# Build once, deploy to multiple registries
OUTPUT_MODE=archive PLATFORMS="linux/amd64,linux/arm64" ./oys-bitnami-builder.sh

# Deploy to production
skopeo copy oci-archive:tzahifadida-nginx-1.25.3-linux-amd64.tar docker://prod-registry.com/nginx:1.25.3-amd64
skopeo copy oci-archive:tzahifadida-nginx-1.25.3-linux-arm64.tar docker://prod-registry.com/nginx:1.25.3-arm64

Custom Namespace and Tagging

# Custom namespace for company builds
NS=acme-corp REGISTRY=registry.acme.com ./oys-bitnami-builder.sh

# Results in: registry.acme.com/acme-corp/nginx:1.25.3

Development Workflow

# Quick local testing
REGISTRY=localhost:5000 PLATFORMS=linux/amd64 ./oys-bitnami-builder.sh

# Production multi-arch build  
REGISTRY=prod-registry.com PLATFORMS="linux/amd64,linux/arm64" FORCE_REBUILD=true ./oys-bitnami-builder.sh

Troubleshooting

Common Issues

1. "Missing dependency" errors

# Install missing tools
brew install docker git skopeo  # macOS
apt install docker.io git skopeo  # Ubuntu

2. "Cannot access registry" warnings

# Login to registry first
docker login registry.company.com

# Or skip authentication
REGISTRY_AUTH=none ./oys-bitnami-builder.sh

3. "buildx builder not found"

# Create and use a buildx builder
docker buildx create --name mbuilder --use
docker buildx inspect --bootstrap

4. Archive mode fails

# Check if skopeo is installed
which skopeo

# Install skopeo
brew install skopeo  # macOS
apt install skopeo   # Ubuntu