Skip to content

Instantly share code, notes, and snippets.

@shvargon
Created January 23, 2024 06:11
Show Gist options
  • Save shvargon/8c2a62bd57399c0900afce002287ab88 to your computer and use it in GitHub Desktop.
Save shvargon/8c2a62bd57399c0900afce002287ab88 to your computer and use it in GitHub Desktop.
Create base astra linux docker base image

Example usage

build-docker-image.sh -r http://dl.astralinux.ru/astra/frozen/1.7_x86-64/1.7.4/repository-main \
  -c 1.7_x86-64 -i alse:174-base --cache-dir $HOME/debcache
build-docker-image.sh -r http://dl.astralinux.ru/astra/frozen/1.7_x86-64/1.7.4/repository-main \
  -c 1.7_x86-64 -i alse:174-slim --cache-dir $HOME/debcache -s
build-docker-image.sh -r http://dl.astralinux.ru/astra/frozen/1.7_x86-64/1.7.4/repository-main \
  -u http://dl.astralinux.ru/astra/frozen/1.7_x86-64/1.7.4/repository-update \
  -c 1.7_x86-64 -i alse:174-update --cache-dir $HOME/debcache
build-docker-image.sh -r http://dl.astralinux.ru/astra/frozen/1.7_x86-64/1.7.4/repository-main \
  -u http://dl.astralinux.ru/astra/frozen/1.7_x86-64/1.7.4/repository-update \
  -c 1.7_x86-64 -i alse:174-update-slim --cache-dir $HOME/debcache    
#!/bin/sh
program=$(basename $0)
version=1.0
set -e
pkg_missing=false
for required_pkg in docker.io debootstrap; do
if ! dpkg -l $required_pkg >/dev/null 2>/dev/null; then
printf 'Please install %s package\n' $required_pkg
pkg_missing=true
fi
done
if $pkg_missing; then
exit 1
fi
# Check docker can be run without sudo
docker version 2>&1 >/dev/null ||\
(printf 'Please run with sudo or add your account to `docker` group\n';\
exit 1)
usage="\
Usage:
$program -v
Print program version
$program -r REPOSITORY [-c CODENAME] -i IMAGE_NAME [-b]
Create Docker image IMAGE_NAME based on REPOSITORY with CODENAME
-v Print version
-r REPOSITORY Address of the repository
-u UPDATE Address of the repository update
-c CODENAME Codename (specified in $REPOSITORY/dists)
-i IMAGE_NAME Name of the image being created
-b Install base Astra Linux packages
-s Create slim version
-d, --cache-dir Select cache-directory
-m, --merged-usr Merged usr (default false)
default CODENAME is \"stable\""
invalid_args() {
echo "${usage}" 1>&2
exit 1
}
REPO=$REPO
UPDATE=$UPDATE
IMAGE=$IMAGE
CODENAME="${CODENAME:-stable}"
install_base_pkgs=false
slim=false
merged=false
for arg in "$@"; do
shift
case "$arg" in
'--cache-dir') set -- "$@" '-d' ;;
*) set -- "$@" "$arg" ;;
esac
done
while getopts 'r:u:c:i:d:vbsm' option; do
case $option in
r)
REPO=$OPTARG
;;
u)
UPDATE=$OPTARG
;;
i)
IMAGE=$OPTARG
;;
c)
CODENAME=$OPTARG
;;
b)
install_base_pkgs=true
;;
v)
echo $program $version
;;
s)
slim=true
;;
m)
merged=true
;;
d)
CACHE_DIR=$OPTARG
;;
?)
invalid_args
;;
esac
done
if [ -z $REPO ]; then
echo Please specify -r \(repository\) argument
fi
if [ -z $IMAGE ]; then
echo Please specify -i \(image\) argument
fi
if [ -z $REPO ] || [ -z $IMAGE ]; then
invalid_args
fi
ROOTFS_IMAGE="$IMAGE-rootfs"
TMPDIR=`mktemp -d`
cd $TMPDIR
cleanup() {
cd $HOME
# debootstrap leaves mounted /proc and /sys folders in chroot
# when terminated by Ctrl-C
sudo umount $TMPDIR/proc $TMPDIR/sys >/dev/null 2>/dev/null || true
# Delete temporary data at exit
sudo rm -rf $TMPDIR
}
trap cleanup EXIT
extraArgs=()
if [ -n "${CACHE_DIR}" ]; then
extraArgs+=(--cache-dir=$CACHE_DIR)
fi
if ! $merged ; then
extraArgs+=(--no-merged-usr)
fi
sudo -E debootstrap --no-check-gpg --variant=minbase \
--components=main,contrib,non-free \
"${extraArgs[@]}" "$CODENAME" ./chroot "$REPO"
cat <<EOF | sudo tee -a ./chroot/etc/apt/apt.conf.d/docker-autoremove-suggests
# Since Docker users are looking for the smallest possible final images, the
# following emerges as a very common pattern:
# RUN apt-get update \
# && apt-get install -y <packages> \
# && <do some compilation work> \
# && apt-get purge -y --auto-remove <packages>
# By default, APT will actually _keep_ packages installed via Recommends or
# Depends if another package Suggests them, even and including if the package
# that originally caused them to be installed is removed. Setting this to
# "false" ensures that APT is appropriately aggressive about removing the
# packages it added.
# https://aptitude.alioth.debian.org/doc/en/ch02s05s05.html#configApt-AutoRemove-SuggestsImportant
Apt::AutoRemove::SuggestsImportant "false";
EOF
cat <<EOF | sudo tee -a ./chroot/etc/apt/apt.conf.d/docker-clean
# Since for most Docker users, package installs happen in "docker build" steps,
# they essentially become individual layers due to the way Docker handles
# layering, especially using CoW filesystems. What this means for us is that
# the caches that APT keeps end up just wasting space in those layers, making
# our layers unnecessarily large (especially since we'll normally never use
# these caches again and will instead just "docker build" again and make a brand
# new image).
# Ideally, these would just be invoking "apt-get clean", but in our testing,
# that ended up being cyclic and we got stuck on APT's lock, so we get this fun
# creation that's essentially just "apt-get clean".
DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };
APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };
Dir::Cache::pkgcache "";
Dir::Cache::srcpkgcache "";
# Note that we do realize this isn't the ideal way to do this, and are always
# open to better suggestions (https://github.com/debuerreotype/debuerreotype/issues).
EOF
cat <<EOF | sudo tee -a ./chroot/etc/apt/apt.conf.d/docker-gzip-indexes
# Since Docker users using "RUN apt-get update && apt-get install -y ..." in
# their Dockerfiles don't go delete the lists files afterwards, we want them to
# be as small as possible on-disk, so we explicitly request that Apt keep them
# compressed on-disk too instead of decompressing them.
# For comparison, an "apt-get update" layer without this on a pristine
# "debian:wheezy" base image was "29.88 MB", where with this it was only
# "8.273 MB".
Acquire::GzipIndexes "true";
EOF
cat <<EOF | sudo tee -a ./chroot/etc/apt/apt.conf.d/docker-no-language
# In Docker, we don't often need the "Translations" files, so we're just wasting
# time and space by downloading them, and this inhibits that. For users that do
# need them, it's a simple matter to delete this file and "apt-get update". :)
Acquire::Languages "none";
EOF
cat <<EOF | sudo tee -a ./chroot//etc/dpkg/dpkg.cfg.d/docker-apt-speedup
# For most Docker users, package installs happen during "docker build", which
# doesn't survive power loss and gets restarted clean afterwards anyhow, so
# this minor tweak gives us a nice speedup (much nicer on spinning disks,
# obviously).
force-unsafe-io
EOF
echo "deb $REPO $CODENAME contrib main non-free" | sudo tee ./chroot/etc/apt/sources.list
if [ -n "${UPDATE}" ]; then
echo "deb $UPDATE $CODENAME contrib main non-free" | sudo tee -a ./chroot/etc/apt/sources.list
sudo chroot ./chroot /bin/sh -c "apt update && DEBIAN_FRONTEND=noninteractive apt dist-upgrade -y"
fi
# TODO maybe don`t delete ./chroot/usr/share/locale/* \
if $slim; then
sudo rm -rf ./chroot/usr/share/doc/* \
./chroot/usr/share/info/* \
./chroot/usr/share/linda/* \
./chroot/usr/share/lintian/overrides/* \
./chroot/usr/share/locale/* \
./chroot/usr/share/man/*;
for i in $(seq 1 8); do sudo mkdir -p "./chroot/usr/share/man/man${i}"; done
fi
docker rmi "$ROOTFS_IMAGE" 2>/dev/null || true
tarArgs=()
excludes+=(
'./var/log/apt/history.log'
'./var/log/apt/term.log'
'./var/cache/apt/**'
'./var/lib/apt/lists/**'
'./dev/**'
'./proc/**'
'./sys/**'
)
for exclude in "${excludes[@]}"; do
tarArgs+=( --exclude "$exclude" )
done
sudo tar "${tarArgs[@]}" -C chroot -c . --sort name --numeric-owner | docker import - "$ROOTFS_IMAGE"
docker rmi "$IMAGE" 2>/dev/null || true
if $install_base_pkgs; then
cmd="echo Installing base packages && apt-get install -y parsec parsec-tests linux-astra-modules-common astra-safepolicy lsb-release acl perl-modules-5.28 ca-certificates"
else
cmd="true"
fi
docker build --network=host --no-cache=true -t "$IMAGE" - <<EOF
FROM $ROOTFS_IMAGE
ENV TERM xterm-256color
ENV DEBIAN_FRONTEND noninteractive
RUN set -ex; apt-get update && $cmd && rm -rf /var/lib/apt/lists/*
WORKDIR /
CMD bash
EOF
printf 'Docker image "%s" has been generated\n' "$IMAGE"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment