Proces budowania kontenerów

Budowanie własnych kontenerów w procesie CI/CD może wydawać się skomplikowane — ale wcale nie musi takie być. W tym wpisie pokażę krok po kroku, jak przygotować pipeline do budowania i publikowania obrazów kontenerowych z użyciem narzędzia Buildah.
Cały proces ilustruje poniższy diagram:
--- config: theme: neo layout: dagre look: neo --- flowchart LR subgraph s1["Przygotowanie procesu CI"] n5["Przygotowanie tymczasowego obrazu z buildah"] n6["Przygotowanie procesu gitlab-ci"] n7["Utworzenie komponentu build"] n11["Utworzenie komponentu publish"] end subgraph s2["Przygotowanie kontenera"] n8["Utworzenie pliku config.yml"] n9["git push"] end n5 --> n6 n6 --> n7 s1 --> s2 n8 --> n9 s2 --> n10("Container") n7 --> n11 n5@{ shape: rect} n6@{ shape: rect} n7@{ shape: rect} n9@{ shape: lean-r} click n5 "#przygotowanie-tymczasowego-obrazu-z-buildah" click n6 "#przygotowanie-procesu-gitlab-ci" click n7 "#utworzenie-komponentu-build" click n11 "#utworzenie-komponentu-publish" click n8 "#przygotowanie-obrazu-buildah--image-builderem"
Przygotowanie procesu CI
Przygotowanie tymczasowego obrazu z Buildah
Przygotowujemy obraz Dockerfile:
FROM ubuntu:noble
ENV DEBIAN_FRONTEND=noninteractive
ENV STORAGE_DRIVER=vfs
ENV BUILDAH_ISOLATION=chroot
COPY scripts/ /opt/scripts/
# Install system dependencies and ansible
RUN apt-get update && apt-get install -y \
buildah \
curl \
fuse-overlayfs \
gzip \
slirp4netns \
iproute2 \
uidmap \
iputils-ping \
dnsutils \
ca-certificates \
git \
curl \
gnupg \
sudo \
software-properties-common \
tar \
yq \
zip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /tmp/buildah-root \
&& mkdir -p /tmp/buildah-runroot \
# Make scripts executable
&& chmod +x /opt/scripts/*.bash
ENTRYPOINT ["/opt/scripts/entrypoint.bash"]
Budowanie i publikacja obrazu:
docker login registry.gitlab.com
docker build -t registry.gitlab.com/pl.rachuna-net/containers/buildah:0.0.1 .
docker push registry.gitlab.com/pl.rachuna-net/containers/buildah:0.0.1
Przygotowanie procesu GitLab CI
Przykładowy .gitlab-ci.yml
:
default:
tags:
- process-ci
stages:
- prepare
- validate
- unit-test
- sast
- dast
- build
- publish
- release
- deploy
- integration-test
- cleanup
workflow:
rules:
- if: '$CI_COMMIT_TAG'
when: never
- if: $CI_PIPELINE_SOURCE == "push" && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TITLE =~ /^([Draft]|\(Draft\)|Draft:)/
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "web"
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_COMMIT_BRANCH
include:
- component: $CI_SERVER_FQDN/pl.rachuna-net/cicd/components/release/versioning@$COMPONENT_VERSION_RELEASE
inputs:
docker_image: $CONTAINER_IMAGE_SEMANTIC_RELEASE
- component: $CI_SERVER_FQDN/pl.rachuna-net/cicd/components/build/image-builder@feat/215
inputs:
docker_image: registry.gitlab.com/pl.rachuna-net/containers/buildah:1.0.0-4241d7e7
- component: $CI_SERVER_FQDN/pl.rachuna-net/cicd/components/publish/image-builder@feat/220
inputs:
docker_image: registry.gitlab.com/pl.rachuna-net/containers/buildah:1.0.0-4241d7e7
🕵 Set Version:
stage: prepare
rules:
- when: on_success
🚀 build container image:
stage: build
variables:
CONTAINER_VERSION: $RELEASE_CANDIDATE_VERSION
rules:
- when: on_success
🌐 publish container image:
stage: publish
needs:
- job: 🕵 Set Version
artifacts: true
variables:
CONTAINER_VERSION: $RELEASE_CANDIDATE_VERSION
rules:
- when: on_success
📍 Publish Version:
stage: release
rules:
- when: on_success
Utworzenie komponentu build
Plik szablonu:
templates/image-builder.yml
Skrypt budujący obraz:
scripts/image-builder.bash
Utworzenie komponentu publish
Analogicznie — publikacja gotowego obrazu:
scripts/image-builder.bash
Przygotowanie kontenera
Przygotowanie obrazu Buildah — image builderem
Przykładowy config.yml
:
---
base_image: ubuntu:noble
labels:
maintainer: "Maciej Rachuna <rachuna.maciej@gmail.com>"
description: Kontener z narzędziem Buildah, wykorzystywany w procesach budowania kontenerów w środowisku GitLab CI.
version: "1.0.0"
image_source: "https://gitlab.com/pl.rachuna-net/containers/buildah"
env:
DEBIAN_FRONTEND: noninteractive
TF_IN_AUTOMATION: "true"
LANG: C.UTF-8
before_build_commands: []
packages:
- bash
- buildah
- curl
- fuse-overlayfs
- git
- gzip
- gnupg2
- iproute2
- iputils-ping
- jq
- dnsutils
- libssl3
- lsb-release
- openssh-client
- ca-certificates
- gnupg
- slirp4netns
- uidmap
- sudo
- software-properties-common
- yq
- zip
custom_repos: []
extra_commands:
- chmod 777 /opt/scripts
- chmod 777 /opt/scripts/*
- buildah --version
copy:
- source: scripts/
destination: /opt/scripts/
user: []
entrypoint: "/opt/scripts/entrypoint.bash"
cmd: "/bin/bash"
Przygotowanie środowiska deweloperskiego

W tym wpisie pokazuję, jak przygotować własny obraz Ubuntu 24.10 dla Vagranta, opublikować go w rejestrze Vagrant Cloud (lub przez alternatywny hosting) oraz jak uruchomić środowisko deweloperskie przy pomocy vagrant up.
Cały proces ilustruje poniższy diagram:
--- config: theme: neo layout: dagre look: neo --- flowchart LR subgraph s1["Przygotowanie obrazu"] n5["Przygotowanie maszyny<br>wirtualnej na virtualbox"] n6@{ label: "<span style=\"padding-left:\">Utworzenie box<br></span><span style=\"padding-left:\">(vagrant package)</span>" } n7@{ label: "Wysłanie do<br style=\"--tw-scale-x:\">Vagrant box Registry" } end subgraph s2["Użycie obrazu (vagrant up)"] n8["vagrant up"] n9["run bootstrap.bash"] n11["bash scripts"] end n5 --> n6 n6 --> n7 s1 --> s2 n8 --> n9 s2 --> n10("Ready to use") n9 --> n11 n5@{ shape: rect} n6@{ shape: rect} n7@{ shape: rect} n9@{ shape: lean-r} n11@{ shape: procs} click n5 "#przygotowanie-maszyny-wirtualnej-na-virtualboxie" click n6 "#utworzenie-box" click n7 "#wys%c5%82anie-do-vagrant-box-registry" click n8 "#użycie-obrazu-vagrant-up" click n9 "#ręczne-uruchomienie-bootstrapbash"
Przygotowanie maszyny wirtualnej na virtualboxie
Przygotowałem maszynę wirtualną na virtualbox ubuntu 24-10
z użytkownikiem vagrant
hasłem vagrant
echo "vagrant ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/vagrant
sudo apt-get update
sudo apt-get dist-upgrade -y
sudo apt install -y openssh-server curl wget sudo
sudo apt install -y build-essential dkms linux-headers-$(uname -r)
mkdir -p /home/vagrant/.ssh
curl -fsSL https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant.pub -o /home/vagrant/.ssh/authorized_keys
chown -R vagrant:vagrant /home/vagrant/.ssh
chmod 700 /home/vagrant/.ssh
chmod 600 /home/vagrant/.ssh/authorized_keys
sudo apt-get autoremove -y
sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
sudo timedatectl set-timezone UTC
sudo locale-gen en_US.UTF-8
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
Utworzenie box
vagrant package --base ubuntu-24-10 --output ubuntu-24.10.box
m@nbo-001-mr ~ vagrant package --base ubuntu-24-10 --output ubuntu-24.10.box
==> ubuntu-24-10: Exporting VM...
==> ubuntu-24-10: Compressing package to: /home/maciej-rachuna/ubuntu-24.10.box
m@nbo-001-mr ~ ls -l |grep ubuntu-24
-rw-rw-r-- 1 m m 1871476745 lip 23 08:49 ubuntu-24.10.box
Wysłanie do Vagrant box Registry
U mnie z jakiegoś powodu opcja nie działa, więc wrzuciłem obraz przez UI
vagrant cloud auth login
Użycie obrazu (vagrant up)
Pobranie repozytorium z vagrantem
git clone https://gitlab.com/pl.rachuna-net/tools/vagrant.git
Uruchomienie maszyny developerskiej
chmod +x start_vm.bash
./start_vm.bash
bootstrap.bash
vagrant up automatycznie uruchomi bootstrap.bashm@nbo-001-mr /repo/pl.rachuna-net/tools/vagrant (main) vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'rachuna-net.pl/ubuntu-24-10' version '1.0.0' is up to date...
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.
==> default: Running provisioner: shell...
default: Running: /tmp/vagrant-shell20250723-96391-b06anr.bash
default: ===> 🚀 Run bootstrap script
default: ===> 📁 Copy userfiles to /root
default: ===> 🚀 Running script: /vagrant/provisioning/upgrade-ubuntu.bash
default: ===> Upgrade system packages and distribution
default: ===> 🚀 Running script: /vagrant/provisioning/install-packages.bash
default: ===> Install packages
default: ===> 🚀 Running script: /vagrant/provisioning/bootstrap-certs.bash
default: ===> Pobieranie CA certyfikatu dla rachuna-net.pl
default: ===> 🚀 Running script: /vagrant/provisioning/install-hashicorp.bash
default: ===> 🚀 Running script: /vagrant/provisioning/install-zsh.bash
default: ===> 🚀 Running script: /vagrant/provisioning/install-hugo.bash
Dostęp do maszyny wirtualnej
- SSH jest dostępne na porcie
2222
na hoście, przekierowanym do portu22
w VM. - Włączone jest przekazywanie agenta SSH oraz X11.
- Połączenie można nawiązać poleceniem:
ssh -p 2222 vagrant@localhost
Edytuj plik
~/.ssh/config
, dodając wpis:Host dev-station HostName 127.0.0.1 Port 2222 User vagrant IdentityFile /repo/pl.rachuna-net/tools/vagrant/.vagrant/machines/default/virtualbox/private_key ForwardX11 yes
Dzięki temu możesz łatwo łączyć się z maszyną wirtualną za pomocą polecenia:
ssh dev-station
Ręczne uruchomienie bootstrap.bash
vagrant@dev-station:/vagrant$ cd /vagrant/
vagrant@dev-station:/vagrant$ chmod +x bootstrap.bash
vagrant@dev-station:/vagrant$ ./bootstrap.bash
===> 🚀 Run bootstrap script
===> 📁 Copy userfiles to /home/vagrant
===> 🚀 Running script: /vagrant/provisioning/upgrade-ubuntu.bash
===> Upgrade system packages and distribution
===> 🚀 Running script: /vagrant/provisioning/install-packages.bash
===> Install packages
===> 🚀 Running script: /vagrant/provisioning/bootstrap-certs.bash
===> Pobieranie CA certyfikatu dla rachuna-net.pl
===> 🚀 Running script: /vagrant/provisioning/install-hashicorp.bash
===> 🚀 Running script: /vagrant/provisioning/install-zsh.bash
===> 🚀 Running script: /vagrant/provisioning/install-hugo.bash