I am working on a FRP web app that runs Purescript on the front end and Haskell (Servant and Opaleye) on the back end talking to a PostgreSQL database.
Right now, PostgreSQL runs natively (I found a flake containing a set of shell scripts from the Elixir discourse that help me start, stop, setup, etc the database) but I can’t help but have the inkling that I’m going about this all wrong.
My instincts say that is far more advisable to do this as a Docker or OCI container (despite my Nixy aversion to those solutions). I don’t think I want to go the route of using postgresql as a NixOS service for the same portability/canonical instincts.
My instincts say that I should instead be creating an OCI image that spins up the database rather than running it natively. Is that true?
Can you point me to a canonical example or some documentation that would set me straight on this type of thing? Obviously I tend to do things using 100% Nix but this one has me a little confused since it feels wrong to use Nix for this type of thing.
Basically, I want my entire dev environment to be provisioned and spun up using that one Nix flake. I’m doing this to not only provision my dev environment anywhere but to also deploy this app easily when that time comes. If someone doesn’t mind steering me straight, I’d be incredibly thankful.
Bonus Issue I’ve been struggling with: My preferred Haskell build tool (IOG’s Haskell.nix) is very broken right now with the recent major changes to postgresql-libpq. I get lots of errors when I run ‘nix-develop’ in the build which refer to pkg-config not knowing where to find anything with the recent changes. I tried setting env variables in the shell hook but that really never worked. So, I just commented it out and use ‘cabal build’ at the moment until I can possibly fix that.
ps. I also have had similar issues with building Purescript with purs-nix and have abandoned it since the new version of spago was launched.
The developer experience that IHP provides, building on devenv, is pretty nice. They also integrate PostgreSQL, so there may be something you can cargo-cult there.
If you’re not only using nix but NixOS, I often find that, at least on single machine setups, their services shims (which set up systemd services) are enough. They run in a very stable manner, if you manage to avoid the footguns.
I have also written a small blogpost about building a haskell + nix project and deploying it on NixOS. It also uses Postgres. Maybe it’s helpful. (Admittedly the nix part is a bit short but if you have questions, feel free to ask) (+ the project is open source, I won’t link it for crawling reasons but you should be able to find it)
This is an example app associated with tutorial series to be finished. But basically, you can use services-flake to define your whole stack (postgres, etc.) in Nix and have the user run it using a single nix run command.
I got a pretty decent flake built for using PostgreSQL as a service. Now, I’m working on one that can declare and build all of the backend as a Docker container (since ociTools seems fairly far behind the functionality in dockerTools).
It would be really cool if the nix build could tell what environment it is being built for and do the appropriate thing for each. So, for example if it is being built on a non-NixOS machine, it would automatically provision all of that using Docker and containers instead. And if it being built on NixOS, it could automatically build everything inside of a nix microvm. That would be
Ps. I see you all over the place (GitHub, Nix, Haskell, Rust). Thanks for all that you do for Nix, Haskell, and Rust.
With IHP, by default you get a locally running postgres when running the dev server; the IHP starter script just automagically starts up postgres in the background when you type ./start and stops it on ctrl+c. I find this really convenient (having previously used wordpress and even mssql locally ) But in prod your app will look for an envvar with the connection string and it’s up to you to provision postgres however you want. This makes a lot of sense, since people may have very different requirements, IHP doesn’t assume you want fully managed or self-hosted or whatever. (You can of course run it this way in dev too.)