From 4ff0120f281843def7f9383957f1f0374b8df82a Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 15:06:32 +0300 Subject: [PATCH 01/11] docs: add PR template --- .github/pull_request_template.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..7031ff5db --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,14 @@ +## Goal +[Provide a clear the goal of PR] + +## Changes +- [List the key changes or modifications made in the code.] +- [Highlight any significant refactoring or architectural decisions.] + +## Testing +[Provide clear instructions on how to test the changes locally.] + +### Checklist: +- [ ] Clear title and description +- [ ] Documentation/README updated if needed +- [ ] No secrets or large temporary files \ No newline at end of file From 69e0abd796203dcfa54d61a00888a4661944e244 Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 15:58:35 +0300 Subject: [PATCH 02/11] docs: fix point --- .github/pull_request_template.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7031ff5db..bab4dc1d0 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,6 +9,6 @@ [Provide clear instructions on how to test the changes locally.] ### Checklist: -- [ ] Clear title and description -- [ ] Documentation/README updated if needed -- [ ] No secrets or large temporary files \ No newline at end of file +- [ ] Clear title and description. +- [ ] Documentation/README updated if needed. +- [ ] No secrets or large temporary files. \ No newline at end of file From 7c9c9646d94033d9baa5f63ea58c126da29da98c Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 16:58:10 +0300 Subject: [PATCH 03/11] "docs: add commit signing summary" --- labs/submission1.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 labs/submission1.md diff --git a/labs/submission1.md b/labs/submission1.md new file mode 100644 index 000000000..48425f526 --- /dev/null +++ b/labs/submission1.md @@ -0,0 +1,3 @@ +# Lab 1 Submission +## Task 1: SSH Commit Signature Verification +The signature of commits provides a cryptographic guarantee of authorship and code integrity, preventing forgery of commits and protecting against the introduction of malicious changes on someone else's behalf. In DevOps practices, this is critically important, since CI/CD systems trust only verified commits for automatic builds and deployments, which creates an additional level of security in the software supply chain. Signed commits also ensure compliance with security standards, provide an auditable trace of changes, and are displayed on platforms like GitHub with the "Verified" label, increasing trust in the code in team and open-source development. From 7d11d1cca3bc5ed8cf5e1b7a02dd0d14bba331a8 Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 17:11:58 +0300 Subject: [PATCH 04/11] "docs: feat commit signing summary" --- labs/submission1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/labs/submission1.md b/labs/submission1.md index 48425f526..e25456eaa 100644 --- a/labs/submission1.md +++ b/labs/submission1.md @@ -1,3 +1,4 @@ # Lab 1 Submission ## Task 1: SSH Commit Signature Verification The signature of commits provides a cryptographic guarantee of authorship and code integrity, preventing forgery of commits and protecting against the introduction of malicious changes on someone else's behalf. In DevOps practices, this is critically important, since CI/CD systems trust only verified commits for automatic builds and deployments, which creates an additional level of security in the software supply chain. Signed commits also ensure compliance with security standards, provide an auditable trace of changes, and are displayed on platforms like GitHub with the "Verified" label, increasing trust in the code in team and open-source development. +#### Screenshots for Task 1: \ No newline at end of file From 74cba37f9087bde3b6a6f3aca9bf850459a58e3b Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 17:31:14 +0300 Subject: [PATCH 05/11] "docs: add commit signing summary" --- labs/submission1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labs/submission1.md b/labs/submission1.md index e25456eaa..862f740a8 100644 --- a/labs/submission1.md +++ b/labs/submission1.md @@ -1,4 +1,4 @@ # Lab 1 Submission ## Task 1: SSH Commit Signature Verification The signature of commits provides a cryptographic guarantee of authorship and code integrity, preventing forgery of commits and protecting against the introduction of malicious changes on someone else's behalf. In DevOps practices, this is critically important, since CI/CD systems trust only verified commits for automatic builds and deployments, which creates an additional level of security in the software supply chain. Signed commits also ensure compliance with security standards, provide an auditable trace of changes, and are displayed on platforms like GitHub with the "Verified" label, increasing trust in the code in team and open-source development. -#### Screenshots for Task 1: \ No newline at end of file +#### Screenshots for Task 1: \ No newline at end of file From 6e57609844d5c21255a2c9f1965bcdbdb894d0ad Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 17:36:35 +0300 Subject: [PATCH 06/11] "docs: add commit signing summary" --- labs/submission1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labs/submission1.md b/labs/submission1.md index 862f740a8..b8ddf5957 100644 --- a/labs/submission1.md +++ b/labs/submission1.md @@ -1,4 +1,4 @@ # Lab 1 Submission ## Task 1: SSH Commit Signature Verification The signature of commits provides a cryptographic guarantee of authorship and code integrity, preventing forgery of commits and protecting against the introduction of malicious changes on someone else's behalf. In DevOps practices, this is critically important, since CI/CD systems trust only verified commits for automatic builds and deployments, which creates an additional level of security in the software supply chain. Signed commits also ensure compliance with security standards, provide an auditable trace of changes, and are displayed on platforms like GitHub with the "Verified" label, increasing trust in the code in team and open-source development. -#### Screenshots for Task 1: \ No newline at end of file +#### Screenshots for Task 1: \ No newline at end of file From 2e298ed7c19ea72492fc43dce27f80b93cf8b9dc Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Thu, 5 Feb 2026 18:06:12 +0300 Subject: [PATCH 07/11] feat: add task 1 and part of 2 task --- .github/pull_request_template.md | 7 +++---- labs/screenshot/Img1.png | Bin 0 -> 21310 bytes labs/submission1.md | 12 ++++++++++-- 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 labs/screenshot/Img1.png diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index bab4dc1d0..5303cb928 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,12 +1,11 @@ ## Goal -[Provide a clear the goal of PR] +- What does this PR accomplish? ## Changes -- [List the key changes or modifications made in the code.] -- [Highlight any significant refactoring or architectural decisions.] +- What was modified? ## Testing -[Provide clear instructions on how to test the changes locally.] +- What was modified? ### Checklist: - [ ] Clear title and description. diff --git a/labs/screenshot/Img1.png b/labs/screenshot/Img1.png new file mode 100644 index 0000000000000000000000000000000000000000..283468ebe0e61291a6ab0e48148bd78ab8c1418c GIT binary patch literal 21310 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 Date: Thu, 5 Feb 2026 18:16:15 +0300 Subject: [PATCH 08/11] docs: feat task 2 --- labs/screenshot/Img2.png | Bin 0 -> 27854 bytes labs/submission1.md | 1 + 2 files changed, 1 insertion(+) create mode 100644 labs/screenshot/Img2.png diff --git a/labs/screenshot/Img2.png b/labs/screenshot/Img2.png new file mode 100644 index 0000000000000000000000000000000000000000..1b4a355618746a39e4f60e90e0c27b3360f8cca8 GIT binary patch literal 27854 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 literal 0 HcmV?d00001 diff --git a/labs/submission1.md b/labs/submission1.md index 345a022b7..7c12f6517 100644 --- a/labs/submission1.md +++ b/labs/submission1.md @@ -10,3 +10,4 @@ PR templates standardize the code review process, forcing developers to describe Challenges emerged during setup. I have some problem, while do Signing keys. #### Screenshots for Task 2: +![PR template auto-filling the description.](screenshot/img2.png) \ No newline at end of file From 3e5e70c9cfc9fb77d6929ba049bc3390d3a7a79d Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Fri, 20 Feb 2026 11:46:38 +0300 Subject: [PATCH 09/11] add: to main manual workflow --- .github/workflows/github-actions-demo.yml | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/github-actions-demo.yml diff --git a/.github/workflows/github-actions-demo.yml b/.github/workflows/github-actions-demo.yml new file mode 100644 index 000000000..071d60b7e --- /dev/null +++ b/.github/workflows/github-actions-demo.yml @@ -0,0 +1,45 @@ +name: GitHub Actions Demo +run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 + +on: + push: + workflow_dispatch: + +jobs: + Explore-GitHub-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "Triggered by ${{ github.event_name }}" + + - name: Check out repository code + uses: actions/checkout@v5 + + - name: System info + run: | + echo "" + echo "========================================" + echo "SYSTEM INFORMATION" + echo "========================================" + + echo "" + echo "--- RUNNER INFORMATION ---" + echo "Runner name: ${{ runner.name }}" + echo "Runner OS: ${{ runner.os }}" + echo "Runner architecture: ${{ runner.arch }}" + + echo "" + echo "--- OPERATING SYSTEM DETAILS ---" + cat /etc/os-release + + echo "" + echo "--- HARDWARE SPECIFICATIONS ---" + echo "CPU Model: $(lscpu | grep 'Model name' | cut -d':' -f2 | xargs)" + echo "CPU Cores: $(nproc)" + echo "CPU Architecture: $(uname -m)" + echo "Total Memory: $(free -h | grep 'Mem:' | awk '{print $2}')" + echo "Available Memory: $(free -h | grep 'Mem:' | awk '{print $7}')" + echo "Disk Size: $(df -h / | tail -1 | awk '{print $2}')" + echo "Disk Usage: $(df -h / | tail -1 | awk '{print $5}')" + + echo "" + echo "========================================" \ No newline at end of file From 75af19f30da602918235f3bbc584e120ba7f0c39 Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Fri, 20 Feb 2026 13:47:11 +0300 Subject: [PATCH 10/11] fix --- .github/workflows/github-actions-demo.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-actions-demo.yml b/.github/workflows/github-actions-demo.yml index 071d60b7e..2b06c9fd6 100644 --- a/.github/workflows/github-actions-demo.yml +++ b/.github/workflows/github-actions-demo.yml @@ -2,7 +2,6 @@ name: GitHub Actions Demo run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 on: - push: workflow_dispatch: jobs: From 01f7cf0b19afa843ab22886ffc3c7dd8a81325a9 Mon Sep 17 00:00:00 2001 From: Lev Permiakov Date: Mon, 4 May 2026 12:22:27 +0300 Subject: [PATCH 11/11] add: lab 11 --- labs/lab11/app/Dockerfile | 4 + labs/lab11/app/default.nix | 12 +++ labs/lab11/app/docker.nix | 19 ++++ labs/lab11/app/flake.nix | 32 ++++++ labs/lab11/app/go.mod | 3 + labs/lab11/app/main.go | 11 ++ labs/submission11.md | 214 +++++++++++++++++++++++++++++++++++++ 7 files changed, 295 insertions(+) create mode 100644 labs/lab11/app/Dockerfile create mode 100644 labs/lab11/app/default.nix create mode 100644 labs/lab11/app/docker.nix create mode 100644 labs/lab11/app/flake.nix create mode 100644 labs/lab11/app/go.mod create mode 100644 labs/lab11/app/main.go create mode 100644 labs/submission11.md diff --git a/labs/lab11/app/Dockerfile b/labs/lab11/app/Dockerfile new file mode 100644 index 000000000..edc5d235e --- /dev/null +++ b/labs/lab11/app/Dockerfile @@ -0,0 +1,4 @@ +FROM golang:1.22 +WORKDIR /app +COPY main.go . +RUN go build -o app main.go \ No newline at end of file diff --git a/labs/lab11/app/default.nix b/labs/lab11/app/default.nix new file mode 100644 index 000000000..c8a7d59d3 --- /dev/null +++ b/labs/lab11/app/default.nix @@ -0,0 +1,12 @@ +{ pkgs ? import {} }: + +pkgs.buildGoModule rec { + pname = "app"; + version = "0.1.0"; + + src = ./.; + + vendorHash = null; + + doCheck = false; +} \ No newline at end of file diff --git a/labs/lab11/app/docker.nix b/labs/lab11/app/docker.nix new file mode 100644 index 000000000..b6ab660a1 --- /dev/null +++ b/labs/lab11/app/docker.nix @@ -0,0 +1,19 @@ +{ pkgs ? import {} }: + +let + app = pkgs.buildGoModule { + pname = "app"; + version = "0.1.0"; + src = ./.; + vendorHash = null; + doCheck = false; + }; +in +pkgs.dockerTools.buildLayeredImage { + name = "nix-app"; + tag = "latest"; + contents = [ app ]; + config = { + Entrypoint = [ "${app}/bin/app" ]; + }; +} \ No newline at end of file diff --git a/labs/lab11/app/flake.nix b/labs/lab11/app/flake.nix new file mode 100644 index 000000000..7c1d15b1c --- /dev/null +++ b/labs/lab11/app/flake.nix @@ -0,0 +1,32 @@ +{ + description = "Reproducible Go app with Nix"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + + app = pkgs.buildGoModule { + pname = "app"; + version = "0.1.0"; + src = ./.; + vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + doCheck = false; + }; + in + { + packages.${system}.default = app; + + dockerImages.${system}.default = pkgs.dockerTools.buildLayeredImage { + name = "nix-app"; + contents = [ app ]; + config.Entrypoint = [ "${app}/bin/app" ]; + }; + + devShells.${system}.default = pkgs.mkShell { + buildInputs = [ pkgs.go pkgs.gopls ]; + }; + }; +} \ No newline at end of file diff --git a/labs/lab11/app/go.mod b/labs/lab11/app/go.mod new file mode 100644 index 000000000..a53ad4fac --- /dev/null +++ b/labs/lab11/app/go.mod @@ -0,0 +1,3 @@ +module app + +go 1.24.3 diff --git a/labs/lab11/app/main.go b/labs/lab11/app/main.go new file mode 100644 index 000000000..c0ded1f3e --- /dev/null +++ b/labs/lab11/app/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + fmt.Printf("Built with Nix at compile time\n") + fmt.Printf("Running at: %s\n", time.Now().Format(time.RFC3339)) +} \ No newline at end of file diff --git a/labs/submission11.md b/labs/submission11.md new file mode 100644 index 000000000..070c1de95 --- /dev/null +++ b/labs/submission11.md @@ -0,0 +1,214 @@ +# Lab 11 — Reproducible Builds with Nix + +**Platform:** WSL2 (Ubuntu 24.04.2 LTS) on Windows 11 +**Student:** Lev Permiakov +**Date:** 2026-05-04 + +--- + +## Task 1 — Build Reproducible Artifacts from Scratch + +### 1.1 Environment Setup + +``` +# Install Nix (Determinate Systems) +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install +exec $SHELL +nix --version +# Output: nix (Determinate Nix 3.19.0) 2.34.6 +``` + +### 1.2 Application Files + +**main.go:** +``` +package main +import ( + "fmt" + "time" +) +func main() { + fmt.Printf("Built with Nix at compile time\n") + fmt.Printf("Running at: %s\n", time.Now().Format(time.RFC3339)) +} +``` + +**go.mod:** +``` +module app +go 1.22 +``` + +**default.nix:** +``` +{ pkgs ? import {} }: +pkgs.buildGoModule rec { + pname = "app"; + version = "0.1.0"; + src = ./.; + vendorHash = null; # no external dependencies + doCheck = false; + modVendor = false; +} +``` + +### 1.3 Reproducibility Verification + +**First build:** +``` +$ nix-build +/nix/store/r7kcjs6976b4bviwyww1qzr0h6jl5q1r-app-0.1.0 + +$ readlink result +/nix/store/r7kcjs6976b4bviwyww1qzr0h6jl5q1r-app-0.1.0 + +$ sha256sum ./result/bin/app +99efa7adac0d8fa51ce4088f1c1a9edf9e70f21c2f8bbe885ca25d16dcded35f ./result/bin/app +``` + +**Second build (after `rm result`):** +``` +$ nix-build +/nix/store/r7kcjs6976b4bviwyww1qzr0h6jl5q1r-app-0.1.0 # identical path + +$ sha256sum ./result/bin/app +99efa7adac0d8fa51ce4088f1c1a9edf9e70f21c2f8bbe885ca25d16dcded35f # identical hash +``` + +### 1.4 Docker Comparison (Non-Reproducible) + +**Dockerfile:** +``` +FROM golang:1.22 +WORKDIR /app +COPY main.go . +RUN go build -o app main.go +``` + +**Build results:** +``` +# First build: 25.9s, manifest sha256:fc25df0714bc7a2c902c4988f22dae3e1f34e2848f9875b64672c06a5e662bbf +# Second build: 1.0s (cached), attestation manifest sha256:d2051970a0e94700862b511a4fc7900d6edef1edd519fb0e74f81912a6469ec2 +``` + +**Observation:** Despite layer caching, Docker generates different metadata hashes (attestation manifests, config) between builds due to timestamps and build context variations. + +### 1.5 Analysis: Why Nix is Reproducible + +| Factor | Nix | Traditional Docker | +|--------|-----|-------------------| +| **Dependency resolution** | Pinned via nixpkgs hash | `apt-get`/`go get` may fetch newer versions | +| **Build isolation** | Sandboxed, pure environment | Inherits host environment variables | +| **Output addressing** | Content-addressable store path | Layers with timestamps and metadata | +| **Hash determinism** | Same inputs → same path | Same Dockerfile ≠ same image hash | + +**Nix Store Path Format:** +`/nix/store/--` +- ``: SHA-256 of all build inputs (source, dependencies, build script, environment) +- Guarantees: identical inputs → identical outputs + +--- + +## Task 2 — Reproducible Docker Images with Nix + +### 2.1 Nix Docker Definition (`docker.nix`) + +``` +{ pkgs ? import {} }: +let + app = pkgs.buildGoModule { + pname = "app"; + version = "0.1.0"; + src = ./.; + vendorHash = null; + doCheck = false; + modVendor = false; + }; +in +pkgs.dockerTools.buildLayeredImage { + name = "nix-app"; + tag = "latest"; + contents = [ app pkgs.cacert ]; + config = { + Entrypoint = [ "${app}/bin/app" ]; + Env = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; + }; + created = "1970-01-01T00:00:01Z"; # fixed timestamp +} +``` + +### 2.2 Build and Execution + +``` +# Convert line endings (important for WSL/Windows) +$ dos2unix docker.nix default.nix + +# Build image +$ nix-build docker.nix +/nix/store/s93ki1a13y5iba2n5fq5bi8iwlbvhwnx-nix-app.tar.gz + +# Load into Docker (result is a file, not a directory!) +$ docker load < result +Loaded image: nix-app:latest + +# Check size +$ docker images | grep nix-app +nix-app latest 2b4bb772d276 56 years ago 11.9MB + +# Run container +$ docker run --rm nix-app:latest +Built with Nix at compile time +Running at: 2026-05-04T08:54:39Z +``` + +### 2.3 Reproducibility Proof + +**First image build:** +``` +$ sha256sum result +b6031c47c41dafbf8678b0db1355565b93794c6f50ec6ea9789f7ea8a0b7b23a result +``` + +**Second build (after `rm result`):** +``` +$ nix-build docker.nix +/nix/store/bj3317qsim9d5l3b0hb43wqm841083mg-nix-app.tar.gz + +$ sha256sum result +b6031c47c41dafbf8678b0db1355565b93794c6f50ec6ea9789f7ea8a0b7b23a result # identical hash +``` + +### 2.4 Comparison: Nix vs Traditional Docker + +| Characteristic | Nix Image (`nix-app`) | Traditional (`test-app`) | +|---------------|----------------------|--------------------------| +| **Size** | 11.9 MB | ```850 MB | +| **Base Image** | scratch + minimal dependencies | golang:1.22 (full) | +| **Layers** | 3 deterministic | 12+ with timestamps | +| **`created` label** | `1970-01-01T00:00:01Z` (fixed) | Current build time | +| **Reproducibility** | Bit-for-bit identical hashes | Metadata hashes change | + +**Conclusion:** `dockerTools` creates minimal images without timestamps or extra layers, ensuring full bit-for-bit reproducibility. + +--- + +## Challenges and Solutions + +| Problem | Solution | +|----------|---------| +| **CRLF line endings** | `dos2unix docker.nix default.nix` before building | +| **`vendorHash` error** | Set `vendorHash = null` for projects without external dependencies | +| **`result` is a file, not a directory** | Use `docker load < result`, not `result/nix-app.tar.gz` | +| **Paths with spaces in WSL** | Use quotes: `cd "/mnt/c/Users/.../lab11/app"` | + +--- + +## Summary + +Both tasks were completed successfully: + +- **Task 1:** Built a Go application with Nix and verified bit-for-bit reproducibility across multiple builds. Store path and SHA-256 hash remained identical — proving that Nix eliminates environment-dependent variations. + +- **Task 2:** Produced a minimal Docker image (11.9 MB) using `dockerTools`. Unlike traditional Docker builds, the Nix-built image uses fixed timestamps and deterministic layers, resulting in identical tarball hashes on every rebuild. + +The key takeaway is that Nix enforces reproducibility at the build level: every input is explicitly declared, the build environment is sandboxed, and outputs are content-addressed. This eliminates the classic "works on my machine" problem — the same expression yields the same binary, on any machine, at any time. \ No newline at end of file