I just switched one of my systems over to NixOS from Arch and so far it seems interesting. One question I had is regarding the nix-shell. So I get the basic concept of it and that it allows creating a shell that has packages installed with that shell making ideal for dev environments. I’ve even seen talks where the suggest nix-shells over docker/podman, my question is how is persistent data (like databases) handled?
Nix shell basically just downloads the software (if it’s not already downloaded) and then modifies your PATH to include the new software.
Persistent data stay persistent.
Nix shell has one use case common with docker (local development), but other than that the solutions are not similar at all.
Services like databases that manage runtime information usually store that information in
/var
or your home directory as usual.In general Nix doesn’t manage persistent data. It will be stored in whatever location the tool writes it to.
nix-shell
is a very simple program. Basically it downloads/builds the package you have configured, then sets up environment variables likePATH
to include that package. It would be similar to downloading a pre-built tarball run running./foo
inside of that.For most built-in modules this will be
/var/lib/foo
for a servicefoo
. If you runnix-shell
the service will write data wherever it would normally write data on any other distribution.Okay, that’s good to know. I just wanted to make sure that if I had something like MariaDB or Postgres get installed with
nix-shell
that I wouldn’t lose everything thus having to set everything back up next time I start the shell again.No, you won’t lose anything. However do be aware that unless you specifically configure different data directories using the same DBMS in multiple projects will use the same underlying data files.
Typically this won’t be a problem, and you can just create different logical databases if necessary.
Okay, hopefully someone here can point out where I am going wrong with setting up my dev shell the way I want. I am currently using
direnv
andnix-direnv
to manage the dev shell, and I found this blog post which shows a way to start and stop MySQL/Mariadb but I am having some weird issues with it.Currently my flake looks like this:
{ description = "A basic flake with a shell"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; inputs.flake-utils.url = "github:numtide/flake-utils"; outputs = { nixpkgs, flake-utils, ... }@inputs: flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; in { devShells.default = pkgs.mkShell { packages = with pkgs; [ bashInteractive php ]; buildInputs = [ pkgs.mariadb ]; shellHook = '' export MYSQL_BASEDIR=${pkgs.mariadb} export MYSQL_HOME=$PWD/.direnv/mysql export MYSQL_DATADIR=$MYSQL_HOME/data export MYSQL_UNIX_PORT=$MYSQL_HOME/mysql.sock export MYSQL_PID_FILE=$MYSQL_HOME/mysql.pid alias mysql='mysql -u root' if [[ ! -d $MYSQL_HOME ]]; then mariadb-install-db --auth-root-authentication-method=normal \ --datadir="$MYSQL_DATADIR" --basedir="$MYSQL_BASEDIR" \ --pid-file="$MYSQL_PID_FILE" fi mariadbd --datadir=$MYSQL_DATADIR --pid-file=$MYSQL_PID_FILE \ --socket=$MYSQL_UNIX_PORT --tmpdir='/tmp' 2>/dev/null & MYSQL_PID=$! ''; }; }); }
When I run it like this
mariadbd
starts just fine, but doesn’t get backgrounded dispite the&
making that shell session useless which is not what I want as I have to spawn a second shell just to do anything.Even weirder is when I add the
finish()
function and the call totrap
like in the blog post thenmariadbd
doesn’t start (or starts and immedently gets killed).mariadb
doesn’t get backgrounded? Are you sure? Are you able to type commands and see their output? Also, what happens when puttingset -x
at the start of your shell hook? You should see the last line printed e.gMYSQL_PID=12345