fix(nix): fix GHC 9.10.3 interface-file crash and binary name

Generated.Types imports 119 modules, pushing the combined .hi read past
a ~287 MB binary-deserialization limit in GHC 9.10.3. Fix by adding a
nixpkgs overlay that patches the inter-hub-models derivation: replaces
Generated/Types.hs with a thin TypesPart1/TypesPart2 re-export wrapper
after build-generated-code runs, and adds the two split modules to the
cabal exposed-modules list.

Also fix the production binary name from /bin/App to /bin/RunProdServer
in deployment.yaml and RUNBOOK.md (the IHP NixSupport build produces
RunProdServer, not App). Switch packages.docker to IHP's built-in
unoptimized-docker-image which already uses the correct binary path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 23:16:44 +02:00
parent 718fe3782b
commit 9cbf4caadf
3 changed files with 46 additions and 26 deletions

View File

@@ -19,7 +19,7 @@ spec:
{{- if .Values.runMigrations }}
- name: migrate
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
command: ["/bin/App", "migrate"]
command: ["/bin/RunProdServer", "migrate"]
envFrom:
- secretRef:
name: {{ .Values.envFrom.secretRef }}

View File

@@ -49,7 +49,7 @@ IHP migrations run automatically on startup via the init container in the Deploy
To run migrations manually:
```bash
kubectl exec -n inter-hub deploy/inter-hub -- /bin/App migrate
kubectl exec -n inter-hub deploy/inter-hub -- /bin/RunProdServer migrate
```
To check migration status:

View File

@@ -18,10 +18,46 @@
systems = import systems;
imports = [ ihp.flakeModules.default ];
perSystem = { pkgs, config, ... }: let
# IHP production binary — built by the ihp flake module as packages.default
appPkg = config.packages.default;
in {
# GHC 9.10.3 crash fix: Generated.Types imports 119 modules, pushing the
# combined interface-file read past a ~287 MB binary-deserialization limit.
# We patch the inter-hub-models derivation (after build-generated-code runs)
# to replace Generated.Types with a thin re-export of two split modules that
# are already maintained in build/Generated/TypesPart{1,2}.hs.
nixpkgs.overlays = [
(final: prev: {
haskellPackages = prev.haskellPackages.extend (hfinal: hprev:
if builtins.hasAttr "inter-hub-models" hprev then {
"inter-hub-models" = hprev."inter-hub-models".overrideAttrs (old: {
postUnpack = (old.postUnpack or "") + ''
cp ${./build/Generated/TypesPart1.hs} \
"$sourceRoot/build/Generated/TypesPart1.hs"
cp ${./build/Generated/TypesPart2.hs} \
"$sourceRoot/build/Generated/TypesPart2.hs"
printf '%s\n' \
'-- Split wrapper: GHC 9.10.3 interface-file overflow workaround.' \
'module Generated.Types (' \
' module Generated.TypesPart1,' \
' module Generated.TypesPart2' \
' ) where' \
'import Generated.TypesPart1' \
'import Generated.TypesPart2' \
> "$sourceRoot/build/Generated/Types.hs"
cabal_file=$(ls "$sourceRoot"/*.cabal | head -1)
awk '/Generated\.LearningInsightInclude/{
print
print " Generated.TypesPart1"
print " Generated.TypesPart2"
next
}{print}' "$cabal_file" > /tmp/patched-models.cabal
mv /tmp/patched-models.cabal "$cabal_file"
'';
});
} else {}
);
})
];
perSystem = { pkgs, config, ... }: {
ihp = {
appName = "inter-hub";
enable = true;
@@ -80,27 +116,11 @@
# static.makeBundling = true; # Set false if not using Makefile for CSS/JS bundling
};
# OCI container image for Kubernetes deployment (Railiance01)
# OCI container image for Kubernetes deployment (Railiance01).
# Build: nix build .#docker
# Push: skopeo copy docker-archive:result docker://92.205.130.254:32166/coulomb/inter-hub:TAG
packages.docker = pkgs.dockerTools.buildLayeredImage {
name = "inter-hub";
tag = "latest";
contents = with pkgs; [
appPkg # IHP binary + bundled static files + migrations
cacert # SSL certs for outbound HTTPS (Anthropic API)
bash # needed by IHP's production entrypoint scripts
coreutils
];
config = {
Cmd = [ "${appPkg}/bin/App" ];
ExposedPorts."8000/tcp" = {};
Env = [
"PORT=8000"
"IHP_ENV=Production"
];
};
};
# Push: skopeo copy docker-archive:result docker://92.205.130.254:32166/coulomb/inter-hub:SHA
# Uses IHP's built-in unoptimized image; binary is /bin/RunProdServer.
packages.docker = config.packages.unoptimized-docker-image;
# Custom configuration that will start with `devenv up`
devenv.shells.default = {