Community maintained Docker config for the knot server

try to use pkgs dockerTools

+126 -31
+126 -31
.tangled/workflows/publish.yml
··· 7 7 8 8 dependencies: 9 9 nixpkgs: 10 - - docker 10 + - nix 11 + - skopeo 11 12 - coreutils 12 13 - gnused 13 14 - gnugrep 14 15 - bash 16 + - git 15 17 16 18 steps: 17 - - name: "Check Docker availability" 19 + - name: "Create Nix expression for Docker image" 18 20 command: | 19 - echo "Checking Docker availability..." 20 - which docker || echo "Docker not found in PATH" 21 - docker --version || echo "Docker version check failed" 22 - docker info || echo "Docker daemon not running" 23 - ls -la /var/run/docker.sock || echo "Docker socket not found" 21 + cat > docker-image.nix << 'EOF' 22 + { pkgs ? import <nixpkgs> {} }: 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"; 29 + 30 + # Clone and build knot 31 + knotSrc = pkgs.fetchGit { 32 + url = "https://tangled.sh/@tangled.sh/core"; 33 + ref = tag; 34 + }; 35 + 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 + }; 46 + 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 + ''; 54 + 55 + in pkgs.dockerTools.buildImage { 56 + name = "knot"; 57 + tag = tag; 58 + 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 + }; 75 + 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 + ''; 86 + 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 24 114 25 - - name: "Extract version from Dockerfile" 115 + - name: "Build Docker image with Nix" 26 116 command: | 27 - if [ ! -f "Dockerfile" ]; then 28 - echo "ERROR: Dockerfile not found" 29 - exit 1 30 - fi 117 + echo "Building Docker image with Nix..." 118 + nix-build docker-image.nix -o docker-image.tar.gz 119 + 120 + # Extract tag from the built image 31 121 export TAG=$(grep -iE '^arg TAG=' Dockerfile | sed -E "s/arg TAG='?([^']+)'?/\1/i") 32 - if [ -z "$TAG" ]; then 33 - echo "ERROR: Could not extract TAG from Dockerfile" 34 - echo "Dockerfile content:" 35 - cat Dockerfile 36 - exit 1 37 - fi 38 - echo "Detected TAG=$TAG" 122 + echo "Built image with TAG: $TAG" 123 + 124 + # Save TAG for next steps 39 125 if [ -n "$TANGLED_ENV_FILE" ]; then 40 126 echo "TAG=$TAG" >> "$TANGLED_ENV_FILE" 41 127 fi 128 + echo "export TAG=$TAG" >> ~/.bashrc 42 129 43 - - name: "Log in to Docker Hub" 130 + - name: "Push Docker image to registry" 44 131 command: | 132 + # Source the environment 133 + source ~/.bashrc || true 134 + if [ -n "$TANGLED_ENV_FILE" ] && [ -f "$TANGLED_ENV_FILE" ]; then 135 + source "$TANGLED_ENV_FILE" 136 + fi 137 + 45 138 if [ -z "$DOCKER_USERNAME" ] || [ -z "$DOCKER_PASSWORD" ]; then 46 139 echo "ERROR: DOCKER_USERNAME or DOCKER_PASSWORD not set" 47 140 exit 1 48 141 fi 49 - echo "Logging in as: $DOCKER_USERNAME" 50 - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin 51 142 52 - - name: "Build Docker image" 53 - command: | 54 143 if [ -z "$TAG" ]; then 55 144 echo "ERROR: TAG variable not set" 56 145 exit 1 57 146 fi 58 - echo "Building image: $DOCKER_USERNAME/$DOCKER_REPO:$TAG" 59 - docker build --build-arg TAG="$TAG" -t "$DOCKER_USERNAME/$DOCKER_REPO:$TAG" . 60 - docker tag "$DOCKER_USERNAME/$DOCKER_REPO:$TAG" "$DOCKER_USERNAME/$DOCKER_REPO:latest" 147 + 148 + echo "Pushing image: $DOCKER_USERNAME/$DOCKER_REPO:$TAG" 149 + 150 + # Load the image and push with skopeo 151 + skopeo copy \ 152 + --dest-creds="$DOCKER_USERNAME:$DOCKER_PASSWORD" \ 153 + docker-archive:docker-image.tar.gz \ 154 + docker://docker.io/$DOCKER_USERNAME/$DOCKER_REPO:$TAG 61 155 62 - - name: "Push Docker image" 63 - command: | 64 - docker push "$DOCKER_USERNAME/$DOCKER_REPO:$TAG" 65 - docker push "$DOCKER_USERNAME/$DOCKER_REPO:latest" 156 + # Also push as latest 157 + skopeo copy \ 158 + --dest-creds="$DOCKER_USERNAME:$DOCKER_PASSWORD" \ 159 + docker-archive:docker-image.tar.gz \ 160 + docker://docker.io/$DOCKER_USERNAME/$DOCKER_REPO:latest 66 161 67 162 environment: 68 163 GIT_COMMIT: "${CI_COMMIT_SHA}"