Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 92 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,108 @@
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, flake-utils }:
outputs = { nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};

# Project-local MariaDB instance. Data lives in $MARIADB_HOME (.mariadb/ in the repo root).
# Database name, user and password are read from backend/.env, falling back to backend/.env.example.
db-start = pkgs.writeShellApplication {
name = "db-start";
runtimeInputs = [ pkgs.mariadb pkgs.util-linux ];
text = ''
env_file="$PROJECT_ROOT/backend/.env"
[ -f "$env_file" ] || env_file="$PROJECT_ROOT/backend/.env.example"
set -a
# shellcheck source=/dev/null
. "$env_file"
set +a
: "''${DB_NAME:?DB_NAME missing in $env_file}"
: "''${DB_USER:?DB_USER missing in $env_file}"
DB_PORT="''${DB_PORT:-3306}"
DB_PASSWORD="''${DB_PASSWORD:-}"
mkdir -p "$MARIADB_HOME"
if [ ! -d "$MARIADB_HOME/data/mysql" ]; then
echo "Initializing MariaDB data directory..."
mariadb-install-db \
--datadir="$MARIADB_HOME/data" \
--auth-root-authentication-method=socket \
> "$MARIADB_HOME/install.log" 2>&1
fi
if ! mariadb-admin ping >/dev/null 2>&1; then
setsid mariadbd \
--no-defaults \
--datadir="$MARIADB_HOME/data" \
--socket="$MYSQL_UNIX_PORT" \
--pid-file="$MARIADB_HOME/mariadb.pid" \
--log-error="$MARIADB_HOME/mariadb.log" \
--bind-address=127.0.0.1 \
--port="$DB_PORT" \
< /dev/null > /dev/null 2>&1 &
for _ in $(seq 1 30); do
mariadb-admin ping >/dev/null 2>&1 && break
sleep 0.5
done
if ! mariadb-admin ping >/dev/null 2>&1; then
echo "MariaDB failed to start, see $MARIADB_HOME/mariadb.log" >&2
exit 1
fi
fi
# Escape for use inside SQL identifiers/literals.
name="''${DB_NAME//\`/\`\`}"
user="''${DB_USER//\'/\\\'}"
pass="''${DB_PASSWORD//\'/\\\'}"
mariadb <<SQL
CREATE DATABASE IF NOT EXISTS \`$name\`;
CREATE USER IF NOT EXISTS '$user'@'localhost' IDENTIFIED BY '$pass';
CREATE USER IF NOT EXISTS '$user'@'127.0.0.1' IDENTIFIED BY '$pass';
ALTER USER '$user'@'localhost' IDENTIFIED BY '$pass';
ALTER USER '$user'@'127.0.0.1' IDENTIFIED BY '$pass';
GRANT ALL PRIVILEGES ON \`$name\`.* TO '$user'@'localhost';
GRANT ALL PRIVILEGES ON \`$name\`.* TO '$user'@'127.0.0.1';
SQL
echo "MariaDB running on 127.0.0.1:$DB_PORT with database '$DB_NAME' and user '$DB_USER' (from $env_file)."
'';
};

db-stop = pkgs.writeShellApplication {
name = "db-stop";
runtimeInputs = [ pkgs.mariadb ];
text = ''
if mariadb-admin shutdown 2>/dev/null; then
echo "MariaDB stopped."
else
echo "MariaDB is not running."
fi
'';
};
in
{
devShells.default = pkgs.mkShell {
packages = with pkgs; [
nodejs_24
packages = [
pkgs.nodejs_24
pkgs.mariadb
db-start
db-stop
];

shellHook = ''
export PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
export MARIADB_HOME="$PROJECT_ROOT/.mariadb"
# Picked up by the mariadb client tools, so they connect to the local instance by default.
export MYSQL_UNIX_PORT="$MARIADB_HOME/mysqld.sock"
echo "Node $(node -v) & npm $(npm -v) ready."
db-start || echo "Could not start MariaDB, see $MARIADB_HOME/mariadb.log"
echo "MariaDB keeps running after you leave the shell; run 'db-stop' to stop it."
'';
};
});
Expand Down