containerbase
v1.0.261
Published
generic containerized application
Downloads
1,935
Maintainers
Readme
Project Status
Use case
An Arch Linux based container image for x86-64 and ARM64 to build your own application images on. It takes care of the parts every containerized application needs: running the application as an unprivileged user that matches the owner of your files on the host, decrypting secrets on startup and installing additional packages, including packages from the Arch User Repository.
Features included:
- Up-to-date Arch Linux with "base-devel", "git", "openssh" and "neovim", rebuilt regularly.
- AUR helper aura on x86-64.
- Maps the application user to the user and group id of your files on the host.
- Decrypts GPG encrypted files on startup with a password from a Docker secret, a file or an environment variable.
- Optionally clones your application from a git repository at build time.
- Includes the bashlink shell library.
Quick start
Open a shell in the image:
docker run --entrypoint /usr/bin/bash --interactive --rm --tty \
ghcr.io/thaibault/containerbase:latestRun a command as application user:
docker run --env COMMAND="echo 'whoami'" --rm \
ghcr.io/thaibault/containerbase:latestBuilding your own image
Start from the image, install what your application needs, copy it to "/application/" and tell the image how to start it. This example runs a Node.js script:
FROM ghcr.io/thaibault/containerbase:latest
USER $INSTALLER_USER_NAME
RUN pacman-wrapper \
--noconfirm --refresh --sync --sysupgrade nodejs && \
clean-up
USER root
COPY --chown=application:users . $APPLICATION_PATH
ENV COMMAND="echo 'node index.js'"- Install packages as user "installer" with "pacman-wrapper". It uses aura if available, so AUR packages work as well, otherwise pacman. Always update the whole system along with it, Arch Linux does not support partial upgrades.
- "clean-up" removes package caches and orphaned packages to keep the image small. Pass package names to remove them as well.
- The owner of "/application/package.json" decides which user runs the application, see user mapping. Without "--chown" it is "root".<!--deDE:Der Besitzer von "/application/package.json" bestimmt, welcher Benutzer die Anwendung ausführt, siehe Benutzerzuordnung. Ohne "--chown" ist das "root".--><!--frFR:Le propriétaire de "/application/package.json" détermine l'utilisateur qui exécute l'application, voir correspondance des utilisateurs. Sans "--chown", c'est "root".-->
The start command
"COMMAND" is evaluated by the shell on startup and its output is the command which is run. This allows composing the command from environment variables which are only known at runtime. Arguments given to "docker run" after the image name are appended before evaluation:
docker run --env COMMAND="echo echo" --rm \
ghcr.io/thaibault/containerbase:latest hello world
# Prints "hello world".Startup sequence
The entry point "/usr/bin/initialize" runs these steps:
- Hands over to an "initialize.sh" next to one of the environment files if present, so your application can replace the whole sequence.
- Loads the environment files "/etc/containerBase/environment.sh", "/application/serviceHandler/environment.sh" and "/application/environment.sh" if they exist.
- Decrypts encrypted files if "DECRYPT" is "true".
- Maps the application user to the host ids.
- Runs the command as application user, or as "root" if mapped to it.
User mapping
Files written by your application into mounted host directories should belong to you, not to an unknown user id. On startup the image therefore changes the user and group ids of its application user "application" to the ids given in "HOST_USER_ID" and "HOST_USER_GROUP_ID". If they are not set, the owner of "/application/package.json" is used. Mounting your project to "/application/" is therefore enough during development:
docker run --rm --volume "$(pwd):/application" your-imageIf the ids resolve to "0" the command runs as "root". Change the reference file via "APPLICATION_USER_ID_INDICATOR_FILE_PATH".
Encrypted files
Keep secrets like certificates or credentials encrypted in your repository and image. Encrypt a directory with GPG using the included "crypt" script:
docker run --entrypoint crypt --rm --volume "$(pwd):/work" --workdir /work \
ghcr.io/thaibault/containerbase:latest \
--password-file password plain/ encrypted/Each file is stored with a ".gpg" suffix. Put the result to "/application/encrypted/" and start the container with "DECRYPT=true". The files are then available unencrypted below "/tmp/plain/". The password is taken from the first available source:
- Docker secret "encryption_password", i.e. "/run/secrets/encryption_password".
- File "/application/.encryptionPassword".
- Environment variable "DECRYPTION_PASSWORD".
docker run --env DECRYPT=true --env DECRYPTION_PASSWORD=secret --rm your-image"ENCRYPTED_PATHS", "DECRYPTED_PATHS", "PASSWORD_SECRET_NAMES" and "PASSWORD_FILE_PATHS" accept space separated lists to handle several directories with different passwords. "encrypt" does the reverse based on the same settings.
Retrieving the application from git
Instead of copying files, an image can clone its application at build time. Set "REPOSITORY_URL", "PRIVATE_SSH_KEY", "PUBLIC_SSH_KEY" and "KNOWN_HOSTS", optionally the build argument "BRANCH_NAME" (default "main"), and run "retrieve-application". It clones the repository including submodules to "/application/" and removes the git metadata afterwards.
Environment variables
- "COMMAND": Command generator, see above.
- "APPLICATION_PATH": Application directory, "/application/".
- "ENVIRONMENT_FILE_PATHS": Shell files loaded on startup.
- "MAIN_USER_NAME" and "MAIN_USER_GROUP_NAME": Application user and group, "application" and "users".
- "HOST_USER_ID", "HOST_USER_GROUP_ID" and "APPLICATION_USER_ID_INDICATOR_FILE_PATH": User mapping.
- "DECRYPT", "ENCRYPTED_PATHS", "DECRYPTED_PATHS", "DECRYPTION_PASSWORD", "PASSWORD_SECRET_NAMES" and "PASSWORD_FILE_PATHS": Encrypted files.
- "REPOSITORY_URL", "PRIVATE_SSH_KEY", "PUBLIC_SSH_KEY", "KNOWN_HOSTS" and "STANDALONE": Retrieving the application.
Building the base image
The image is bootstrapped from scratch with pacman, so it can be built for several architectures:
docker buildx build --platform linux/amd64,linux/arm64 \
--tag ghcr.io/thaibault/containerbase:latest .- "MIRROR_AREA_PATTERN": Restrict the pacman mirror list to a region, e.g. "Germany".
- A file "custom-root-ca.crt" next to the Dockerfile is trusted while bootstrapping, e.g. behind a company proxy.
Development
yarn install
yarn lint
yarn test