<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>RACHUNA.DEV | Blog</title><description/><link>https://rachuna.dev/</link><language>en</language><item><title>Instalacja Gitlab Runner</title><link>https://rachuna.dev/blog/20260604/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260604/</guid><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.B4107m-5_Z2i599q.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1536&quot; height=&quot;433&quot;&gt;&lt;/p&gt;
&lt;p&gt;W tym wpisie pokażę krok po kroku, jak instaluję GitLab Runnera w praktycznym, produkcyjnym scenariuszu. Skupię się na sprawdzonym podejściu, które stosuję na co dzień — bez zbędnej teorii, za to z naciskiem na poprawną konfigurację, bezpieczeństwo i typowe pułapki, na które łatwo trafić przy pierwszym uruchomieniu runnera.&lt;/p&gt;
&lt;p&gt;Jeśli korzystasz z GitLaba do automatyzacji procesów CI/CD i chcesz mieć pełną kontrolę nad tym, gdzie i jak wykonywane są joby, ten materiał jest właśnie dla Ciebie.&lt;/p&gt;
&lt;aside aria-label=&quot;Note&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Note &lt;/p&gt; &lt;div&gt; &lt;p&gt;&lt;strong&gt;GitLab Runner&lt;/strong&gt; to lekki agent wykonawczy, który odpowiada za uruchamianie zadań CI/CD (jobów) zdefiniowanych w pliku .gitlab-ci.yml.&lt;/p&gt;&lt;p&gt;Mówiąc precyzyjnie:
GitLab Runner pobiera zadania z GitLaba, wykonuje je w określonym środowisku (np. Docker, maszyna wirtualna, system hosta), a następnie raportuje wynik wykonania z powrotem do GitLaba.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;

&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;krok-po-kroku&quot;&gt;Krok po kroku&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-maszyn-wirtualnych&quot;&gt;Utworzenie maszyn wirtualnych&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Definicja vm &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/pve-rachuna-dev/iac-proxmox/-/blob/main/machines/1002_gitlab_runner.tf.json?ref_type=heads&quot;&gt;gitlab-runner-1022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Definicja vm &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/pve-rachuna-dev/iac-proxmox/-/blob/main/machines/1003_gitlab_runner.tf.json?ref_type=heads&quot;&gt;gitlab-runner-1023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Definicja vm &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/pve-rachuna-dev/iac-proxmox/-/blob/main/machines/1004_gitlab_runner.tf.json?ref_type=heads&quot;&gt;gitlab-runner-1024&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-repozytoriów&quot;&gt;Utworzenie repozytoriów&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Definicja repozytorium &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/infrastructure/gitlab-com/ansible.tf.json&quot;&gt;dev.rachuna/infrastructure/gitlab-rachuna-net/ansible&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-projektu-ansible&quot;&gt;Utworzenie projektu ansible&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;ansible &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/ansible/-/releases/1.0.2&quot;&gt;1.0.2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Definicja hostów&lt;/strong&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  children&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    vault&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    gitlab_runners&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      children&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        nodes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          hosts&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            gitlab-runner-1002&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            gitlab-runner-1003&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            gitlab-runner-1004&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;host_vars/ct01002/gitlab-runner.yml&lt;/code&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;inv_gitlab_runner_configuration&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  concurrent&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  check_interval&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  shutdown_timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  session_timeout&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;3600&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  runners&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    - &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;{{ inventory_hostname }}.gitlab&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      url&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;https://gitlab.com&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      register_runner&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;53317509&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        token&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;{{ inv_secret_gitlab_runner_token }}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        register_gitlab_api_token&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;{{ ivn_secret_gitlab_api_token }}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;GitLab Runner for dev.rachuna&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        tag_list&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;&quot;rachuna-dev&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        runner_type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;group_type&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        group_id&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;132728705&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        access_level&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;not_protected&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      executor&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;docker&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      docker&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        tls_verify&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;registry.gitlab.com/dev.rachuna/artifacts/containers/python:1.0.0&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        privileged&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        disable_entrypoint_overwrite&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        oom_kill_disable&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        disable_cache&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        volumes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          - &lt;/span&gt;&lt;span&gt;&quot;/cache:/cache&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          - &lt;/span&gt;&lt;span&gt;&quot;/var/run/docker.sock:/var/run/docker.sock&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        shm_size&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        network_mode&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;host&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;napisanie-roli-ansible&quot;&gt;Napisanie roli ansible&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;gitlab-runner &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/ansible/-/releases/1.0.2&quot;&gt;1.0.2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;uruchomienie-procesu-cicd&quot;&gt;Uruchomienie procesu CI/CD&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/ci.CH0vwA7t_ZoRuq6.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;888&quot; height=&quot;449&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/runners.CT5xMjXg_Z1CnKw4.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1577&quot; height=&quot;407&quot;&gt;&lt;/p&gt;</content:encoded><category>ansible</category><category>gitlab</category></item><item><title>Image builder</title><link>https://rachuna.dev/blog/20260603/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260603/</guid><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.DMpRhusG_DNxNE.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;799&quot; height=&quot;193&quot;&gt;&lt;/p&gt;
&lt;p&gt;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 &lt;strong&gt;Buildah&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Dziś przedstawie wam, jak zbudowałem własny image builder, krok po kroku.&lt;/p&gt;
&lt;aside aria-label=&quot;Note&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Note &lt;/p&gt; &lt;div&gt; &lt;p&gt;&lt;strong&gt;Buildah&lt;/strong&gt; to narzędzie linuksowe służące do &lt;strong&gt;budowania obrazów kontenerowych (OCI/Docker)&lt;/strong&gt;, zaprojektowane jako &lt;strong&gt;lekka, skryptowalna alternatywa dla Dockera&lt;/strong&gt;, szczególnie w środowiskach serwerowych i CI/CD.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;p&gt;Buildah pozwala &lt;strong&gt;tworzyć obrazy kontenerów bez uruchamiania demona&lt;/strong&gt; i &lt;strong&gt;bez konieczności posiadania Dockera&lt;/strong&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;kluczowe-cechy&quot;&gt;Kluczowe cechy&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Brak demona&lt;/strong&gt;
Buildah działa jako zwykłe polecenie CLI – nie wymaga działającego serwisu w tle (jak &lt;code dir=&quot;auto&quot;&gt;dockerd&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rootless (bez uprawnień roota)&lt;/strong&gt;
Może budować obrazy jako zwykły użytkownik, co znacząco poprawia bezpieczeństwo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zgodność z OCI / Docker&lt;/strong&gt;
Tworzone obrazy są w pełni kompatybilne z Dockerem, Podmanem, Kubernetesem itd.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skryptowalność&lt;/strong&gt;
Buildah jest zaprojektowany jako zestaw niskopoziomowych poleceń (&lt;code dir=&quot;auto&quot;&gt;buildah from&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;buildah run&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;buildah commit&lt;/code&gt;), idealnych do automatyzacji w bashu lub CI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dockerfile – opcjonalnie&lt;/strong&gt;
Obsługuje Dockerfile (&lt;code dir=&quot;auto&quot;&gt;buildah bud&lt;/code&gt;), ale nie wymusza ich użycia.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;krok-po-kroku&quot;&gt;Krok po kroku&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-repozytoriów&quot;&gt;Utworzenie repozytoriów&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Definicja repozytorium &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/artifacts/containers/buildah.tf?ref_type=heads&quot;&gt;dev.rachuna/artifacts/containers/buildah&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-kontenera-mechanizmem-devcontainer-i-opublikowanie-w-gitlab&quot;&gt;Utworzenie kontenera mechanizmem .devcontainer i opublikowanie w gitlab&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Dokładny opis znajdziesz &lt;a href=&quot;https://rachuna.dev/blog/20260601&quot;&gt;w tym artykule&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dokerfile:&lt;/strong&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;span&gt; ubuntu:noble&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ENV&lt;/span&gt;&lt;span&gt; DEBIAN_FRONTEND=noninteractive&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ENV&lt;/span&gt;&lt;span&gt; STORAGE_DRIVER=vfs&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ENV&lt;/span&gt;&lt;span&gt; BUILDAH_ISOLATION=chroot&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;COPY&lt;/span&gt;&lt;span&gt; scripts/ /opt/scripts/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Install system dependencies and ansible&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RUN&lt;/span&gt;&lt;span&gt; apt-get update &amp;#x26;&amp;#x26; apt-get install -y \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        buildah \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        curl \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        fuse-overlayfs \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        gzip \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        slirp4netns \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        iproute2 \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        uidmap \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        iputils-ping \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        dnsutils \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ca-certificates \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        git \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        curl \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        gnupg \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        sudo \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        software-properties-common \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        tar \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        yq \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        zip \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; apt-get clean \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; rm -rf /var/lib/apt/lists/* \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; mkdir -p /tmp/buildah-root \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; mkdir -p /tmp/buildah-runroot \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    # Make scripts executable&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &amp;#x26;&amp;#x26; chmod +x /opt/scripts/*.bash&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ENTRYPOINT&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;/opt/scripts/entrypoint.bash&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;przygotowanie-procesu-ci&quot;&gt;Przygotowanie procesu CI&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Dokładny kod znajdziesz &lt;a href=&quot;https://gitlab.com/dev.rachuna/flows/gitlab/-/blob/main/pipelines/image-builder/README.md?ref_type=heads&quot;&gt;tutaj&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;napisanie-konfiguracji-dla-obrazu-buildah&quot;&gt;Napisanie konfiguracji dla obrazu buildah&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Wydanie wersji buildah &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/containers/buildah/-/releases/1.0.0&quot;&gt;1.0.0&lt;/a&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;base_image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ubuntu:noble&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  maintainer&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Maciej Rachuna &amp;#x3C;rachuna.maciej@gmail.com&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Kontener z narzędziem Buildah, wykorzystywany w procesach budowania kontenerów w środowisku GitLab CI.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  version&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  image_source&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;https://gitlab.com/dev.rachuna/containers/buildah&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  DEBIAN_FRONTEND&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;noninteractive&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  TF_IN_AUTOMATION&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;true&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  LANG&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;C.UTF-8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;before_build_commands&lt;/span&gt;&lt;span&gt;: []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;packages&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;bash&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;buildah&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;fuse-overlayfs&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;git&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;gzip&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;gnupg2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;iproute2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;iputils-ping&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;jq&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;dnsutils&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;libssl3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;lsb-release&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;openssh-client&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;ca-certificates&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;gnupg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;slirp4netns&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;uidmap&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;software-properties-common&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;yq&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;zip&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;custom_repos&lt;/span&gt;&lt;span&gt;: []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;extra_commands&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;buildah --version&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;copy&lt;/span&gt;&lt;span&gt;: []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;entrypoint&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cmd&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;skalowanie-dla-pozostałych-kontenerów&quot;&gt;Skalowanie dla pozostałych kontenerów&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Przykład:&lt;/strong&gt; Wydanie wersji opentofu &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/containers/opentofu/-/releases/1.0.0&quot;&gt;1.0.0&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded><category>buildah</category><category>container</category><category>gitlab-ci</category></item><item><title>Konfiguracja .gitconfig</title><link>https://rachuna.dev/blog/20260602/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260602/</guid><pubDate>Tue, 02 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.Cz6wOx3V_Z1QlHOp.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1774&quot; height=&quot;887&quot;&gt;&lt;/p&gt;
&lt;p&gt;Git ma opinię narzędzia prostego: pobierz zmiany, utwórz commit, wypchnij branch. Przy większej liczbie repozytoriów szybko okazuje się jednak, że kilka ustawień globalnych potrafi wyeliminować powtarzalne polecenia i ujednolicić codzienną pracę.&lt;/p&gt;
&lt;p&gt;Mój plik &lt;code dir=&quot;auto&quot;&gt;~/.gitconfig&lt;/code&gt; nie jest rozbudowany. Koncentruje się na czytelnej historii, przewidywalnym zachowaniu nowych branchy, współdzielonych hookach oraz kilku aliasach do operacji wykonywanych regularnie. W tym artykule przejdę przez jego najważniejsze sekcje i wyjaśnię, dlaczego są przydatne.&lt;/p&gt;

&lt;aside aria-label=&quot;Note&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Note &lt;/p&gt; &lt;div&gt; &lt;p&gt;Konfiguracja globalna działa dla wszystkich repozytoriów użytkownika. Ustawienia specyficzne dla pojedynczego projektu nadal można zapisać lokalnie poleceniem &lt;code dir=&quot;auto&quot;&gt;git config --local&lt;/code&gt;.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;tożsamość-autora-commitów&quot;&gt;Tożsamość autora commitów&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Pierwsza sekcja określa dane autora zapisywane w commitach:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[user]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    name&lt;/span&gt;&lt;span&gt; = Maciej Rachuna&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    email&lt;/span&gt;&lt;span&gt; = &amp;#x3C;adres-email&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Git umieszcza te wartości w metadanych każdego nowego commita. Nie jest to mechanizm uwierzytelniania do GitLaba ani GitHuba. Adres e-mail pozwala platformie powiązać commit z kontem użytkownika, ale dostęp do zdalnego repozytorium nadal wymaga osobnej autoryzacji.&lt;/p&gt;
&lt;p&gt;Adresu używanego lokalnie nie publikuję w przykładzie. W publicznym repozytorium można zastąpić go adresem &lt;code dir=&quot;auto&quot;&gt;noreply&lt;/code&gt;, jeżeli platforma hostingowa udostępnia taki wariant.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;czytelniejszy-log&quot;&gt;Czytelniejszy log&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Domyślne &lt;code dir=&quot;auto&quot;&gt;git log&lt;/code&gt; zawiera dużo informacji, ale przy szybkim przeglądaniu historii przydaje się krótszy format:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[pretty]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    slim&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;&quot;%C(red)%h%C(yellow)%d%C(reset) %s %C(green)(%cd) %C(bold blue)&amp;#x3C;%an&gt;%C(reset)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[alias]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    lg&lt;/span&gt;&lt;span&gt; = log --graph --abbrev-commit --decorate --&lt;/span&gt;&lt;span&gt;date&lt;/span&gt;&lt;span&gt;=relative --&lt;/span&gt;&lt;span&gt;pretty&lt;/span&gt;&lt;span&gt;=slim&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    lg1&lt;/span&gt;&lt;span&gt; = log --graph --abbrev-commit --decorate --&lt;/span&gt;&lt;span&gt;format&lt;/span&gt;&lt;span&gt;=format:&lt;/span&gt;&lt;span&gt;&apos;%C(bold blue)%h%C(reset) - %C(white)%s%C(reset) %C(dim white)(%cr) %C(green)&amp;#x3C;%an&gt;%C(reset)&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Format &lt;code dir=&quot;auto&quot;&gt;slim&lt;/code&gt; składa się z:&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Element&lt;/th&gt;&lt;th&gt;Znaczenie&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;%h&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Skrócony hash commita.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;%d&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Referencje wskazujące commit, na przykład branch lub tag.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;%s&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Temat commita.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;%cd&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Data commita.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;%an&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Autor commita.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Alias &lt;code dir=&quot;auto&quot;&gt;lg&lt;/code&gt; używa tego formatu razem z grafem branchy i względną datą, na przykład &lt;code dir=&quot;auto&quot;&gt;2 hours ago&lt;/code&gt;. &lt;code dir=&quot;auto&quot;&gt;lg1&lt;/code&gt; jest alternatywną wersją z formatem zapisanym bezpośrednio w aliasie.&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; lg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; lg1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Oba polecenia sprawdzają się lepiej niż surowe &lt;code dir=&quot;auto&quot;&gt;git log&lt;/code&gt;, gdy chcę szybko sprawdzić historię zmian i miejsca rozgałęzień.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;commity-i-praca-z-branchami&quot;&gt;Commity i praca z branchami&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Kolejne ustawienia określają domyślne zachowanie podstawowych operacji:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[commit]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    gpgSign&lt;/span&gt;&lt;span&gt; = false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[push]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    autoSetupRemote&lt;/span&gt;&lt;span&gt; = true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[pull]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    rebase&lt;/span&gt;&lt;span&gt; = false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[init]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    defaultBranch&lt;/span&gt;&lt;span&gt; = main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;commit.gpgSign = false&lt;/code&gt; wyłącza automatyczne podpisywanie commitów kluczem GPG. Commit nadal zawiera autora, ale nie otrzymuje kryptograficznego podpisu.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;push.autoSetupRemote = true&lt;/code&gt; upraszcza pierwsze wypchnięcie nowego brancha. Zamiast:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;span&gt; --set-upstream&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span&gt; feature/example&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;wystarczy:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Git sam ustawi upstream dla bieżącego brancha.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;pull.rebase = false&lt;/code&gt; oznacza, że &lt;code dir=&quot;auto&quot;&gt;git pull&lt;/code&gt; nie przepisuje lokalnej historii przez rebase. Jeżeli lokalny i zdalny branch się rozeszły, Git zachowuje model oparty na merge.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;init.defaultBranch = main&lt;/code&gt; ustawia nazwę pierwszego brancha w nowych repozytoriach tworzonych przez &lt;code dir=&quot;auto&quot;&gt;git init&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;szybka-poprawka-ostatniego-commita&quot;&gt;Szybka poprawka ostatniego commita&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Najbardziej automatyzujący alias w konfiguracji to:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[alias]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    amend&lt;/span&gt;&lt;span&gt; = !git add . &amp;#x26;&amp;#x26; git commit --amend --no-edit --&lt;/span&gt;&lt;span&gt;date&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;now&apos;&lt;/span&gt;&lt;span&gt; &amp;#x26;&amp;#x26; git push --force-with-lease&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Polecenie:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; amend&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;wykonuje kolejno trzy operacje:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Dodaje wszystkie zmiany z bieżącego katalogu do staging area.&lt;/li&gt;
&lt;li&gt;Nadpisuje ostatni commit bez zmiany jego opisu i aktualizuje datę.&lt;/li&gt;
&lt;li&gt;Wysyła poprawiony commit do zdalnego repozytorium.&lt;/li&gt;
&lt;/ol&gt;
&lt;aside aria-label=&quot;Caution&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Caution &lt;/p&gt; &lt;div&gt; &lt;p&gt;Alias zmienia historię brancha. Używa &lt;code dir=&quot;auto&quot;&gt;--force-with-lease&lt;/code&gt;, więc jest bezpieczniejszy od zwykłego &lt;code dir=&quot;auto&quot;&gt;--force&lt;/code&gt;: Git odmówi wysłania zmian, jeżeli zdalny branch został w międzyczasie zaktualizowany przez inną osobę. Nadal nie należy używać go bez namysłu na branchach współdzielonych.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;p&gt;Warto też pamiętać, że &lt;code dir=&quot;auto&quot;&gt;git add .&lt;/code&gt; bierze pod uwagę pliki od bieżącego katalogu w dół. Najbardziej przewidywalny efekt daje uruchomienie aliasu z głównego katalogu repozytorium.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;wspólne-ignore-i-hooki&quot;&gt;Wspólne ignore i hooki&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Repozytoria umieszczam pod &lt;code dir=&quot;auto&quot;&gt;/repo&lt;/code&gt;, dlatego globalna konfiguracja odwołuje się do współdzielonych plików z tego katalogu:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[core]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    excludesfile&lt;/span&gt;&lt;span&gt; = /repo/.gitignore_global&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    hooksPath&lt;/span&gt;&lt;span&gt; = /repo/git-hooks&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;core.excludesfile&lt;/code&gt; wskazuje globalny plik ignorowanych ścieżek. To dobre miejsce na pliki związane z lokalnym środowiskiem pracy, które nie powinny trafiać do &lt;code dir=&quot;auto&quot;&gt;.gitignore&lt;/code&gt; każdego projektu osobno.&lt;/p&gt;
&lt;p&gt;Przykładowe wpisy:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.envrc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.env&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.devcontainer&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.vscode&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;core.hooksPath&lt;/code&gt; przenosi źródło hooków Git z domyślnego &lt;code dir=&quot;auto&quot;&gt;.git/hooks&lt;/code&gt; do wspólnego katalogu &lt;code dir=&quot;auto&quot;&gt;/repo/git-hooks&lt;/code&gt;. Jeden zestaw skryptów może dzięki temu działać we wszystkich lokalnych repozytoriach.&lt;/p&gt;
&lt;aside aria-label=&quot;Caution&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Caution &lt;/p&gt; &lt;div&gt; &lt;p&gt;Globalny &lt;code dir=&quot;auto&quot;&gt;hooksPath&lt;/code&gt; wyłącza automatyczne użycie hooków zapisanych w &lt;code dir=&quot;auto&quot;&gt;.git/hooks&lt;/code&gt; konkretnego repozytorium. Wspólny katalog powinien więc obsługiwać wszystkie wymagane przypadki albo delegować wykonanie do hooków projektowych.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;zaufane-repozytoria-w-repo&quot;&gt;Zaufane repozytoria w &lt;code dir=&quot;auto&quot;&gt;/repo&lt;/code&gt;&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Git chroni przed wykonywaniem operacji w repozytoriach należących do innego użytkownika systemowego. W środowiskach kontenerowych właściciel plików widoczny wewnątrz kontenera może różnić się od właściciela procesu, dlatego pojawia się ustawienie:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[safe]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    directory&lt;/span&gt;&lt;span&gt; = /repo/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pozwala ono pracować z repozytoriami znajdującymi się bezpośrednio pod &lt;code dir=&quot;auto&quot;&gt;/repo&lt;/code&gt;. Jest to wygodne w Dev Containers, gdzie ten sam workspace jest montowany z hosta do kontenera.&lt;/p&gt;
&lt;aside aria-label=&quot;Caution&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Caution &lt;/p&gt; &lt;div&gt; &lt;p&gt;Listę zaufanych katalogów należy ograniczać do kontrolowanych lokalizacji. Dodanie wszystkich ścieżek jako bezpiecznych osłabia ochronę przed uruchomieniem konfiguracji z repozytorium należącego do innego użytkownika.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;pager-i-zewnętrzny-diff&quot;&gt;Pager i zewnętrzny diff&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Git domyślnie uruchamia pager, gdy wynik polecenia nie mieści się w terminalu. W mojej konfiguracji pager jest wyłączony dla najczęściej używanych komend:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[pager]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    branch&lt;/span&gt;&lt;span&gt; = false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    diff&lt;/span&gt;&lt;span&gt; = false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    log&lt;/span&gt;&lt;span&gt; = false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    show&lt;/span&gt;&lt;span&gt; = false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dzięki temu &lt;code dir=&quot;auto&quot;&gt;git branch&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;git diff&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;git log&lt;/code&gt; i &lt;code dir=&quot;auto&quot;&gt;git show&lt;/code&gt; wypisują wynik bezpośrednio do terminala. Jest to wygodne zwłaszcza przy pracy w zintegrowanym terminalu VS Code oraz przy filtrowaniu wyników innymi narzędziami.&lt;/p&gt;
&lt;p&gt;Konfiguracja zawiera również aliasy przeznaczone do uruchomienia zewnętrznego narzędzia &lt;code dir=&quot;auto&quot;&gt;difft&lt;/code&gt;:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[alias]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    dlog&lt;/span&gt;&lt;span&gt; = !git -c &lt;/span&gt;&lt;span&gt;diff.external&lt;/span&gt;&lt;span&gt;=difft log --ext-diff&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    dshow&lt;/span&gt;&lt;span&gt; = !git -c &lt;/span&gt;&lt;span&gt;diff.external&lt;/span&gt;&lt;span&gt;=difft show --ext-diff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; dlog&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; dshow&lt;/span&gt;&lt;span&gt; HEAD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;aside aria-label=&quot;Note&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Note &lt;/p&gt; &lt;div&gt; &lt;p&gt;W lokalnym pliku klucz zapisany jest jako &lt;code dir=&quot;auto&quot;&gt;diff.externall&lt;/code&gt; z dodatkową literą &lt;code dir=&quot;auto&quot;&gt;l&lt;/code&gt;. Poprawna nazwa ustawienia Git to &lt;code dir=&quot;auto&quot;&gt;diff.external&lt;/code&gt;. W przykładzie pokazuję poprawiony wariant, aby aliasy rzeczywiście korzystały z &lt;code dir=&quot;auto&quot;&gt;difft&lt;/code&gt;.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;</content:encoded><category>vscode</category><category>devcontainers</category><category>docker</category><category>opentofu</category></item><item><title>Dev Containers w VS Code - jedno środowisko dla wielu projektów</title><link>https://rachuna.dev/blog/20260601/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260601/</guid><pubDate>Mon, 01 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.BqDI2arW_Z20NYD8.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1000&quot; height=&quot;194&quot;&gt;&lt;/p&gt;
&lt;p&gt;Pracując nad wieloma projektami infrastrukturalnymi szybko trafiamy na ten sam problem: każdy z nich wymaga odpowiedniej wersji narzędzi, rozszerzeń edytora i konfiguracji środowiska. OpenTofu, Ansible, Vault, Go, Python, &lt;code dir=&quot;auto&quot;&gt;direnv&lt;/code&gt;, certyfikaty, pluginy VS Code - lista rośnie, a ręczne przygotowanie kolejnego laptopa lub maszyny wirtualnej zabiera czas.&lt;/p&gt;
&lt;p&gt;Rozwiązaniem są &lt;strong&gt;Dev Containers&lt;/strong&gt;: kontenery developerskie uruchamiane bezpośrednio z Visual Studio Code. Repozytorium &lt;a href=&quot;https://gitlab.com/dev.rachuna/devtools/devcontainers&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainers&lt;/code&gt;&lt;/a&gt; zbiera gotowe profile środowisk oraz helpery, które pozwalają podpinać je do kolejnych projektów.&lt;/p&gt;

&lt;aside aria-label=&quot;Note&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Note &lt;/p&gt; &lt;div&gt; &lt;p&gt;Dev Container nie jest kontenerem aplikacji ani środowiskiem produkcyjnym. To powtarzalny warsztat pracy: VS Code otwiera projekt wewnątrz kontenera, a terminal, rozszerzenia i narzędzia CLI działają w przygotowanym środowisku.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;do-czego-służy-dev-containers-w-vs-code&quot;&gt;Do czego służy Dev Containers w VS Code?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Rozszerzenie &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers&quot;&gt;Dev Containers&lt;/a&gt; pozwala uruchomić środowisko developerskie zdefiniowane w pliku &lt;code dir=&quot;auto&quot;&gt;.devcontainer/devcontainer.json&lt;/code&gt;. VS Code nadal działa na hoście, ale serwer edytora, terminal i komendy projektu uruchamiane są już w kontenerze.&lt;/p&gt;
&lt;p&gt;Dzięki temu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wersje narzędzi są zapisane w kodzie zamiast w pamięci autora projektu,&lt;/li&gt;
&lt;li&gt;nowy projekt można otworzyć bez instalowania całego toolchainu na hoście,&lt;/li&gt;
&lt;li&gt;rozszerzenia VS Code są dobierane do rodzaju pracy,&lt;/li&gt;
&lt;li&gt;kilka projektów może używać różnych środowisk bez konfliktów,&lt;/li&gt;
&lt;li&gt;aktualizację wspólnych narzędzi można wykonać w jednym miejscu.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pod spodem nadal działa Docker. Dev Containers dodaje warstwę integracji z VS Code: buduje obraz, uruchamia kontener, montuje workspace i otwiera projekt w ścieżce wskazanej przez konfigurację.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;jak-zbudowane-jest-repozytorium&quot;&gt;Jak zbudowane jest repozytorium?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Repozytorium rozdziela konfigurację na profile, wspólne skrypty i proste helpery:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;devcontainers/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── bin/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── devcontainer-link&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── devcontainer-render&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   └── devcontainer-update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── common/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── Dockerfile.base&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── scripts/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   └── snippets/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── profiles/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── ansible/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── base/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── golang/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── opentofu/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── python/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   └── vault/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;└── templates/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    └── project-devcontainer/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Każdy profil zawiera dwa podstawowe pliki:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;profiles/&amp;#x3C;profile&gt;/devcontainer.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;profiles/&amp;#x3C;profile&gt;/Dockerfile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainer.json&lt;/code&gt; opisuje sposób uruchomienia środowiska przez VS Code: obraz, workspace, mounty, użytkownika oraz rozszerzenia edytora. &lt;code dir=&quot;auto&quot;&gt;Dockerfile&lt;/code&gt; buduje środowisko i instaluje potrzebne narzędzia. Powtarzalne kroki zostały przeniesione do &lt;code dir=&quot;auto&quot;&gt;common/scripts/&lt;/code&gt;, dzięki czemu nie trzeba kopiować tych samych instrukcji do każdego profilu.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;dostępne-profile&quot;&gt;Dostępne profile&lt;/h3&gt;&lt;/div&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Profil&lt;/th&gt;&lt;th&gt;Przeznaczenie&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;base&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Bazowe środowisko developerskie z shellem, Gitem, &lt;code dir=&quot;auto&quot;&gt;direnv&lt;/code&gt;, Node.js i Codex CLI.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;opentofu&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Praca z OpenTofu oraz narzędziami dla kodu infrastruktury.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;ansible&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Środowisko dla projektów automatyzowanych przez Ansible.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;vault&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Praca z HashiCorp Vault CLI.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;golang&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Toolchain dla projektów Go.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;python&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Środowisko dla projektów Python, rozszerzone między innymi o &lt;code dir=&quot;auto&quot;&gt;conftest&lt;/code&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;pierwsze-uruchomienie&quot;&gt;Pierwsze uruchomienie&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Przed rozpoczęciem pracy potrzebne są:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker,&lt;/li&gt;
&lt;li&gt;Visual Studio Code,&lt;/li&gt;
&lt;li&gt;rozszerzenie &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers&quot;&gt;Dev Containers&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;lokalna kopia repozytorium &lt;code dir=&quot;auto&quot;&gt;devcontainers&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Najprostszy wariant to podpięcie profilu jako symlink. Helper &lt;code dir=&quot;auto&quot;&gt;devcontainer-link&lt;/code&gt; tworzy w projekcie dowiązanie &lt;code dir=&quot;auto&quot;&gt;.devcontainer&lt;/code&gt; do wybranego profilu.&lt;/p&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;przejdź-do-repozytorium-projektu&quot;&gt;Przejdź do repozytorium projektu&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /repo/dev.rachuna/artifacts/opentofu/gitlab-group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;podepnij-profil&quot;&gt;Podepnij profil&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/repo/dev.rachuna/devtools/devcontainers/bin/devcontainer-link&lt;/span&gt;&lt;span&gt; opentofu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Efekt odpowiada ręcznemu utworzeniu dowiązania:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ln&lt;/span&gt;&lt;span&gt; -s&lt;/span&gt;&lt;span&gt; /repo/dev.rachuna/devtools/devcontainers/profiles/opentofu&lt;/span&gt;&lt;span&gt; .devcontainer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;otwórz-projekt-w-kontenerze&quot;&gt;Otwórz projekt w kontenerze&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;W VS Code uruchom polecenie:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Dev Containers: Reopen in Container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;poczekaj-na-zbudowanie-obrazu&quot;&gt;Poczekaj na zbudowanie obrazu&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;VS Code zbuduje obraz i ponownie otworzy projekt. Dla profilu &lt;code dir=&quot;auto&quot;&gt;opentofu&lt;/code&gt; wykona także kontrolne polecenie:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Od tej chwili terminal otwierany w VS Code działa wewnątrz kontenera.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;dlaczego-ścieżka-projektu-się-nie-zmienia&quot;&gt;Dlaczego ścieżka projektu się nie zmienia?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Domyślnie Dev Containers montuje kod w katalogu podobnym do &lt;code dir=&quot;auto&quot;&gt;/workspaces/nazwa-projektu&lt;/code&gt;. W projektach infrastrukturalnych wygodniej jest zachować tę samą ścieżkę na hoście i w kontenerze, szczególnie gdy skrypty odwołują się do innych repozytoriów.&lt;/p&gt;
&lt;p&gt;Profile takie jak &lt;code dir=&quot;auto&quot;&gt;opentofu&lt;/code&gt; konfigurują więc:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;workspaceMount&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind,consistency=cached&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;workspaceFolder&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;${localWorkspaceFolder}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Jeśli projekt na hoście znajduje się tutaj:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/repo/dev.rachuna/artifacts/opentofu/gitlab-group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to po otwarciu kontenera nadal pracujemy w:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/repo/dev.rachuna/artifacts/opentofu/gitlab-group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nie trzeba zmieniać ścieżek w skryptach ani zastanawiać się, czy polecenie zostało uruchomione na hoście, czy już w kontenerze.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;dwa-sposoby-podpinania-profilu&quot;&gt;Dwa sposoby podpinania profilu&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Repozytorium obsługuje dwa warianty pracy. Wybór zależy od tego, czy projekt ma korzystać z centralnie utrzymywanego profilu, czy przechowywać własną kopię konfiguracji.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;wariant-1-symlink-do-profilu&quot;&gt;Wariant 1: symlink do profilu&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/repo/dev.rachuna/devtools/devcontainers/bin/devcontainer-link&lt;/span&gt;&lt;span&gt; opentofu&lt;/span&gt;&lt;span&gt; /repo/dev.rachuna/artifacts/opentofu/gitlab-group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To najwygodniejsze rozwiązanie dla lokalnych projektów utrzymywanych na tej samej maszynie. Projekt zawsze korzysta z aktualnego profilu z repozytorium &lt;code dir=&quot;auto&quot;&gt;devcontainers&lt;/code&gt;. Po zmianie Dockerfile wystarczy w VS Code wykonać:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Dev Containers: Rebuild Container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Symlink ma jednak jedną ważną konsekwencję: projekt zależy od lokalnej ścieżki repozytorium &lt;code dir=&quot;auto&quot;&gt;devcontainers&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;wariant-2-renderowanie-konfiguracji-do-projektu&quot;&gt;Wariant 2: renderowanie konfiguracji do projektu&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Jeżeli projekt powinien zawierać własną, samowystarczalną kopię &lt;code dir=&quot;auto&quot;&gt;.devcontainer&lt;/code&gt;, można ją wygenerować:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/repo/dev.rachuna/devtools/devcontainers/bin/devcontainer-render&lt;/span&gt;&lt;span&gt; opentofu&lt;/span&gt;&lt;span&gt; /repo/dev.rachuna/artifacts/opentofu/gitlab-group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Helper zapisze:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.devcontainer/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── .profile&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── Dockerfile&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── devcontainer.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;└── common/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    └── scripts/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Renderowana konfiguracja ma lokalny build context i własną kopię wspólnych skryptów. Można ją przechowywać razem z projektem, udostępniać innym osobom oraz modyfikować niezależnie od centralnego repozytorium.&lt;/p&gt;
&lt;p&gt;Aby później odświeżyć wygenerowany wariant, wystarczy uruchomić:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/repo/dev.rachuna/devtools/devcontainers/bin/devcontainer-update&lt;/span&gt;&lt;span&gt; /repo/dev.rachuna/artifacts/opentofu/gitlab-group&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Polecenie odczyta nazwę profilu z &lt;code dir=&quot;auto&quot;&gt;.devcontainer/.profile&lt;/code&gt; i ponownie wykona render.&lt;/p&gt;
&lt;aside aria-label=&quot;Caution&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Caution &lt;/p&gt; &lt;div&gt; &lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainer-update&lt;/code&gt; nadpisuje wygenerowane pliki. Jeśli projekt ma własne zmiany w &lt;code dir=&quot;auto&quot;&gt;.devcontainer&lt;/code&gt;, warto utrzymywać je jako osobny profil albo świadomie przenosić po aktualizacji.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;co-znajduje-się-w-profilu&quot;&gt;Co znajduje się w profilu?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Spójrzmy na najważniejsze fragmenty konfiguracji &lt;code dir=&quot;auto&quot;&gt;opentofu&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;build-obrazu&quot;&gt;Build obrazu&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;build&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;dockerfile&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Dockerfile&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;context&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;/repo/dev.rachuna/devtools/devcontainers&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;args&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;USERNAME&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;mrachuna&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kontekst budowania wskazuje repozytorium &lt;code dir=&quot;auto&quot;&gt;devcontainers&lt;/code&gt;, ponieważ Dockerfile korzysta ze wspólnych skryptów:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;COPY&lt;/span&gt;&lt;span&gt; common/scripts/ /tmp/devcontainer-scripts/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;integracja-użytkownika-i-repozytoriów&quot;&gt;Integracja użytkownika i repozytoriów&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;remoteUser&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;mrachuna&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;mounts&quot;&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;source=${localEnv:HOME},target=/home/mrachuna,type=bind,consistency=cached&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;source=/repo,target=/repo,type=bind,consistency=cached&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;containerEnv&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;HOME&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;/home/mrachuna&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kontener używa tego samego katalogu domowego i widzi drzewo &lt;code dir=&quot;auto&quot;&gt;/repo&lt;/code&gt;. Dzięki temu wewnątrz kontenera dostępne są między innymi konfiguracja shella, Git, SSH oraz sąsiednie projekty.&lt;/p&gt;
&lt;aside aria-label=&quot;Danger&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Danger &lt;/p&gt; &lt;div&gt; &lt;p&gt;Montowanie katalogu domowego udostępnia kontenerowi prywatne pliki użytkownika, w tym potencjalnie klucze SSH i tokeny. Używaj wyłącznie zaufanych obrazów i Dockerfile. Dla współdzielonych lub mniej zaufanych projektów ogranicz mounty do konkretnych plików, na przykład &lt;code dir=&quot;auto&quot;&gt;.gitconfig&lt;/code&gt; i &lt;code dir=&quot;auto&quot;&gt;.ssh&lt;/code&gt;.&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;div&gt;&lt;h3 id=&quot;rozszerzenia-vs-code&quot;&gt;Rozszerzenia VS Code&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Profil może automatycznie doinstalować rozszerzenia właściwe dla danego rodzaju projektu:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;customizations&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;vscode&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;extensions&quot;&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;editorconfig.editorconfig&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;redhat.vscode-yaml&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;gamunu.opentofu&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;ms-azuretools.vscode-docker&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;timonwong.shellcheck&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Po otwarciu projektu dostajemy więc nie tylko CLI, lecz także gotowy edytor.&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;jak-rozwijać-repozytorium&quot;&gt;Jak rozwijać repozytorium?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Rozwój repozytorium polega najczęściej na aktualizacji wspólnego skryptu, zmianie istniejącego profilu albo dodaniu kolejnego profilu.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;zmiana-wspólnego-narzędzia&quot;&gt;Zmiana wspólnego narzędzia&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Jeżeli narzędzie ma znaleźć się w kilku środowiskach, dodaj lub zmodyfikuj skrypt w:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;common/scripts/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Następnie wywołaj go w Dockerfile odpowiednich profili. Przykładowo instalacja &lt;code dir=&quot;auto&quot;&gt;direnv&lt;/code&gt; jest współdzielona przez wiele obrazów:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;RUN&lt;/span&gt;&lt;span&gt; bash /tmp/devcontainer-scripts/install-direnv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;aktualizacja-istniejącego-profilu&quot;&gt;Aktualizacja istniejącego profilu&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Każdy profil rozwijamy w jego katalogu:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;profiles/opentofu/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── Dockerfile&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;└── devcontainer.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zmiana w &lt;code dir=&quot;auto&quot;&gt;Dockerfile&lt;/code&gt; wpływa na zawartość obrazu. Zmiana w &lt;code dir=&quot;auto&quot;&gt;devcontainer.json&lt;/code&gt; wpływa na sposób uruchamiania kontenera przez VS Code: mounty, rozszerzenia, użytkownika, workspace i komendy startowe.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;dodanie-nowego-profilu&quot;&gt;Dodanie nowego profilu&lt;/h3&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utwórz-katalog-profilu&quot;&gt;Utwórz katalog profilu&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; profiles/&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;nazwa-profil&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;dodaj-dockerfile&quot;&gt;Dodaj Dockerfile&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Wybierz możliwie prosty obraz bazowy i wykorzystaj skrypty z &lt;code dir=&quot;auto&quot;&gt;common/scripts/&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;dodaj-devcontainerjson&quot;&gt;Dodaj &lt;code dir=&quot;auto&quot;&gt;devcontainer.json&lt;/code&gt;&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Skonfiguruj &lt;code dir=&quot;auto&quot;&gt;build&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;remoteUser&lt;/code&gt;, mounty, workspace oraz rozszerzenia VS Code dopasowane do technologii.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;sprawdź-profil-lokalnie&quot;&gt;Sprawdź profil lokalnie&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Podepnij go do testowego projektu:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;bin/devcontainer-link&lt;/span&gt;&lt;span&gt; &amp;#x3C;&lt;/span&gt;&lt;span&gt;nazwa-profil&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; /tmp/devcontainer-profile-test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Następnie otwórz katalog w VS Code i wykonaj:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Dev Containers: Rebuild and Reopen in Container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;walidacja-zmian&quot;&gt;Walidacja zmian&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Przed wysłaniem zmian warto wykonać podstawowe testy statyczne:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;jq&lt;/span&gt;&lt;span&gt; empty&lt;/span&gt;&lt;span&gt; profiles/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;/devcontainer.json&lt;/span&gt;&lt;span&gt; common/snippets/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;bash&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; bin/devcontainer-render&lt;/span&gt;&lt;span&gt; bin/devcontainer-link&lt;/span&gt;&lt;span&gt; bin/devcontainer-update&lt;/span&gt;&lt;span&gt; common/scripts/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Można również sprawdzić renderowanie na katalogu tymczasowym:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; /tmp/devcontainer-render-test&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;bin/devcontainer-render&lt;/span&gt;&lt;span&gt; opentofu&lt;/span&gt;&lt;span&gt; /tmp/devcontainer-render-test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na końcu pozostaje test praktyczny: przebudowanie kontenera w VS Code oraz uruchomienie podstawowego polecenia dla danego profilu, na przykład:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;kiedy-używać-którego-wariantu&quot;&gt;Kiedy używać którego wariantu?&lt;/h2&gt;&lt;/div&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Potrzeba&lt;/th&gt;&lt;th&gt;Najlepszy wybór&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Kilka własnych projektów na jednej maszynie&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainer-link&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Centralna aktualizacja środowiska bez kopiowania plików&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainer-link&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Konfiguracja wersjonowana razem z projektem&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainer-render&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Udostępnienie środowiska innym osobom&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;devcontainer-render&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Niezależne dostosowanie &lt;code dir=&quot;auto&quot;&gt;.devcontainer&lt;/code&gt; w konkretnym projekcie&lt;/td&gt;&lt;td&gt;lokalna kopia po &lt;code dir=&quot;auto&quot;&gt;devcontainer-render&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Dev Containers dobrze rozwiązuje problem powtarzalnego warsztatu pracy. Zamiast dokumentować kolejną listę pakietów do ręcznej instalacji, utrzymujemy wykonywalną definicję środowiska. VS Code staje się wejściem do projektu, Docker zapewnia izolację, a wspólne profile pozwalają rozwijać narzędzia w jednym miejscu.&lt;/p&gt;</content:encoded><category>vscode</category><category>devcontainers</category><category>docker</category><category>opentofu</category></item><item><title>Nadpisanie teraform states</title><link>https://rachuna.dev/blog/20260529/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260529/</guid><pubDate>Fri, 29 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.C0EgS58b_Z1CNN2i.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;993&quot; height=&quot;209&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Terraform GitLab States&lt;/strong&gt; pozwala na zarządzanie i synchronizację stanu infrastruktury bezpośrednio w ramach projektu GitLab. Dzięki temu możliwe jest centralne przechowywanie i kontrola stanu, co ułatwia współpracę zespołową oraz automatyzację procesów CI/CD. W niniejszym dokumencie przedstawiono sposób wysyłania zmian do istniejącego stanu OpenTofu do GitLab za pomocą API.&lt;/p&gt;

&lt;hr&gt;
&lt;div&gt;&lt;h3 id=&quot;popsułem-terraform-state-ale-mam-backup&quot;&gt;Popsułem terraform state, ale mam backup :)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Mając lokalnie plik tfstate można w bardzo szybki sposób go nadpisać, wystarczy wykonać to polecenie&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; PROJECT_ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;1234569&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; TF_STATE_NAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;production&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; --request&lt;/span&gt;&lt;span&gt; POST&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     --header&lt;/span&gt;&lt;span&gt; &quot;PRIVATE-TOKEN: &lt;/span&gt;&lt;span&gt;$GITLAB_TOKEN&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     --header&lt;/span&gt;&lt;span&gt; &quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     --data-binary&lt;/span&gt;&lt;span&gt; &quot;@tfstate.json&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     &quot;https://gitlab.com/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded><category>opentofu</category></item><item><title>Integracja z projektem gitlab</title><link>https://rachuna.dev/blog/20260528/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260528/</guid><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.C0EgS58b_Z1CNN2i.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;993&quot; height=&quot;209&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/state&quot;&gt;&lt;strong&gt;Terraform State&lt;/strong&gt;&lt;/a&gt; to mechanizm w Terraformie, który przechowuje aktualny stan zarządzanej infrastruktury. Jest to plik (domyślnie &lt;code dir=&quot;auto&quot;&gt;terraform.tfstate&lt;/code&gt;), w którym Terraform zapisuje informacje o zasobach, ich konfiguracji oraz zależnościach. Dzięki temu Terraform może:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Śledzić zmiany&lt;/strong&gt; – porównuje aktualną infrastrukturę ze skonfigurowaną w kodzie, identyfikując różnice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optymalizować działania&lt;/strong&gt; – wie, które zasoby wymagają zmiany, zamiast tworzyć je od nowa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zarządzać zależnościami&lt;/strong&gt; – rozumie, w jakiej kolejności tworzyć, aktualizować lub usuwać zasoby.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Współdzielić stan&lt;/strong&gt; – umożliwia pracę zespołową poprzez zdalne przechowywanie stanu w backendach takich jak S3, GitLab czy Terraform Cloud.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Zarządzanie stanem jest kluczowe, dlatego warto używać &lt;strong&gt;zdalnego backendu&lt;/strong&gt; zamiast przechowywać &lt;code dir=&quot;auto&quot;&gt;terraform.tfstate&lt;/code&gt; lokalnie, szczególnie w środowiskach zespołowych.&lt;/p&gt;

&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;ustawienie-terraform-state-w-ustawieniach-repozytorium&quot;&gt;Ustawienie terraform state w ustawieniach repozytorium&lt;/h2&gt;&lt;/div&gt;
&lt;aside aria-label=&quot;Danger&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Danger &lt;/p&gt; &lt;div&gt; &lt;p&gt;Nigdy umieszczaj terraform state w &lt;strong&gt;bezpośrednio&lt;/strong&gt; w repozytorium kodu&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; VAULT_ADDR&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;https://vault.local&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; VAULT_TOKEN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;hvs.QWERTY&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; CI_SERVER_URL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;https://gitlab.com/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; CI_USERNAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;techuser&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; GITLAB_TOKEN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;qwerty&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;123456789&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; TF_STATE_NAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;production&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;terraform&lt;/span&gt;&lt;span&gt; init&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;address=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_SERVER_URL&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;lock_address=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_SERVER_URL&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/lock&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;unlock_address=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_SERVER_URL&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/lock&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;username=gitlab-ci-token&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;password=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;GITLAB_TOKEN&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;lock_method=POST&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;unlock_method=DELETE&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -backend-config=&lt;/span&gt;&lt;span&gt;&quot;retry_wait_min=5&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;dla OpenTofu&lt;/strong&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; VAULT_ADDR&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;https://vault.local&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; VAULT_TOKEN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;hvs.QWERTY&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; CI_SERVER_URL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;https://gitlab.com/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; CI_USERNAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;techuser&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; GITLAB_TOKEN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;qwerty&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;123456789&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; TF_STATE_NAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;production&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; init&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;address=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_SERVER_URL&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;lock_address=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_SERVER_URL&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/lock&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;unlock_address=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_SERVER_URL&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/api/v4/projects/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;CI_PROJECT_ID&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/terraform/state/&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;TF_STATE_NAME&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;/lock&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;username=gitlab-ci-token&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;password=&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;GITLAB_TOKEN&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;lock_method=POST&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;unlock_method=DELETE&quot;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -backend-config=&lt;/span&gt;&lt;span&gt;&quot;retry_wait_min=5&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;gdzie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CI_PROJECT_ID - id projektu w gitlab&lt;/li&gt;
&lt;li&gt;CI_SERVER_URL - serwer URL&lt;/li&gt;
&lt;li&gt;TF_STATE_NAME - nazwa instancji state&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;terraform-state-z-procesu-ci&quot;&gt;Terraform state z procesu CI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/terraform_state.WZEt-9td_Z3Etm9.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1433&quot; height=&quot;357&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Dokumentacja: &lt;a href=&quot;https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html&quot;&gt;https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html&lt;/a&gt;&lt;/p&gt;</content:encoded><category>opentofu</category></item><item><title>Importowanie obiektów do tfstate</title><link>https://rachuna.dev/blog/20260527/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260527/</guid><pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.C0EgS58b_Z1CNN2i.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;993&quot; height=&quot;209&quot;&gt;&lt;/p&gt;
&lt;p&gt;W poprzednich artykułach użyłem tofu import, ale nie wyjaśniłem dokładnie co robi to polecenie. Dziś się bardziej niemu przyjrzymy.&lt;/p&gt;

&lt;div&gt;&lt;h2 id=&quot;tofu-import--co-to-jest-i-do-czego-służy&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;tofu Import&lt;/code&gt; – Co to jest i do czego służy?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;tofu import&lt;/code&gt;&lt;/strong&gt; to polecenie w OpenTofu, które umożliwia &lt;strong&gt;wprowadzenie istniejących zasobów&lt;/strong&gt; do stanu (&lt;code dir=&quot;auto&quot;&gt;state&lt;/code&gt;) OpenTofu, bez konieczności ich tworzenia od zera. Jest to przydatne, gdy mamy zasoby zarządzane ręcznie lub przez inne narzędzia i chcemy przejąć nad nimi kontrolę za pomocą OpenTofu.&lt;/p&gt;
&lt;p&gt;Do czego służy OpenTofu import?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Przejmowanie kontroli nad istniejącymi zasobami&lt;/strong&gt; – jeśli masz już zasoby w chmurze (np. VM w AWS, projekt w GitLab, użytkowników w Azure), możesz je zaimportować do OpenTofu bez ich ponownego tworzenia.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unikanie usuwania i ponownego tworzenia zasobów&lt;/strong&gt; – jeśli ręcznie utworzony zasób nie znajduje się w stanie OpenTofu, ale istnieje, można go dodać do &lt;code dir=&quot;auto&quot;&gt;state&lt;/code&gt;, zamiast niszczyć i tworzyć od nowa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Migracja do OpenTofu&lt;/strong&gt; – jeśli zarządzałeś zasobami ręcznie lub przy pomocy innego narzędzia (np. Ansible, CloudFormation), możesz je przenieść do OpenTofu.&lt;/li&gt;
&lt;/ul&gt;
&lt;aside aria-label=&quot;Caution&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Caution &lt;/p&gt; &lt;div&gt; &lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nie importuje konfiguracji (&lt;code dir=&quot;auto&quot;&gt;.tf&lt;/code&gt;)&lt;/strong&gt; – dodaje zasoby tylko do &lt;code dir=&quot;auto&quot;&gt;state&lt;/code&gt;, nie generuje kodu. Konfigurację trzeba dodać ręcznie.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Brak wsparcia dla całych modułów&lt;/strong&gt; – &lt;code dir=&quot;auto&quot;&gt;tofu import&lt;/code&gt; działa na poziomie pojedynczych zasobów, a nie całych modułów.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Niektóre zasoby nie są wspierane&lt;/strong&gt; – nie wszystkie dostawcy (&lt;code dir=&quot;auto&quot;&gt;providers&lt;/code&gt;) umożliwiają import wszystkich typów zasobów.&lt;/li&gt;
&lt;/ul&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;przykłady-importowanie-obiektów&quot;&gt;Przykłady importowanie obiektów&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;importowanie-grupy-gitlab&quot;&gt;importowanie grupy gitlab&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  to&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dev-rachuna&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;infrastructure&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opentofu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;group_modules&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gitlab_group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  id&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &quot;100726684&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;albo&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.dev-rachuna.module.infrastructure.module.opentofu.module.group_modules.gitlab_group.group&lt;/span&gt;&lt;span&gt; 100726684&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;importowanie-projektu-gitlab&quot;&gt;importowanie projektu gitlab&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    to&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dev-rachuna&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;infrastructure&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;opentofu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;modules&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gitlab_group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gitlab_project&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;project&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    id&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &quot;66189322&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;albo&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.dev-rachuna.module.infrastructure.module.opentofu.module.modules.module.gitlab_group.gitlab_project.project&lt;/span&gt;&lt;span&gt; 66189322&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded><category>opentofu</category></item><item><title>Zarządzanie projektami w gitlab</title><link>https://rachuna.dev/blog/20260526/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260526/</guid><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.CdVOJLD3_Z2qWVGO.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1099&quot; height=&quot;331&quot;&gt;&lt;/p&gt;
&lt;p&gt;W poprzednim &lt;a href=&quot;https://rachuna.dev/blog/20260525/&quot;&gt;poście&lt;/a&gt; opisałem jak zarządzać grupami za pomocą opentofu. Dziś opowiem jak to robić z projektami.&lt;/p&gt;

&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Wymagania&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zainstalowany opentofu&lt;/li&gt;
&lt;li&gt;repozytorium &lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab&quot;&gt;iac-gitlab&lt;/a&gt;&lt;/strong&gt; z zestawem definicji, który pozwala w deklaratywny sposób tworzyć i utrzymywać grupy oraz projekty w GitLabie.&lt;/li&gt;
&lt;li&gt;Dwa moduły:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-group&quot;&gt;gitlab-group&lt;/a&gt;&lt;/strong&gt; - moduł opentofu do zarządzania grupami&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-project&quot;&gt;gitlab-project&lt;/a&gt;&lt;/strong&gt; - moduł opentofu do zarządzania projektami&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;krop-po-kroku&quot;&gt;Krop po kroku&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;przygotowanie-devcontainer&quot;&gt;Przygotowanie devcontainer&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/devtools/devcontainers/-/tree/main/profiles/opentofu?ref_type=heads&quot;&gt;profiles/opentofu&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;napisanie-logiki-dla-modułu-gitlab-project&quot;&gt;Napisanie logiki dla modułu &lt;code dir=&quot;auto&quot;&gt;gitlab-project&lt;/code&gt;&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Wydanie wersji &lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-project/-/releases/1.0.0&quot;&gt;1.0.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-definicji-w-iac-gitlab-com-dla-grup&quot;&gt;Utworzenie definicji w &lt;code dir=&quot;auto&quot;&gt;iac-gitlab-com&lt;/code&gt; dla grup&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Definicja repozytorium &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/artifacts/opentofu/gitlab-group.tf.json?ref_type=heads&quot;&gt;dev.rachuna/artifacts/opentofu/gitlab-group&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja repozytorium &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/artifacts/opentofu/gitlab-project.tf.json?ref_type=heads&quot;&gt;dev.rachuna/artifacts/opentofu/gitlab-project&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja repozytorium &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/infrastructure/gitlab-com/iac-gitlab.tf.json?ref_type=heads&quot;&gt;dev.rachuna/infrastructure/gitlab-com/iac-gitlab&lt;/a&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-dev.module.artifacts.module.opentofu.module.gitlab-group.gitlab_project.project&lt;/span&gt;&lt;span&gt; 82399936&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-dev.module.artifacts.module.opentofu.module.gitlab-project.gitlab_project.project&lt;/span&gt;&lt;span&gt; 82423317&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-dev.module.infrastructure.module.gitlab-com.module.iac-gitlab.gitlab_project.project&lt;/span&gt;&lt;span&gt; 82399007&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;jak-zbudowane-jest-repozytorium-iac-gitlab&quot;&gt;Jak zbudowane jest repozytorium &lt;code dir=&quot;auto&quot;&gt;iac-gitlab&lt;/code&gt; ?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Struktura katalogów odzwierciedla hierarchię GitLaba:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;iac-gitlab-com&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── data/                                 # listy do walidacji (typy projektów, avatary, etykiety)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── dev.rachuna/                          # główna grupa i jej podgrupy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── apps/        &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   │   └── docs.tf.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── artifacts/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   │    └── opentofu/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   │         ├── gitlab-group.tf.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   │         └── gitlab-project.tf.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   └── infrastructure/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│       └── gitlab-com/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│           └── iac-gitlab.tf.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;└── _providers.tf.json                    # konfiguracja providerów (m.in. GitLab)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;tworzenie-projektu&quot;&gt;Tworzenie projektu&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Moduł &lt;code dir=&quot;auto&quot;&gt;gitlab-project&lt;/code&gt; umożliwia definiowanie parametrów projektu:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;module&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;iac-gitlab&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;source&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;git::https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-project.git?ref=1.0.0&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;iac-gitlab&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;description&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;IAC do zarządzania obiektami GitLab (gitlab.com).&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;visibility&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;public&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;parent_group&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;${local.parent_name}&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;project_type&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;opentofu-iac&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;environments&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;production&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;external_url&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/terraform&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded><category>gitlab</category><category>opentofu</category></item><item><title>Zarządzanie grupami w gitlab</title><link>https://rachuna.dev/blog/20260525/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260525/</guid><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.CdVOJLD3_Z2qWVGO.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1099&quot; height=&quot;331&quot;&gt;&lt;/p&gt;
&lt;p&gt;OpenTofu coraz częściej wykorzystywany jest nie tylko do budowy infrastruktury chmurowej, lecz także do zarządzania całym ekosystemem usług.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;po-co-iac-dla-gitlaba&quot;&gt;Po co IaC dla GitLaba?&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automatyzacja:&lt;/strong&gt; grupy i projekty tworzą się automatycznie na podstawie kodu.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Powtarzalność:&lt;/strong&gt; każda zmiana jest opisana w repozytorium, a &lt;code dir=&quot;auto&quot;&gt;tofu plan&lt;/code&gt; pokazuje różnice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rozliczalność:&lt;/strong&gt; pełna historia zmian wraz z informacją kto, gdzie i kiedy je zlecił.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Porządek:&lt;/strong&gt; struktura katalogów odpowiada strukturze GitLaba, co ułatwia nawigację i odnalezienie definicji konkretnej grupy czy projektu.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Wymagania&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zainstalowany opentofu&lt;/li&gt;
&lt;li&gt;repozytorium &lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab&quot;&gt;iac-gitlab&lt;/a&gt;&lt;/strong&gt; z zestawem definicji, który pozwala w deklaratywny sposób tworzyć i utrzymywać grupy oraz projekty w GitLabie.&lt;/li&gt;
&lt;li&gt;Moduł:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-group&quot;&gt;gitlab-group&lt;/a&gt;&lt;/strong&gt; - moduł opentofu do zarządzania grupami&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;krop-po-kroku&quot;&gt;Krop po kroku&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;przygotowanie-devcontainer&quot;&gt;Przygotowanie devcontainer&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna/devtools/devcontainers/-/tree/main/profiles/opentofu?ref_type=heads&quot;&gt;profiles/opentofu&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-obiektów&quot;&gt;Utworzenie obiektów&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Grupy:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.com/dev.rachuna&quot;&gt;dev.rachuna&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dev.rachuna → &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts&quot;&gt;artifacts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dev.rachuna → &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts&quot;&gt;artifacts&lt;/a&gt; → &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu&quot;&gt;opentofu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dev.rachuna → &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure&quot;&gt;infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dev.rachuna → &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure&quot;&gt;infrastructure&lt;/a&gt; → &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com&quot;&gt;gitlab-com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Repozytoria&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dev.rachuna → infrastructure → gitlab-com → &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab&quot;&gt;iac-gitlab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dev.rachuna → artifacts → opentofu → &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-group&quot;&gt;gitlab-group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;&quot;&gt;&lt;/h4&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;napisanie-logiki-dla-modułu-gitlab-group&quot;&gt;Napisanie logiki dla modułu &lt;code dir=&quot;auto&quot;&gt;gitlab-group&lt;/code&gt;&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Wydanie wersji &lt;a href=&quot;https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-group/-/releases/1.0.0&quot;&gt;1.0.0&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-definicji-w-iac-gitlab-com-dla-grup-i-import&quot;&gt;Utworzenie definicji w &lt;code dir=&quot;auto&quot;&gt;iac-gitlab-com&lt;/code&gt; dla grup i import&lt;/h3&gt;&lt;/div&gt;
&lt;aside aria-label=&quot;Danger&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Danger&lt;/p&gt;&lt;div&gt;&lt;p&gt;Grupy trzeba importować po kolei (najpierw rodzice, później dzieci)&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna.tf.json?ref_type=heads&quot;&gt;dev.rachuna&lt;/a&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module._pl_rachuna-net.gitlab_group.group&lt;/span&gt;&lt;span&gt; 82399007&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/apps.tf.json?ref_type=heads&quot;&gt;dev.rachuna/apps&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/artifacts.tf.json?ref_type=heads&quot;&gt;dev.rachuna/artifacts&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/devtools.tf.json?ref_type=heads&quot;&gt;dev.rachuna/devtools&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/infrastructure.tf.json?ref_type=heads&quot;&gt;dev.rachuna/infrastructure&lt;/a&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-net.module._apps.gitlab_group.group&lt;/span&gt;&lt;span&gt; 132755809&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-net.module._artifacts.gitlab_group.group&lt;/span&gt;&lt;span&gt; 132732346&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-net.module._devtools.gitlab_group.group&lt;/span&gt;&lt;span&gt; 132751910&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-net.module._infrastructure.gitlab_group.group&lt;/span&gt;&lt;span&gt; 132730200&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/artifacts/opentofu.tf.json?ref_type=heads&quot;&gt;dev.rachuna/artifacts/opentofu&lt;/a&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-net.module.artifacts.module._opentofu.gitlab_group.group&lt;/span&gt;&lt;span&gt; 132732367&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Definicja grupy &lt;a href=&quot;https://gitlab.com/dev.rachuna/infrastructure/gitlab-com/iac-gitlab/-/blob/main/dev.rachuna/infrastructure/gitlab-com.tf.json?ref_type=heads&quot;&gt;dev.rachuna/infrastructure/gitlab-com&lt;/a&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; import&lt;/span&gt;&lt;span&gt; module.pl_rachuna-net.module.infrastructure.module._gitlab-com.gitlab_group.group&lt;/span&gt;&lt;span&gt; 132730215&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;wdrażanie-zmian-z-opentofu&quot;&gt;Wdrażanie zmian z opentofu&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tofu&lt;/span&gt;&lt;span&gt; apply&lt;/span&gt;&lt;span&gt; -auto-approve&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;jak-zbudowane-jest-repozytorium-iac-gitlab-com&quot;&gt;Jak zbudowane jest repozytorium &lt;code dir=&quot;auto&quot;&gt;iac-gitlab-com&lt;/code&gt; ?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Struktura katalogów odzwierciedla hierarchię GitLaba:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;iac-gitlab-com&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── data/                # listy do walidacji (typy projektów, avatary, etykiety)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;├── dev.rachuna/      # główna grupa i jej podgrupy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── apps/        &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── artifacts/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   │    └── opentofu/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   ├── devtools/        &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│   └── infrastructure/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;│       └── gitlab-com/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;└── _providers.tf        # konfiguracja providerów (m.in. GitLab)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;przykładowa-definicja-grupy&quot;&gt;Przykładowa definicja grupy&lt;/h2&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;module&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;_devtools&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;source&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;git::https://gitlab.com/dev.rachuna/artifacts/opentofu/gitlab-group.git?ref=main&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;parent_group&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;${local.parent_name}&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;devtools&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;description&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Narzedzia i skrypty dla developerów&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;visibility&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;public&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;avatar&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;images/devtools.png&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;devtools&quot;&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;source&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;./devtools/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded><category>gitlab</category><category>opentofu</category></item><item><title>Statyczna strona na Gitlab pages</title><link>https://rachuna.dev/blog/20260522/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260522/</guid><pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.CRtrhfiP_1ChKfT.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1125&quot; height=&quot;341&quot;&gt;&lt;/p&gt;
&lt;p&gt;W tym wpisie pokaże wam, jak opublikować statyczną stronę internetową.
Wykorzystam framweork &lt;a href=&quot;https://astro.build/&quot;&gt;astro&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pobranie repozytorium z moją stroną&lt;/strong&gt;&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; clone&lt;/span&gt;&lt;span&gt; https://gitlab.com/dev.rachuna/apps/web.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;krop-po-kroku&quot;&gt;Krop po kroku&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-projektu-astro&quot;&gt;Utworzenie projektu astro&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; astro@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;dostosywanie-strony&quot;&gt;Dostosywanie strony&lt;/h3&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;tworzymy-prosty-pipeline-gitlab-ciyml&quot;&gt;Tworzymy prosty pipeline &lt;code dir=&quot;auto&quot;&gt;.gitlab-ci.yml&lt;/code&gt;&lt;/h3&gt;&lt;/div&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;stages&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  - &lt;/span&gt;&lt;span&gt;deploy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;node:20-alpine&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cache&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  key&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    files&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      - &lt;/span&gt;&lt;span&gt;package-lock.json&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  paths&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    - &lt;/span&gt;&lt;span&gt;node_modules/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pages&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  stage&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;deploy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  script&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    - &lt;/span&gt;&lt;span&gt;npm ci&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    - &lt;/span&gt;&lt;span&gt;npm run build&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    # GitLab Pages wymaga artifactu w katalogu public&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    - &lt;/span&gt;&lt;span&gt;rm -rf public&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    - &lt;/span&gt;&lt;span&gt;mv dist public&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  artifacts&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    paths&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      - &lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  # rules:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  #   # publikuj tylko z domyślnej gałęzi&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  #   - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;publikujemy-stronę&quot;&gt;Publikujemy stronę&lt;/h3&gt;&lt;/div&gt;
&lt;aside aria-label=&quot;Note&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Note&lt;/p&gt;&lt;div&gt;&lt;p&gt;Informacje o twojej stronie znajdziesz w &lt;strong&gt;Deploy&lt;/strong&gt; → &lt;strong&gt;Pages&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;W moim przypadku otrzymałem taką stronę&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;https://web-2d99ae.gitlab.io/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;utworzenie-domeny-w-pages&quot;&gt;Utworzenie domeny w pages&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Repozytorium&lt;/strong&gt; → &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Pages&lt;/strong&gt; → kliknij &lt;code dir=&quot;auto&quot;&gt;New Domain&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/new_domain.BIqouk_s_2aronz.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1296&quot; height=&quot;465&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ustawienie domeny &lt;a href=&quot;https://rachuna.dev&quot;&gt;rachuna.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitLab wygeneruje dwa rekordy DNS:
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;ALIAS&lt;/code&gt;:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;  docs.rachuna.dev.  ALIAS  dev.rachuna.gitlab.io.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;TXT&lt;/code&gt;:&lt;/p&gt;
&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;_gitlab-pages-verification-code.docs.rachuna.dev.  TXT  gitlab-pages-verification-code=&amp;#x3C;wygenerowany_kod&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;dodanie-rekordów-do-dns&quot;&gt;Dodanie rekordów do DNS&lt;/h3&gt;&lt;/div&gt;
&lt;aside aria-label=&quot;Danger&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Danger&lt;/p&gt;&lt;div&gt;&lt;p&gt;Na podstawie instrukcji &lt;a href=&quot;https://docs.gitlab.com/ee/user/project/pages/custom_domains_ssl_tls_certification/index.html#for-root-domains&quot;&gt;custom domains&lt;/a&gt;.
Dla domen głównych nie można użyć &lt;code dir=&quot;auto&quot;&gt;ALIAS/CNAME&lt;/code&gt;, należy użyć rekordu &lt;code dir=&quot;auto&quot;&gt;A&lt;/code&gt;.&lt;/p&gt;&lt;div data-nova-code-container=&quot;&quot;&gt;&lt;pre tabindex=&quot;0&quot; dir=&quot;ltr&quot;&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;rachuna.dev.   A   35.185.44.232&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;h3 id=&quot;gitlab-automatycznie-zweryfikuje-rekordy-i-wygeneruje-certyfikat-ssl-lets-encrypt&quot;&gt;GitLab automatycznie zweryfikuje rekordy i wygeneruje certyfikat SSL (Let’s Encrypt)&lt;/h3&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;przydatne-linki&quot;&gt;Przydatne linki&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://astro.build/&quot;&gt;Astro – Dokumentacja&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://starlight-theme-nova.pages.dev/guide/getting-started/&quot;&gt;starlight-theme-nova&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.gitlab.com/ee/user/project/pages/custom_domains_ssl_tls_certification/&quot;&gt;GitLab Pages – Custom Domains&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>gitlab</category></item><item><title>Moje środowisko LAB</title><link>https://rachuna.dev/blog/20260521/</link><guid isPermaLink="true">https://rachuna.dev/blog/20260521/</guid><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://rachuna.dev/_astro/cover.oq2SsA9a_ZMtb07.webp&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1127&quot; height=&quot;318&quot;&gt;&lt;/p&gt;
&lt;p&gt;W ostatnim czasie postanowiłem zrealizować długo odkładaną wizję – stworzyć własne laboratorium IT w domu, które pozwoli mi ćwiczyć i testować technologie DevOps w praktyce. Pomysł powstał z potrzeby eksperymentowania w środowisku zbliżonym do produkcyjnego, ale przy minimalnych kosztach i maksymalnej elastyczności.&lt;/p&gt;

&lt;div&gt;&lt;h2 id=&quot;wybór-sprzętu-mini-pc-jako-fundament-laboratorium&quot;&gt;Wybór sprzętu: Mini PC jako fundament laboratorium&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Do budowy mojego LAB-a wybrałem trzy kompaktowe Mini PC. Powody są proste: niski pobór energii, cicha praca i wystarczająca moc obliczeniowa do uruchamiania wielu maszyn wirtualnych. Każda z maszyn będzie pełnić rolę węzła wirtualizacyjnego, na którym zainstaluję Proxmox VE – sprawdzone narzędzie do zarządzania wirtualizacją i kontenerami LXC/VM. Dzięki temu będę miał pełną kontrolę nad maszynami wirtualnymi, snapshotami i klastrami HA, co jest kluczowe przy testach infrastruktury.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;storage-na-synology&quot;&gt;Storage na Synology&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Kluczowym elementem mojego LAB-a będzie centralny storage. Postawiłem na NAS Synology, który zapewnia nie tylko przestrzeń dyskową, ale również funkcje zaawansowanego zarządzania danymi, backupu i dostępności przez sieć. Wszystkie Mini PC będą korzystać z Synology jako magazynu dla maszyn wirtualnych i obrazów systemów, co pozwoli mi w prosty sposób tworzyć i przenosić VM-y pomiędzy węzłami. Dodatkowo, Synology umożliwia implementację iSCSI czy NFS, co idealnie integruje się z Proxmoxem.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;sieć-zarządzana-przez-mikrotika&quot;&gt;Sieć zarządzana przez Mikrotika&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Żeby móc testować złożone scenariusze sieciowe i DevOpsowe, potrzebowałem elastycznego rozwiązania do zarządzania siecią. W tym celu wybrałem router MikroTik. Dzięki niemu mogę tworzyć VLAN-y, testować routing, firewall, VPN-y i QoS. To pozwoli mi symulować środowiska produkcyjne, gdzie różne usługi i zespoły korzystają z odseparowanych segmentów sieci. MikroTik zapewnia też świetny interfejs do monitorowania ruchu i diagnostyki problemów w sieci.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;plany-rozwoju-kubernetes-i-devops&quot;&gt;Plany rozwoju: Kubernetes i DevOps&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Budowa laboratorium to dopiero początek. Moim celem jest stopniowe wdrażanie technologii kontenerowych i DevOpsowych. W najbliższym czasie planuję postawić Kubernetes na trzech węzłach Mini PC, co pozwoli mi testować skalowanie aplikacji, zarządzanie konfiguracją, automatyczne deploymenty i monitoring usług.&lt;/p&gt;
&lt;p&gt;Dalej chcę zintegrować narzędzia typowe dla DevOps, takie jak:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CI/CD&lt;/strong&gt; – Jenkins, GitLab CI/CD lub ArgoCD,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitoring i logowanie&lt;/strong&gt; – Prometheus, Grafana, Loki,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kontenery i obrazowanie&lt;/strong&gt; – Docker i Harbor,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zarządzanie konfiguracją&lt;/strong&gt; – Ansible, Terraform, Helm.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dzięki temu będę mógł ćwiczyć całe cykle DevOpsowe – od budowy aplikacji, przez automatyzację wdrożeń, aż po monitoring i optymalizację wydajności.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;zalety-własnego-lab-a&quot;&gt;Zalety własnego LAB-a&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Posiadanie własnego środowiska testowego daje nieocenione możliwości:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Eksperymentowanie bez ryzyka&lt;/strong&gt; – mogę testować konfiguracje produkcyjne bez obawy o wpływ na rzeczywiste systemy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Praktyczna nauka&lt;/strong&gt; – od wirtualizacji, przez sieci, po Kubernetes i CI/CD.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elastyczność&lt;/strong&gt; – możliwość szybkiego tworzenia i usuwania maszyn wirtualnych, wdrażania usług i testowania scenariuszy awaryjnych.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nauka DevOps od A do Z&lt;/strong&gt; – zrozumienie, jak wszystkie warstwy infrastruktury współpracują ze sobą.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h2 id=&quot;podsumowanie&quot;&gt;Podsumowanie&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Budowa domowego laboratorium DevOps na Mini PC, z Proxmoxem, Synology jako centralnym storage’em i siecią zarządzaną przez MikroTika, to nie tylko świetna zabawa, ale też praktyczna inwestycja w rozwój umiejętności IT. W przyszłości planuję rozbudować LAB o Kubernetes, narzędzia CI/CD i monitoring, co pozwoli mi w pełni odtworzyć środowisko zbliżone do rzeczywistego centrum danych. To idealne miejsce do nauki, testowania i eksperymentowania z nowoczesnymi technologiami DevOps.&lt;/p&gt;</content:encoded><category>infrastructure</category></item></channel></rss>