Sign inSign up

bfren/alpine

By bfren

•Updated about 7 hours ago

Alpine Linux with various useful executables

Image
Operating systems
0

100K+

bfren/alpine repository overview

⁠Alpine

GitHub release (latest by date) Docker Pulls Docker Image Size GitHub Workflow Status

Docker Hub⁠ - Quay.io⁠ - bfren ecosystem⁠

⁠Introduction

This is the foundation of the bfren ecosystem⁠ - every other image is built on it, either directly or through Alpine + S6⁠.

It is Alpine Linux⁠ with:

  • Nushell⁠ and the bf module, for writing installation and start-up scripts with structured data and real error handling
  • a custom build of BusyBox⁠ with its default config plus relevant patches from Alpine Linux
  • a standard build step (bf-install) so every image is installed and cleaned up the same way
  • a shared environment store, so every script sees the same variables
  • helper executables for shell scripts, and esh⁠ for templates

Use it as the FROM line for images that run a single command or tool. For images that run a long-lived service, use Alpine + S6⁠ instead.

⁠Quickstart

my-image/
├── Dockerfile
└── overlay/
    └── tmp/
        └── install

Dockerfile:

FROM quay.io/bfren/alpine:alpine3.24-3.5

ARG BF_IMAGE=my-image
ARG BF_VERSION=1.0.0

COPY ./overlay /
RUN bf-install

overlay/tmp/install - your installation script, run by bf-install:

#!/usr/bin/nu

use bf

# Install my-image
def main [] {
    bf pkg install [curl jq]
    bf write ok "my-image installed."
}

Build it and open a shell:

docker build -t my-image . && docker run --rm -it my-image nu

Inside the container, bf image shows the image name and version.

⁠Features

  • 🐧 Alpine 3.15 to 3.24 - choose with the image tag
  • 🐚 Nushell, with the bf module loaded in every shell
  • 🧱 bf-install - one standard build step for every image
  • 🌍 Container environment saved at start-up and available to every script
  • 🛠️ Helper executables (bf-env, bf-write, bf-wget, …) for shell scripts
  • 📝 esh⁠ for generating files from templates
  • 🕐 Timezone set to Europe/London
  • 🧪 Built-in test runner that checks its tests really execute

⁠Tags

Images are published to Docker Hub (bfren/alpine) and Quay.io (quay.io/bfren/alpine) for linux/amd64, linux/arm/v7 and linux/arm64.

TagExampleUse when
alpineX.Yalpine3.24You want the latest image for an Alpine version
alpineX.Y-MAJORalpine3.24-3You want updates, but not breaking changes
alpineX.Y-MINORalpine3.24-3.5You want fixes only - recommended for building on
alpineX.Y-VERSIONalpine3.24-3.5.0You want to pin this image exactly
alpineX.Y.Zalpine3.24.2You want an exact Alpine release
alpineX.Y.Z-VERSIONalpine3.24.2-3.5.0You want to pin both
latest, 3, 3.5, 3.5.0As above, on the newest Alpine version
AlpineSecurity support ends
3.242028-06-01
3.232027-11-01
3.222027-05-01
3.212026-11-01
3.20ended 2026-04-01
3.19ended 2025-11-01
3.18ended 2025-05-09
3.17ended 2024-11-22
3.16ended 2024-05-23
3.15ended 2023-11-01

Images for unsupported Alpine versions are still built, but no longer receive Alpine security fixes - avoid them for anything new.

⁠Configuration

⁠Environment Variables
VariableValuesDescriptionDefault
BF_DEBUG0, 1Show detailed output from bf scripts.0
⁠Build Arguments
ArgumentDescription
BF_IMAGERequired by bf-install. The image name, saved to /etc/bf/IMAGE.
BF_VERSIONRequired by bf-install. The image version, saved to /etc/bf/VERSION.
BF_PUBLISHINGSet to 1 for release builds - removes the test files and preinstall script.

⁠How It Works

⁠Building

bf-install is the standard last step of every bfren Dockerfile. It:

  1. shows the build log and BF_ variables
  2. sets standard permissions
  3. runs /tmp/install if it exists - put your own installation steps there
  4. saves the image name and version
  5. cleans up /tmp, the package cache and placeholder .empty files
⁠Starting

/init is the entrypoint. It saves the container's environment - including anything you pass with -e - to /etc/bf/env.d, then runs your command.

⁠Environment

Scripts load the saved environment with bf env load. For example, after docker run -e BF_GREETING=hello …:

use bf
bf env load

def main [] {
    bf write $"The greeting is (bf env GREETING)."
}

bf env GREETING reads BF_GREETING - the BF_ prefix is added for you. bf env set NAME value saves BF_NAME for every later script.

Shell scripts can run commands with a clean environment loaded from /etc/bf/env.d using withenv, e.g. withenv my-command. Interactive nu shells reload the environment before each prompt.

⁠The bf module
SubmoduleUse
bf buildRead the image build log, and add entries to it
bf chSet ownership and permissions on files and directories
bf cleanRemove temporary files, package caches and .empty placeholders
bf configAdd lines and modules to the shared Nushell config
bf delDelete files or directories older than a given age
bf dumpPrint a value when debug output is enabled, then pass it on
bf envGet, set, check, load and store environment variables
bf eshGenerate output from an esh template
bf fsRead files, find paths and make temporary directories
bf handleRun an external command and turn failures into Nushell errors
bf httpDownload files and check URLs
bf imageShow a banner with the image name, version and Alpine version
bf installRun the standard image installation (used by bf-install)
bf pkgInstall, remove and upgrade Alpine packages
bf stringQuote strings and fill {placeholder} templates
bf testDiscover and run the tests in /etc/nu/scripts/tests
bf tzGet and set the timezone
bf userAdd users and groups
bf versionCompare and bump version numbers
bf writeWrite timestamped, coloured output (ok, notok, warn, error, debug)
bf xRun a script with BF_X set to its name, so its output is labelled

Run help bf <submodule> in a nu shell for details.

Many of these have executable helpers on the PATH for shell scripts. For example, bf-image runs bf image, which is handy with docker exec. Check out overlay/usr/bin/bf for the complete list.

⁠Testing

/test runs the Nushell tests in /etc/nu/scripts/tests (/test-without-http skips tests that need the internet). Before running, it checks that tests really execute and fails if they don't. Tests are removed from published images, so run them on your own builds.

./test.nu        # builds the image and runs /test
./test.nu --all  # every version, in parallel

⁠Troubleshooting

⁠The container exits straight away

The image has no default command. Give it one, e.g. docker run --rm -it bfren/alpine nu.

⁠The build fails with "Unable to get environment variable BF_IMAGE"

bf-install needs the BF_IMAGE and BF_VERSION build arguments. Declare them in your Dockerfile (see Quickstart⁠) or pass them with --build-arg.

⁠Setting BF_TZ does nothing

In this image the timezone is set when the image is built. Call bf tz Europe/Paris (for example) in your /tmp/install, or use Alpine + S6⁠, which applies BF_TZ every time the container starts.

⁠/test says the tests directory does not exist

Published images have their tests removed. Build the image yourself without BF_PUBLISHING=1.

⁠FAQs

⁠Should I use this image or Alpine + S6?

Use this one for images that run a single command - a CLI tool, a build step, PHP scripts. Use Alpine + S6⁠ for long-running services, especially if they need scheduled tasks or start-up checks.

⁠Why save the environment at start-up?

Anything that doesn't inherit the container's environment - scheduled tasks, other users, scripts run with a clean environment - can still read the same values from /etc/bf/env.d.

⁠Why Nushell?

Structured data, real error handling and modules make installation and start-up scripts much easier to read and test than shell scripts - while still being small enough for an Alpine image.

⁠Licence

Copyright (c) 2021-2026 bfren⁠ (unless otherwise stated)

Tag summary

Content type

Image

Digest

sha256:55202d1a8…

Size

23.8 MB

Last updated

about 7 hours ago

docker pull bfren/alpine:alpine3.17.10-3.5.2-dev