about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlan Pearce2024-04-19 16:11:33 +0200
committerAlan Pearce2024-04-19 22:13:42 +0200
commit30e4cb4e4af3a6eebd3b4fb431828d284a72a10a (patch)
treeca5ae02e140f9d1b35a9824da04a71e32a981a47
parent0fc79f324d54cc7a45c0ad0ffa9c75cd716e0126 (diff)
downloadwebsite-30e4cb4e4af3a6eebd3b4fb431828d284a72a10a.tar.lz
website-30e4cb4e4af3a6eebd3b4fb431828d284a72a10a.tar.zst
website-30e4cb4e4af3a6eebd3b4fb431828d284a72a10a.zip
use nix to build docker images
-rw-r--r--.dockerignore10
-rw-r--r--.envrc1
-rw-r--r--.gitignore1
-rw-r--r--Dockerfile34
-rw-r--r--flake.nix33
-rw-r--r--fly.toml3
-rw-r--r--nix/default.nix71
-rw-r--r--nix/gomod2nix.toml142
-rw-r--r--nix/scripts.nix49
9 files changed, 280 insertions, 64 deletions
diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 48be77d..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,10 +0,0 @@
-*
-!cmd
-!server.go
-!content
-!internal
-!static
-!templates
-!config.toml
-!go.mod
-!go.sum
diff --git a/.envrc b/.envrc
index 3550a30..5973c50 100644
--- a/.envrc
+++ b/.envrc
@@ -1 +1,2 @@
+watch_file nix/*
 use flake
diff --git a/.gitignore b/.gitignore
index ae7753d..7dc1da8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -172,3 +172,4 @@ dist
 /.compressstamp
 /.formatstamp
 /server
+/result
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index bf8da92..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# syntax = docker/dockerfile:1
-
-ARG GO_VERSION=1.22.1
-FROM docker.io/library/golang:${GO_VERSION} as builder
-
-WORKDIR /app
-
-COPY --link go.mod .
-RUN go mod download
-
-COPY --link . .
-
-# RUN go vet ./...
-ENV ENV=production
-RUN go run ./cmd/build
-
-ENV GOOS=linux GOARCH=amd64 CGO_ENABLED=0
-RUN go build server.go
-
-# Final stage for app image
-FROM gcr.io/distroless/static
-
-WORKDIR /app
-
-# Copy built application
-COPY --link config.toml .
-COPY --from=builder /app/server server
-
-# Start the server by default, this can be overwritten at runtime
-EXPOSE 3000
-EXPOSE 9091
-
-ENV ENV=production
-CMD [ "/app/server" ]
diff --git a/flake.nix b/flake.nix
index 4d78ce1..78a2c53 100644
--- a/flake.nix
+++ b/flake.nix
@@ -12,37 +12,34 @@
     inputs.flake-utils.follows = "utils";
   };
 
-  outputs = { nixpkgs, utils, gomod2nix, ... }:
+  outputs = { self, nixpkgs, utils, gomod2nix, ... }:
     utils.lib.eachDefaultSystem
       (system:
         let
-          pkgs = nixpkgs.legacyPackages.${system};
-          nativeBuildInputs = with pkgs; [
-            git
-            go
-          ];
+          pkgs = import nixpkgs {
+            inherit system;
+            overlays = [ gomod2nix.overlays.default ];
+          };
+          nativeBuildInputs = with pkgs; [ go ];
+          packages = import ./nix/default.nix {
+            inherit pkgs self;
+          };
         in
-        rec {
+        {
+          inherit packages;
           devShells = {
             default = pkgs.mkShell {
               packages = with pkgs; [
                 gopls
                 gotools
                 go-tools
-                go-licenses
                 gomod2nix.packages.${system}.default
                 gci
                 flyctl
-                (writeShellScriptBin "watch-builder" ''
-                  ${pkgs.watchexec}/bin/watchexec -r -w flake.nix --shell fish "direnv exec . watchexec -i server.go -i public -r go run ./cmd/build $@"
-                '')
-                (writeShellScriptBin "watch-server" ''
-                  ${pkgs.watchexec}/bin/watchexec -r -w flake.nix --shell fish "direnv exec . watchexec -r go run ./server.go $@"
-                '')
-                (writeShellScriptBin "check-licenses" ''
-                  ${pkgs.go-licenses}/bin/go-licenses check --include_tests ./... --disallowed_types=restricted,forbidden
-                '')
-              ] ++ nativeBuildInputs;
+              ]
+              ++ (import ./nix/scripts.nix {
+                inherit pkgs;
+              });
             };
           };
         });
diff --git a/fly.toml b/fly.toml
index cd2269d..5b7f722 100644
--- a/fly.toml
+++ b/fly.toml
@@ -7,8 +7,7 @@ app = "alanpearce-eu"
 primary_region = "ams"
 
 [build]
-  [build.args]
-    GO_VERSION = "1.22.1"
+  image = "registry.fly.io/alanpearce-eu"
 
 [env]
   PORT = "3000"
diff --git a/nix/default.nix b/nix/default.nix
new file mode 100644
index 0000000..a04131b
--- /dev/null
+++ b/nix/default.nix
@@ -0,0 +1,71 @@
+{ pkgs, self }:
+let
+  revision = "${self.lastModifiedDate}-${self.shortRev or "dirty"}";
+  version = "unstable-${self.shortRev or "dirty"}";
+  mkDocker = server:
+    let
+      PORT = 3000;
+    in
+    pkgs.dockerTools.streamLayeredImage {
+      name = "registry.fly.io/alanpearce-eu";
+      tag = revision;
+      contents = [ server ];
+      config = {
+        Cmd = [ "website" ];
+        Env = [
+          "PRODUCTION=true"
+          "PORT=${builtins.toString PORT}"
+          "ROOT=public"
+        ];
+        ExposedPorts = {
+          "${builtins.toString PORT}/tcp" = { };
+        };
+      };
+    };
+in
+rec {
+  default = server;
+  builder = pkgs.buildGoApplication {
+    pname = "website-builder";
+    inherit version;
+    src = with pkgs.lib.fileset; toSource {
+      root = ./..;
+      fileset = unions [
+        ./../go.mod
+        ./../go.sum
+        ./../cmd
+        ./../internal
+      ];
+    };
+    modules = ./gomod2nix.toml;
+    subPackages = [ "cmd/build" ];
+  };
+  server = pkgs.buildGoApplication {
+    pname = "website";
+    inherit version;
+    CGO_ENABLED = 0;
+    src = with pkgs.lib.fileset; toSource {
+      root = ./..;
+      fileset = unions [
+        ./../go.mod
+        ./../go.sum
+        ./../server.go
+        ./../internal
+        ./../config.toml
+        ./../content
+        ./../static
+        ./../templates
+      ];
+    };
+    buildInputs = [ builder ];
+    prePatch = ''
+      ${builder}/bin/build
+    '';
+    modules = ./gomod2nix.toml;
+    ldflags = [ "-s" "-w" ];
+  };
+  docker = mkDocker server;
+  docker-aarch64-linux = mkDocker (self.packages.aarch64-linux.server);
+  docker-x86_64-linux = mkDocker (self.packages.x86_64-linux.server);
+  fly = docker-x86_64-linux;
+}
diff --git a/nix/gomod2nix.toml b/nix/gomod2nix.toml
new file mode 100644
index 0000000..83643b5
--- /dev/null
+++ b/nix/gomod2nix.toml
@@ -0,0 +1,142 @@
+schema = 3
+
+[mod]
+  [mod."github.com/BurntSushi/toml"]
+    version = "v1.2.1"
+    hash = "sha256-Z1dlsUTjF8SJZCknYKt7ufJz8NPGg9P9+W17DQn+LO0="
+  [mod."github.com/PuerkitoBio/goquery"]
+    version = "v1.9.1"
+    hash = "sha256-HlO8KL0FWs7qZk56wcVAn/y080PfK910HyIVo9y9lvM="
+  [mod."github.com/a-h/htmlformat"]
+    version = "v0.0.0-20240418170242-387207ca8d01"
+    hash = "sha256-6EhDObXsE0ObvaHCPXl2pHXhKaEYr/mUZNhLPcUz3L0="
+    replaced = "github.com/alanpearce/htmlformat"
+  [mod."github.com/adrg/frontmatter"]
+    version = "v0.2.0"
+    hash = "sha256-WJsVcdCpkIkjqUz5fJOFStZYwQlrcFzQ6+mZatZiimo="
+  [mod."github.com/andybalholm/brotli"]
+    version = "v1.1.0"
+    hash = "sha256-njLViV4v++ZdgOWGWzlvkefuFvA/nkugl3Ta/h1nu/0="
+  [mod."github.com/andybalholm/cascadia"]
+    version = "v1.3.2"
+    hash = "sha256-Nc9SkqJO/ecincVcUBFITy24TMmMGj5o0Q8EgdNhrEk="
+  [mod."github.com/ansrivas/fiberprometheus/v2"]
+    version = "v2.6.1"
+    hash = "sha256-C8WChMGD3fJucEqkUEu4kMGdP75xXCgVOLdxJu0x3jI="
+  [mod."github.com/antchfx/xmlquery"]
+    version = "v1.4.0"
+    hash = "sha256-ReWP6CPDvvWUd7vY0qIP4qyxvrotXrx9HXbGbeProP4="
+  [mod."github.com/antchfx/xpath"]
+    version = "v1.3.0"
+    hash = "sha256-SU+Tnf5c9vsDCrY1BVKjqYLhB91xt9oHBS5bicbs2cA="
+  [mod."github.com/ardanlabs/conf/v3"]
+    version = "v3.1.7"
+    hash = "sha256-7H53l0JN5Q6hkAgBivVQ8lFd03oNmP1IG8ihzLKm2CQ="
+  [mod."github.com/beorn7/perks"]
+    version = "v1.0.1"
+    hash = "sha256-h75GUqfwJKngCJQVE5Ao5wnO3cfKD9lSIteoLp/3xJ4="
+  [mod."github.com/cespare/xxhash/v2"]
+    version = "v2.2.0"
+    hash = "sha256-nPufwYQfTkyrEkbBrpqM3C2vnMxfIz6tAaBmiUP7vd4="
+  [mod."github.com/deckarep/golang-set/v2"]
+    version = "v2.6.0"
+    hash = "sha256-ni1XK75Q8iBBmxgoyZTedP4RmrUPzFC4978xB4HKdfs="
+  [mod."github.com/getsentry/sentry-go"]
+    version = "v0.27.0"
+    hash = "sha256-PTkTzVNogqFA/5rc6INLY6RxK5uR1AoJFOO+pOPdE7Q="
+  [mod."github.com/gofiber/adaptor/v2"]
+    version = "v2.2.1"
+    hash = "sha256-hQLeFAC3oRQA14sUK5kBfl+dbqYmULM9TA0bDgNhfp4="
+  [mod."github.com/gofiber/contrib/fibersentry"]
+    version = "v1.0.4"
+    hash = "sha256-feTWuq9aANPm16IpB1ZLZD4gZGt3Fs8Rr2d373Dlzqw="
+  [mod."github.com/gofiber/fiber/v2"]
+    version = "v2.52.4"
+    hash = "sha256-Lp6btwX5ZPo09IrCPz+f7fIztrI9W/sTULBRqAvXJu0="
+  [mod."github.com/golang/groupcache"]
+    version = "v0.0.0-20210331224755-41bb18bfe9da"
+    hash = "sha256-7Gs7CS9gEYZkbu5P4hqPGBpeGZWC64VDwraSKFF+VR0="
+  [mod."github.com/golang/protobuf"]
+    version = "v1.5.3"
+    hash = "sha256-svogITcP4orUIsJFjMtp+Uv1+fKJv2Q5Zwf2dMqnpOQ="
+  [mod."github.com/google/uuid"]
+    version = "v1.6.0"
+    hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw="
+  [mod."github.com/klauspost/compress"]
+    version = "v1.17.8"
+    hash = "sha256-8rgCCfHX29le8m6fyVn6gwFde5TPUHjwQqZqv9JIubs="
+  [mod."github.com/kr/text"]
+    version = "v0.1.0"
+    hash = "sha256-QT65kTrNypS5GPWGvgnCpGLPlVbQAL4IYvuqAKhepb4="
+  [mod."github.com/mattn/go-colorable"]
+    version = "v0.1.13"
+    hash = "sha256-qb3Qbo0CELGRIzvw7NVM1g/aayaz4Tguppk9MD2/OI8="
+  [mod."github.com/mattn/go-isatty"]
+    version = "v0.0.20"
+    hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ="
+  [mod."github.com/mattn/go-runewidth"]
+    version = "v0.0.15"
+    hash = "sha256-WP39EU2UrQbByYfnwrkBDoKN7xzXsBssDq3pNryBGm0="
+  [mod."github.com/matttproud/golang_protobuf_extensions"]
+    version = "v1.0.4"
+    hash = "sha256-uovu7OycdeZ2oYQ7FhVxLey5ZX3T0FzShaRldndyGvc="
+  [mod."github.com/otiai10/copy"]
+    version = "v1.14.0"
+    hash = "sha256-xsaL1ddkPS544y0Jv7u/INUALBYmYq29ddWvysLXk4A="
+  [mod."github.com/philhofer/fwd"]
+    version = "v1.1.2"
+    hash = "sha256-N+jWn8FSjVlb/OAWmvLTm2G5/ckIkhzSPePXoeymfyA="
+  [mod."github.com/pkg/errors"]
+    version = "v0.9.1"
+    hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw="
+  [mod."github.com/prometheus/client_golang"]
+    version = "v1.16.0"
+    hash = "sha256-P/b4/8m1ztF0fCLSJ+eRXN74Bncx2vjOJx7nFl2QEg4="
+  [mod."github.com/prometheus/client_model"]
+    version = "v0.4.0"
+    hash = "sha256-4P0sPWpxa69gGM6zm3dA06cH6twaeopq22VVDJjucHA="
+  [mod."github.com/prometheus/common"]
+    version = "v0.44.0"
+    hash = "sha256-8n3gSWKDSJtGfOQgxsiCGyTnUjb5hvSxJi/hPcrE5Oo="
+  [mod."github.com/prometheus/procfs"]
+    version = "v0.11.0"
+    hash = "sha256-dfbKDyKmL+BNGVuvEZmw1CiGBiwqUADxJKkIi1Sbv1Y="
+  [mod."github.com/rivo/uniseg"]
+    version = "v0.4.7"
+    hash = "sha256-rDcdNYH6ZD8KouyyiZCUEy8JrjOQoAkxHBhugrfHjFo="
+  [mod."github.com/shengyanli1982/law"]
+    version = "v0.1.12"
+    hash = "sha256-TWkgqfmJ9Zhr+1weI+zN0lyJfJdjpLbyQ/zh1EBBpow="
+  [mod."github.com/tinylib/msgp"]
+    version = "v1.1.8"
+    hash = "sha256-nwTpHiEe0pjloZosGmS+z1ZcsVm5dW4OaPhzJG2wAng="
+  [mod."github.com/valyala/bytebufferpool"]
+    version = "v1.0.0"
+    hash = "sha256-I9FPZ3kCNRB+o0dpMwBnwZ35Fj9+ThvITn8a3Jr8mAY="
+  [mod."github.com/valyala/fasthttp"]
+    version = "v1.52.0"
+    hash = "sha256-Gmcd4N4VOqI7Pl9Trb2ifDhaCU/AjEpuVdyNGGww5zc="
+  [mod."github.com/valyala/tcplisten"]
+    version = "v1.0.0"
+    hash = "sha256-aP0CrNH6UNRMhzgA2NgPwKyZs6xry5aDlZnLgGuHZbs="
+  [mod."github.com/yuin/goldmark"]
+    version = "v1.7.1"
+    hash = "sha256-3EUgwoZRRs2jNBWSbB0DGNmfBvx7CeAgEwyUdaRaeR4="
+  [mod."golang.org/x/net"]
+    version = "v0.21.0"
+    hash = "sha256-LfiqMpPtqvW/eLkfx6Ebr5ksqKbQli6uq06c/+XrBsw="
+  [mod."golang.org/x/sync"]
+    version = "v0.3.0"
+    hash = "sha256-bCJKLvwExhYacH2ZrWlZ38lr1d6oNenNt2m1QqDCs0o="
+  [mod."golang.org/x/sys"]
+    version = "v0.19.0"
+    hash = "sha256-cmuL31TYLJmDm/fDnI2Sn0wB88cpdOHV1+urorsJWx4="
+  [mod."golang.org/x/text"]
+    version = "v0.14.0"
+    hash = "sha256-yh3B0tom1RfzQBf1RNmfdNWF1PtiqxV41jW1GVS6JAg="
+  [mod."google.golang.org/protobuf"]
+    version = "v1.30.0"
+    hash = "sha256-Y07NKhSuJQ2w7F7MAINQyBf+/hdMHOrxwA3B4ljQQKs="
+  [mod."gopkg.in/yaml.v2"]
+    version = "v2.4.0"
+    hash = "sha256-uVEGglIedjOIGZzHW4YwN1VoRSTK8o0eGZqzd+TNdd0="
diff --git a/nix/scripts.nix b/nix/scripts.nix
new file mode 100644
index 0000000..94e4d85
--- /dev/null
+++ b/nix/scripts.nix
@@ -0,0 +1,49 @@
+{ pkgs ? import <nixpkgs> { }, ... }:
+let
+  watchFlake = with pkgs; ''
+    ${watchexec}/bin/watchexec --restart \
+     --watch flake.nix \
+     --watch flake.lock \
+  '';
+  image = (builtins.fromTOML (builtins.readFile ../fly.toml)).build.image;
+  nonDarwinSystem = builtins.replaceStrings [ "darwin" ] [ "linux" ] pkgs.stdenv.system;
+  attr = "docker-${nonDarwinSystem}";
+  sh = (pkgs.lib.optionalString pkgs.stdenv.isDarwin "ssh linux-builder ")
+    + "sh";
+  stream = attr: "nix build --print-out-paths .#${attr} | ${sh}";
+in
+with pkgs; [
+  (writeShellScriptBin "watch-builder" ''
+    ${watchFlake} "direnv exec . watchexec -i server.go -i public -r go run ./cmd/build $@"
+  '')
+  (writeShellScriptBin "watch-server" ''
+    ${watchFlake} "direnv exec . watchexec -r go run ./server.go $@"
+  '')
+  (writeShellScriptBin "check-licenses" ''
+    ${go-licenses}/bin/go-licenses check --include_tests ./... --disallowed_types=restricted,forbidden
+  '')
+  (writeShellScriptBin "stream" "${stream attr}")
+  (writeShellScriptBin "stream-fly" "${stream "fly"}")
+  (writeShellScriptBin "load-locally" ''
+    ${stream attr} | ${docker-client}/bin/docker load "$@"
+  '')
+  (writeShellScriptBin "push-to-registry" ''
+    if test -z "''${1:-}"; then
+    cat <<-EOF
+        USAGE: $0 <docker-url> [skopeo-copy-options]
+
+        Example: $0 docker://some_docker_registry/myimage:tag
+
+        See: https://github.com/containers/skopeo/blob/main/docs/skopeo-copy.1.md
+    EOF
+      exit 1
+    fi
+    echo skopeo copy docker-archive:/dev/stdin "$@"
+    stream-fly | ${gzip}/bin/gzip --fast | ${skopeo}/bin/skopeo copy docker-archive:/dev/stdin "$@"
+  '')
+  (writeShellScriptBin "deploy" ''
+    set -eu
+    push-to-registry docker://${image}
+    ${pkgs.flyctl}/bin/flyctl deploy
+  '')
+]