Community maintained Docker config for the knot server

buildah

+72 -102
+72 -102
.tangled/workflows/publish.yml
··· 7 7 8 8 dependencies: 9 9 nixpkgs: 10 - - nix 10 + - buildah 11 11 - skopeo 12 12 - coreutils 13 13 - gnused ··· 16 16 - git 17 17 18 18 steps: 19 - - name: "Create Nix expression for Docker image" 19 + - name: "Extract version from Dockerfile" 20 20 command: | 21 - cat > docker-image.nix << 'EOF' 22 - { pkgs ? import <nixpkgs> {} }: 21 + export TAG=$(grep -iE '^arg TAG=' Dockerfile | sed -E "s/arg TAG='?([^']+)'?/\1/i") 22 + echo "Extracted TAG: $TAG" 23 23 24 - let 25 - # Extract TAG from Dockerfile 26 - dockerfileContent = builtins.readFile ./Dockerfile; 27 - tagMatch = builtins.match ".*arg TAG='?([^']+)'?.*" dockerfileContent; 28 - tag = if tagMatch != null then builtins.elemAt tagMatch 0 else "latest"; 24 + if [ -z "$TAG" ]; then 25 + echo "ERROR: Could not extract TAG from Dockerfile" 26 + exit 1 27 + fi 29 28 30 - # Clone and build knot 31 - knotSrc = pkgs.fetchGit { 32 - url = "https://tangled.sh/@tangled.sh/core"; 33 - ref = tag; 34 - }; 29 + # Save TAG for later steps 30 + if [ -n "$TANGLED_ENV_FILE" ]; then 31 + echo "TAG=$TAG" >> "$TANGLED_ENV_FILE" 32 + fi 33 + echo "export TAG=$TAG" >> ~/.bashrc 35 34 36 - knot = pkgs.buildGoModule { 37 - pname = "knot"; 38 - version = tag; 39 - src = knotSrc; 40 - vendorHash = null; 41 - CGO_ENABLED = "1"; 42 - buildInputs = with pkgs; [ git gcc musl ]; 43 - ldflags = [ "-s" "-w" "-extldflags" "-static" ]; 44 - subPackages = [ "cmd/knot" ]; 45 - }; 35 + - name: "Build Docker image with buildah" 36 + command: | 37 + # Source environment 38 + source ~/.bashrc || true 39 + if [ -n "$TANGLED_ENV_FILE" ] && [ -f "$TANGLED_ENV_FILE" ]; then 40 + source "$TANGLED_ENV_FILE" 41 + fi 46 42 47 - # Create rootfs 48 - rootfs = pkgs.runCommand "rootfs" {} '' 49 - mkdir -p $out 50 - cp -r ${./rootfs}/* $out/ 2>/dev/null || true 51 - chmod 755 $out/etc 2>/dev/null || true 52 - chmod -R 755 $out/etc/s6-overlay 2>/dev/null || true 53 - ''; 43 + if [ -z "$TAG" ]; then 44 + echo "ERROR: TAG variable not set" 45 + exit 1 46 + fi 54 47 55 - in pkgs.dockerTools.buildImage { 56 - name = "knot"; 57 - tag = tag; 48 + echo "Building image with buildah for TAG: $TAG" 58 49 59 - copyToRoot = pkgs.buildEnv { 60 - name = "image-root"; 61 - paths = with pkgs; [ 62 - rootfs 63 - shadow 64 - s6-overlay 65 - execline 66 - openssl 67 - openssh 68 - git 69 - curl 70 - bash 71 - knot 72 - ]; 73 - pathsToLink = [ "/bin" "/etc" "/usr" "/home" "/app" ]; 74 - }; 50 + # Create a new container from alpine 51 + container=$(buildah from alpine:edge) 75 52 76 - runAsRoot = '' 77 - #!${pkgs.runtimeShell} 78 - ${pkgs.dockerTools.shadowSetup} 79 - useradd -d /home/git git 80 - echo "git:$(openssl rand -hex 16)" | chpasswd 81 - mkdir -p /home/git/repositories 82 - chown -R git:git /home/git 83 - mkdir -p /app 84 - chown -R git:git /app 85 - ''; 53 + # Configure the container 54 + buildah config --port 5555 --port 22 $container 55 + buildah config --env KNOT_REPO_SCAN_PATH=/home/git/repositories $container 56 + buildah config --workingdir /app $container 57 + buildah config --entrypoint '["/init"]' $container 86 58 87 - config = { 88 - Expose = { 89 - "5555/tcp" = {}; 90 - "22/tcp" = {}; 91 - }; 92 - Env = [ 93 - "KNOT_REPO_SCAN_PATH=/home/git/repositories" 94 - ]; 95 - Entrypoint = [ "/init" ]; 96 - Labels = { 97 - "org.opencontainers.image.title" = "knot"; 98 - "org.opencontainers.image.description" = "data server for tangled"; 99 - "org.opencontainers.image.source" = "https://tangled.sh/@tangled.sh/knot-docker"; 100 - "org.opencontainers.image.url" = "https://tangled.sh"; 101 - "org.opencontainers.image.vendor" = "tangled.sh"; 102 - "org.opencontainers.image.licenses" = "MIT"; 103 - }; 104 - Healthcheck = { 105 - Test = [ "CMD" "curl" "-f" "http://localhost:5555" ]; 106 - Interval = "60s"; 107 - Timeout = "30s"; 108 - StartPeriod = "5s"; 109 - Retries = 3; 110 - }; 111 - }; 112 - } 113 - EOF 59 + # Add labels 60 + buildah config --label "org.opencontainers.image.title=knot" $container 61 + buildah config --label "org.opencontainers.image.description=data server for tangled" $container 62 + buildah config --label "org.opencontainers.image.source=https://tangled.sh/@tangled.sh/knot-docker" $container 114 63 115 - - name: "Build Docker image with Nix" 116 - command: | 117 - echo "Building Docker image with Nix..." 118 - nix-build docker-image.nix -o docker-image.tar.gz 64 + # Install packages 65 + buildah run $container -- apk add --no-cache shadow s6-overlay execline openssl openssh git curl bash golang gcc musl-dev 66 + 67 + # Setup users and directories 68 + buildah run $container -- sh -c 'useradd -d /home/git git && echo "git:$(openssl rand -hex 16)" | chpasswd' 69 + buildah run $container -- mkdir -p /home/git/repositories 70 + buildah run $container -- chown -R git:git /home/git 71 + buildah run $container -- mkdir -p /app 72 + buildah run $container -- chown -R git:git /app 119 73 120 - # Extract tag from the built image 121 - export TAG=$(grep -iE '^arg TAG=' Dockerfile | sed -E "s/arg TAG='?([^']+)'?/\1/i") 122 - echo "Built image with TAG: $TAG" 74 + # Build knot binary 75 + buildah run $container -- git clone -b $TAG https://tangled.sh/@tangled.sh/core /tmp/knot-src 76 + buildah run $container -- sh -c 'cd /tmp/knot-src && CGO_ENABLED=1 go build -o /usr/bin/knot -ldflags "-s -w -extldflags -static" ./cmd/knot' 77 + buildah run $container -- rm -rf /tmp/knot-src 123 78 124 - # Save TAG for next steps 125 - if [ -n "$TANGLED_ENV_FILE" ]; then 126 - echo "TAG=$TAG" >> "$TANGLED_ENV_FILE" 79 + # Copy rootfs 80 + if [ -d "rootfs" ]; then 81 + buildah copy $container rootfs/ / 82 + buildah run $container -- chmod 755 /etc 83 + buildah run $container -- sh -c 'chmod -R 755 /etc/s6-overlay 2>/dev/null || true' 127 84 fi 128 - echo "export TAG=$TAG" >> ~/.bashrc 85 + 86 + # Add healthcheck (as a script since buildah doesn't support healthcheck directly) 87 + buildah run $container -- sh -c 'echo "#!/bin/sh\ncurl -f http://localhost:5555 || exit 1" > /usr/bin/healthcheck && chmod +x /usr/bin/healthcheck' 88 + 89 + # Commit the container to an image 90 + buildah commit $container localhost/$DOCKER_USERNAME/$DOCKER_REPO:$TAG 91 + buildah tag localhost/$DOCKER_USERNAME/$DOCKER_REPO:$TAG localhost/$DOCKER_USERNAME/$DOCKER_REPO:latest 92 + 93 + # Clean up 94 + buildah rm $container 95 + 96 + echo "Image built successfully: $DOCKER_USERNAME/$DOCKER_REPO:$TAG" 129 97 130 98 - name: "Push Docker image to registry" 131 99 command: | ··· 147 115 148 116 echo "Pushing image: $DOCKER_USERNAME/$DOCKER_REPO:$TAG" 149 117 150 - # Load the image and push with skopeo 118 + # Push the tagged image 151 119 skopeo copy \ 152 120 --dest-creds="$DOCKER_USERNAME:$DOCKER_PASSWORD" \ 153 - docker-archive:docker-image.tar.gz \ 121 + containers-storage:localhost/$DOCKER_USERNAME/$DOCKER_REPO:$TAG \ 154 122 docker://docker.io/$DOCKER_USERNAME/$DOCKER_REPO:$TAG 155 123 156 - # Also push as latest 124 + # Push as latest 157 125 skopeo copy \ 158 126 --dest-creds="$DOCKER_USERNAME:$DOCKER_PASSWORD" \ 159 - docker-archive:docker-image.tar.gz \ 127 + containers-storage:localhost/$DOCKER_USERNAME/$DOCKER_REPO:latest \ 160 128 docker://docker.io/$DOCKER_USERNAME/$DOCKER_REPO:latest 129 + 130 + echo "Successfully pushed both $TAG and latest tags" 161 131 162 132 environment: 163 133 GIT_COMMIT: "${CI_COMMIT_SHA}"