Social cloud hosting
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: build container images with Nix on host

- Build runtime with Nix first, then copy into minimal debian-slim container
- Much faster than installing Nix inside container
- Single source of truth: flakes define runtime, container just runs it

Co-Authored-By: Claude <noreply@anthropic.com>

+90 -35
+45 -8
internal/cli/build.go
··· 69 69 } 70 70 71 71 func buildContainerImages(runtimes []string, flakePath string) error { 72 + // Check nix is available 73 + if _, err := exec.LookPath("nix"); err != nil { 74 + return fmt.Errorf("nix not found in PATH") 75 + } 76 + 72 77 // Check docker/podman is available 73 78 containerRuntime := "docker" 74 79 if _, err := exec.LookPath("docker"); err != nil { ··· 83 88 if _, err := os.Stat(dockerfilePath); err != nil { 84 89 return fmt.Errorf("container Dockerfile not found at %s", dockerfilePath) 85 90 } 86 - contextPath := filepath.Join(flakePath, "..") 91 + 92 + // Create temp build dir 93 + buildDir, err := os.MkdirTemp("", "at-rund-build-") 94 + if err != nil { 95 + return fmt.Errorf("failed to create build dir: %w", err) 96 + } 97 + defer os.RemoveAll(buildDir) 87 98 88 99 for _, runtime := range runtimes { 89 100 imageName := fmt.Sprintf("at-rund-%s:latest", runtime) 90 101 fmt.Printf("Building %s...\n", imageName) 91 102 92 - cmd := exec.Command(containerRuntime, "build", 93 - "--build-arg", fmt.Sprintf("RUNTIME=%s", runtime), 103 + runtimeDir := filepath.Join(flakePath, runtime) 104 + stagingDir := filepath.Join(buildDir, runtime) 105 + runtimeOutDir := filepath.Join(stagingDir, "runtime") 106 + 107 + if err := os.MkdirAll(runtimeOutDir, 0755); err != nil { 108 + return fmt.Errorf("failed to create staging dir: %w", err) 109 + } 110 + 111 + // Step 1: Build with Nix 112 + fmt.Printf(" [1/2] Building with Nix...\n") 113 + resultLink := filepath.Join(stagingDir, "result") 114 + 115 + nixCmd := exec.Command("nix", "build", runtimeDir, "--out-link", resultLink) 116 + nixCmd.Stdout = os.Stdout 117 + nixCmd.Stderr = os.Stderr 118 + if err := nixCmd.Run(); err != nil { 119 + return fmt.Errorf("nix build failed for %s: %w", runtime, err) 120 + } 121 + 122 + // Copy the result (dereferencing symlinks) 123 + cpCmd := exec.Command("cp", "-rL", resultLink+"/.", runtimeOutDir) 124 + if err := cpCmd.Run(); err != nil { 125 + return fmt.Errorf("failed to copy nix result: %w", err) 126 + } 127 + 128 + // Step 2: Build container 129 + fmt.Printf(" [2/2] Building container image...\n") 130 + dockerCmd := exec.Command(containerRuntime, "build", 94 131 "-t", imageName, 95 132 "-f", dockerfilePath, 96 - contextPath, 133 + stagingDir, 97 134 ) 98 - cmd.Stdout = os.Stdout 99 - cmd.Stderr = os.Stderr 135 + dockerCmd.Stdout = os.Stdout 136 + dockerCmd.Stderr = os.Stderr 100 137 101 - if err := cmd.Run(); err != nil { 102 - return fmt.Errorf("failed to build %s: %w", runtime, err) 138 + if err := dockerCmd.Run(); err != nil { 139 + return fmt.Errorf("container build failed for %s: %w", runtime, err) 103 140 } 104 141 105 142 fmt.Printf(" ✓ Built %s\n", imageName)
+5 -20
nix/container/Dockerfile
··· 1 1 FROM debian:bookworm-slim 2 2 3 - ARG RUNTIME=deno 4 - 5 - # Install Nix 3 + # Install minimal runtime dependencies 6 4 RUN apt-get update && apt-get install -y --no-install-recommends \ 7 5 ca-certificates \ 8 - curl \ 9 - xz-utils \ 6 + jq \ 10 7 && rm -rf /var/lib/apt/lists/* 11 8 12 - # Install Nix in single-user mode (simpler for containers) 13 - RUN curl -L https://nixos.org/nix/install | sh -s -- --no-daemon 9 + # Copy pre-built runtime from Nix (provided via --build-arg or mounted) 10 + # The runtime directory contains bin/at-run-exec and all dependencies 11 + COPY runtime /runtime 14 12 15 - # Set up Nix environment 16 - ENV PATH="/root/.nix-profile/bin:$PATH" 17 - ENV NIX_PATH="nixpkgs=channel:nixos-24.11" 18 - 19 - # Copy runtime flakes 20 - COPY runtimes /runtimes 21 - 22 - # Build the runtime using its flake 23 - RUN . /root/.nix-profile/etc/profile.d/nix.sh && \ 24 - nix build /runtimes/${RUNTIME} --out-link /runtime && \ 25 - nix-collect-garbage -d 26 - 27 - # The runtime provides at-run-exec in its bin/ 28 13 ENV PATH="/runtime/bin:$PATH" 29 14 30 15 WORKDIR /bundle
+40 -7
nix/container/build.sh
··· 2 2 # Build container images for at-rund runtimes 3 3 # Usage: ./build.sh [runtime] 4 4 # If no runtime specified, builds all 5 + # 6 + # This script: 7 + # 1. Builds the runtime with Nix (produces bin/at-run-exec + dependencies) 8 + # 2. Creates a minimal debian-slim container with the pre-built runtime 5 9 6 10 set -e 7 11 8 12 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 9 13 RUNTIMES_DIR="$SCRIPT_DIR/../runtimes" 14 + BUILD_DIR="$SCRIPT_DIR/build" 10 15 11 16 build_runtime() { 12 17 local runtime=$1 13 - echo "Building at-rund-${runtime}:latest..." 18 + local runtime_dir="$RUNTIMES_DIR/$runtime" 19 + local staging_dir="$BUILD_DIR/$runtime" 20 + 21 + echo "=== Building at-rund-${runtime}:latest ===" 22 + 23 + # Clean staging 24 + rm -rf "$staging_dir" 25 + mkdir -p "$staging_dir/runtime" 26 + 27 + # Step 1: Build with Nix 28 + echo " [1/2] Building with Nix..." 29 + if [ -f "$runtime_dir/flake.nix" ]; then 30 + nix build "$runtime_dir" --out-link "$staging_dir/result" 31 + 32 + # Copy the Nix store closure to staging 33 + # We need to copy the actual files, not symlinks 34 + cp -rL "$staging_dir/result/." "$staging_dir/runtime/" 35 + rm "$staging_dir/result" 36 + else 37 + echo "Error: No flake.nix found for $runtime" 38 + exit 1 39 + fi 14 40 41 + # Step 2: Build container 42 + echo " [2/2] Building container image..." 15 43 docker build \ 16 - --build-arg RUNTIME="$runtime" \ 17 44 -t "at-rund-${runtime}:latest" \ 18 45 -f "$SCRIPT_DIR/Dockerfile" \ 19 - "$SCRIPT_DIR/.." 46 + "$staging_dir" 47 + 48 + # Cleanup 49 + rm -rf "$staging_dir" 20 50 21 - echo "Built at-rund-${runtime}:latest" 51 + echo " ✓ Built at-rund-${runtime}:latest" 22 52 } 23 53 54 + # Ensure build directory exists 55 + mkdir -p "$BUILD_DIR" 56 + 24 57 if [ -n "$1" ]; then 25 - # Build specific runtime 26 58 build_runtime "$1" 27 59 else 28 - # Build all runtimes that have flakes 29 60 for dir in "$RUNTIMES_DIR"/*/; do 30 61 runtime=$(basename "$dir") 31 62 if [ -f "$dir/flake.nix" ]; then ··· 34 65 done 35 66 fi 36 67 37 - echo "Done!" 68 + echo "" 69 + echo "Done! Images built:" 70 + docker images | grep "at-rund-"