{ config, pkgs, ... }: let # (Optional) name your Compose app’s directory on the VM: composeDir = "/etc/docker-compose-app"; in { # 1) Install Docker engine and Docker‐Compose binary: environment.systemPackages = with pkgs; [ docker docker-compose # pulls in the python-based compose ]; # 2) Enable the Docker daemon: services.docker.enable = true; # 3) Create a directory for your Compose file and copy it from the flake: # If your flake repo has a sibling file `docker-compose.yml`, this will drop # it into /etc/docker-compose-app/docker-compose.yml on the VM. environment.etc."docker-compose-app/docker-compose.yml".text = builtins.readFile ./docker-compose.yml; # 4) Make sure that directory exists with the right permissions: systemd.tmpfiles.rules = [ # D = create directory if missing, mode 0755, owner root:root "D! /etc/docker-compose-app 0755 root root - -" ]; # 5) Define a systemd service to run `docker-compose up`: systemd.services.dockerComposeApp = { description = "docker-compose stack for my application"; after = [ "network-online.target" "docker.service" ]; wants = [ "network-online.target" "docker.service" ]; serviceConfig = { # Run in foreground but let systemd restart if it crashes ExecStart = "${pkgs.docker-compose}/bin/docker-compose -f ${composeDir}/docker-compose.yml up"; ExecStop = "${pkgs.docker-compose}/bin/docker-compose -f ${composeDir}/docker-compose.yml down"; WorkingDirectory = composeDir; Restart = "always"; RestartSec = 10; }; # Make sure the directory exists before this service starts: preStart = '' mkdir -p ${composeDir} chown root:root ${composeDir} ''; wantedBy = [ "multi-user.target" ]; }; # 6) (Optional) If any volumes need to exist, define them here, for example: # environment.etc."docker-compose-app/data".source = "/path/to/local/data"; }