jam-cloud/web/flake.nix

136 lines
4.3 KiB
Nix

{
description = "SOTA Rails 8 Native Environment & OCI Image for JamKazam Web";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
let
supportedSystems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
in {
# Track 1: The Native Inner Loop (for 8GB RAM Macs)
devShells = forAllSystems (system: {
default = let pkgs = import nixpkgs { inherit system; }; in
pkgs.mkShell {
buildInputs = with pkgs; [
ruby_3_4
postgresql_16.lib
jemalloc
libyaml
vips
bun
git
libxml2
libxslt
pkg-config
];
shellHook = ''
export RUBY_YJIT_ENABLE=1
export RAILS_ENV=development
# macOS uses .dylib, Linux uses .so
if [ "$(uname)" = "Darwin" ]; then
export LD_PRELOAD="${pkgs.jemalloc}/lib/libjemalloc.dylib"
else
export LD_PRELOAD="${pkgs.jemalloc}/lib/libjemalloc.so"
fi
echo "🚀 SOTA Web Shell Ready (YJIT + jemalloc enabled)"
'';
};
});
# Track 2: The Production OCI Image
packages = forAllSystems (system:
let
pkgs = import nixpkgs { inherit system; };
# 1. Define the Ruby Environment with common native gems pre-installed
rubyEnv = pkgs.ruby_3_4.withPackages (ps: with ps; [
psych
pg
nokogiri
]);
# 2. Join dev and lib outputs for common dependencies
libyaml-joined = pkgs.symlinkJoin { name = "libyaml-joined"; paths = [ pkgs.libyaml pkgs.libyaml.dev ]; };
openssl-joined = pkgs.symlinkJoin { name = "openssl-joined"; paths = [ pkgs.openssl pkgs.openssl.dev ]; };
postgres-joined = pkgs.symlinkJoin { name = "postgres-joined"; paths = [ pkgs.postgresql_16 pkgs.postgresql_16.lib ]; };
# 3. Aggregate all dependencies into a single environment
allDeps = pkgs.buildEnv {
name = "jam-web-env";
paths = with pkgs; [
rubyEnv
postgres-joined
libyaml-joined
openssl-joined
zlib.dev
zlib
libiconv
libxml2
libxml2.dev
libxslt
libxslt.dev
jemalloc
vips
bash
coreutils
git
gnumake
gcc
pkg-config
binutils
];
};
# 4. A startup script
start-jam-web = pkgs.writeShellScriptBin "start-jam-web" ''
export PATH=${allDeps}/bin:$PATH
export LD_LIBRARY_PATH=${allDeps}/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=${allDeps}/lib/pkgconfig
cd /jam-cloud/web
echo "🔧 Configuring bundler for native extensions..."
bundle config build.psych --with-yaml-dir=${libyaml-joined}
bundle config build.pg --with-pg-config=${postgres-joined}/bin/pg_config
echo "💎 Installing gems..."
bundle install
echo "🚀 Starting Rails..."
exec bundle exec rails server -b 0.0.0.0
'';
appImage = pkgs.dockerTools.buildLayeredImage {
name = "jamkazam-web";
tag = "local";
config = {
Cmd = [ "${start-jam-web}/bin/start-jam-web" ];
Env = [
"RUBY_YJIT_ENABLE=1"
"LD_PRELOAD=${pkgs.jemalloc}/lib/libjemalloc.so"
"RAILS_ENV=production"
"RAILS_SERVE_STATIC_FILES=true"
"PKG_CONFIG_PATH=${allDeps}/lib/pkgconfig"
];
ExposedPorts = { "3000/tcp" = {}; };
};
contents = [
allDeps
start-jam-web
pkgs.libyaml.dev
pkgs.openssl.dev
pkgs.postgresql_16.lib
pkgs.zlib.dev
];
};
in {
inherit appImage;
appImageTarball = appImage;
}
);
};
}