diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Changelog for sandwich-contexts
 
+## 0.3.0.4
+
+* Use the latest process file logging and managed asyncs from `sandwich`.
+* Use a more modern `fake-smtp-server` derivation.
+* Bump `nixpkgsMaster` (now has Chrome 138).
+* Fix a typo in `introduceBinaryViaNixPackage`.
+
 ## 0.3.0.3
 
 * Use --no-link in Nix builds to avoid unnecessary result symlinks.
diff --git a/lib/Test/Sandwich/Contexts/Container.hs b/lib/Test/Sandwich/Contexts/Container.hs
--- a/lib/Test/Sandwich/Contexts/Container.hs
+++ b/lib/Test/Sandwich/Contexts/Container.hs
@@ -6,10 +6,10 @@
 -}
 
 module Test.Sandwich.Contexts.Container (
-  ContainerOptions (..)
+  ContainerOptions(..)
   , defaultContainerOptions
 
-  , ContainerSystem (..)
+  , ContainerSystem(..)
   , waitForHealth
 
   -- * Container/host conversions
diff --git a/lib/Test/Sandwich/Contexts/FakeSmtpServer.hs b/lib/Test/Sandwich/Contexts/FakeSmtpServer.hs
--- a/lib/Test/Sandwich/Contexts/FakeSmtpServer.hs
+++ b/lib/Test/Sandwich/Contexts/FakeSmtpServer.hs
@@ -54,6 +54,7 @@
 import Test.Sandwich.Contexts.HttpWaits
 import Test.Sandwich.Contexts.Nix
 import Test.Sandwich.Contexts.Util.Aeson
+import UnliftIO.Async
 import UnliftIO.Directory
 import UnliftIO.Exception
 
@@ -178,8 +179,9 @@
                                            create_group = True
                                            })
           )
-          (\p -> do
-              void $ liftIO (interruptProcessGroupOf p >> waitForProcess p)
+          (\(p, asy) -> do
+              finally (void $ liftIO (interruptProcessGroupOf p >> waitForProcess p))
+                      (cancel asy)
           )
           (\_ -> do
               let hostname = "localhost"
diff --git a/lib/Test/Sandwich/Contexts/FakeSmtpServer/Derivation.hs b/lib/Test/Sandwich/Contexts/FakeSmtpServer/Derivation.hs
--- a/lib/Test/Sandwich/Contexts/FakeSmtpServer/Derivation.hs
+++ b/lib/Test/Sandwich/Contexts/FakeSmtpServer/Derivation.hs
@@ -13,38 +13,23 @@
 fakeSmtpServerDerivation = [i|
 { callPackage
 , fetchFromGitHub
-, node2nix
-, nodejs_18
+, buildNpmPackage
 , stdenv
 }:
 
-let
-
-  nixified = stdenv.mkDerivation {
-    pname = "fake-smtp-server";
-    version = "0.8.1";
-
-    src = fetchFromGitHub {
-      owner = "codedownio";
-      repo = "fake-smtp-server";
-      rev = "1adbffb35d6c90bcb2ad9fac3049fa2028a34d2f";
-      sha256 = "sha256-zXaNM7sp2c3IEvmoZ81M+7LrcC1I0JhlqG0A+gOA38E=";
-    };
-
-    dontConfigure = true;
-
-    buildInputs = [node2nix];
-
-    buildPhase = ''
-      node2nix -- --nodejs-18 --lock package-lock.json
-    '';
+buildNpmPackage rec {
+  pname = "fake-smtp-server";
+  version = "0.8.1";
 
-    installPhase = ''
-      cp -r ./. $out
-    '';
+  src = fetchFromGitHub {
+    owner = "codedownio";
+    repo = "fake-smtp-server";
+    rev = "1adbffb35d6c90bcb2ad9fac3049fa2028a34d2f";
+    sha256 = "sha256-zXaNM7sp2c3IEvmoZ81M+7LrcC1I0JhlqG0A+gOA38E=";
   };
 
-in
+  npmDepsHash = "sha256-CffyLKMJ4OYGFxxnaM4bFbu2OReekpKr2dTCSo8/Ei8=";
 
-(callPackage nixified { nodejs = nodejs_18; }).package
+  dontNpmBuild = true;
+}
 |]
diff --git a/lib/Test/Sandwich/Contexts/Files.hs b/lib/Test/Sandwich/Contexts/Files.hs
--- a/lib/Test/Sandwich/Contexts/Files.hs
+++ b/lib/Test/Sandwich/Contexts/Files.hs
@@ -230,7 +230,7 @@
   -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.
   -- For example, you can use the "hello" binary from the "hello" package like this:
   --
-  -- introduceBinaryViaNixPackage' @"hello" "hello"
+  -- introduceBinaryViaNixPackage @"hello" "hello"
   => NixPackageName
   -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()
   -> SpecFree context m ()
diff --git a/lib/Test/Sandwich/Contexts/Nix.hs b/lib/Test/Sandwich/Contexts/Nix.hs
--- a/lib/Test/Sandwich/Contexts/Nix.hs
+++ b/lib/Test/Sandwich/Contexts/Nix.hs
@@ -83,7 +83,7 @@
 import Test.Sandwich.Contexts.Files.Types
 import Test.Sandwich.Contexts.Util.Aeson
 import qualified Text.Show
-import UnliftIO.Async
+import UnliftIO.Async (Async, wait)
 import UnliftIO.Directory
 import UnliftIO.Environment
 import UnliftIO.MVar (modifyMVar)
@@ -101,7 +101,7 @@
   , nixContextBuildCache :: MVar (Map Text (Async FilePath))
   }
 instance Show NixContext where
-  show (NixContext {}) = "<NixContext>"
+  show (NixContext {..}) = [i|NixContext<#{nixContextNixBinary}, #{nixContextNixpkgsDerivation}>|]
 
 type HasNixContext context = HasLabel context "nixContext" NixContext
 
@@ -125,15 +125,15 @@
     , nixpkgsDerivationAllowUnfree :: Bool
     } deriving (Show, Eq)
 
--- | Nixpkgs master, accessed 6\/6\/2025.
+-- | Nixpkgs master, accessed 6\/28\/2025.
 -- You can compute updated values for this release (or others) by running
 -- nix-prefetch-github NixOS nixpkgs --rev master
 nixpkgsMaster :: NixpkgsDerivation
 nixpkgsMaster = NixpkgsDerivationFetchFromGitHub {
   nixpkgsDerivationOwner = "NixOS"
   , nixpkgsDerivationRepo = "nixpkgs"
-  , nixpkgsDerivationRev = "067a39e41a125985e061199452c900b0305f4c42"
-  , nixpkgsDerivationSha256 = "sha256-N57WqGFUUDJ7QVR4YPRttp4YuTA4oN/KdXHY4OEXGFk="
+  , nixpkgsDerivationRev = "40a8fd31ccc6d87eff8e8aae833d213b10bb9f50"
+  , nixpkgsDerivationSha256 = "sha256-HXlk/16dnoQqy2wjizF1uA7b1gNS8iYFq7vSAG2P8dk="
   , nixpkgsDerivationAllowUnfree = False
   }
 
@@ -144,8 +144,8 @@
 nixpkgsRelease2505 = NixpkgsDerivationFetchFromGitHub {
   nixpkgsDerivationOwner = "NixOS"
   , nixpkgsDerivationRepo = "nixpkgs"
-  , nixpkgsDerivationRev = "8217c6edf391991f07ecacf3d31ba6eb01d733b1"
-  , nixpkgsDerivationSha256 = "sha256-aaeXPG9zVvi+aKTp0dMUYOeMuhDXQejRPh2CfK23nf8="
+  , nixpkgsDerivationRev = "e56210760332660c9c6456d0db9bf0dbfe330fa9"
+  , nixpkgsDerivationSha256 = "sha256-KGnvMRwjxD2z65x8ECA2WA9pfmnDCu2xo5Ltm/QTSGs="
   , nixpkgsDerivationAllowUnfree = False
   }
 
@@ -185,9 +185,9 @@
   , nixpkgsDerivationAllowUnfree = False
   }
 
--- | Currently set to 'nixpkgsRelease2405'.
+-- | Currently set to 'nixpkgsRelease2505'.
 nixpkgsReleaseDefault :: NixpkgsDerivation
-nixpkgsReleaseDefault = nixpkgsRelease2405
+nixpkgsReleaseDefault = nixpkgsRelease2505
 
 -- | Introduce a 'NixContext', which contains information about where to find Nix and what
 -- version of Nixpkgs to use. This can be leveraged to introduce Nix packages in tests.
@@ -359,7 +359,7 @@
     case M.lookup derivation m of
       Just x -> return (m, x)
       Nothing -> do
-        asy <- async $ do
+        asy <- managedAsync "nix-build-call-package" $ do
           maybeNixExpressionDir <- getCurrentFolder >>= \case
             Just dir -> (Just <$>) $ liftIO $ createTempDirectory dir "nix-expression"
             Nothing -> return Nothing
@@ -399,7 +399,7 @@
     case M.lookup expr m of
       Just x -> return (m, x)
       Nothing -> do
-        asy <- async $ do
+        asy <- managedAsync "nix-build-expression" $ do
           maybeNixExpressionDir <- getCurrentFolder >>= \case
             Just dir -> (Just <$>) $ liftIO $ createTempDirectory dir "nix-expression"
             Nothing -> pure Nothing
@@ -413,7 +413,7 @@
 --   nc <- getContext nixContext
 --   runNixBuild' nc expr outputPath
 
-runNixBuild' :: (MonadUnliftIO m, MonadLogger m) => NixContext -> Text -> Maybe String -> m String
+runNixBuild' :: (MonadUnliftIO m, MonadLogger m, HasBaseContextMonad context m) => NixContext -> Text -> Maybe String -> m String
 runNixBuild' (NixContext {nixContextNixpkgsDerivation}) expr maybeOutputPath = do
   maybeEnv <- case nixpkgsDerivationAllowUnfree nixContextNixpkgsDerivation of
     False -> pure Nothing
diff --git a/lib/Test/Sandwich/Contexts/PostgreSQL.hs b/lib/Test/Sandwich/Contexts/PostgreSQL.hs
--- a/lib/Test/Sandwich/Contexts/PostgreSQL.hs
+++ b/lib/Test/Sandwich/Contexts/PostgreSQL.hs
@@ -69,6 +69,7 @@
 import Test.Sandwich.Contexts.Types.Network
 import Test.Sandwich.Contexts.UnixSocketPath
 import Test.Sandwich.Contexts.Util.UUID (makeUUID)
+import UnliftIO.Async
 import UnliftIO.Directory
 import UnliftIO.Environment
 import UnliftIO.Exception
@@ -261,15 +262,17 @@
         withTempFile baseDir "pwfile" $ \pwfile h -> do
           liftIO $ T.hPutStrLn h password
           hClose h
-          createProcessWithLogging ((proc (postgresBinDir </> "initdb") [dbDirName
-                                                                          , "--username", toString username
-                                                                          , "-A", "md5"
-                                                                          , "--pwfile", pwfile
-                                                                          ]) {
-                                       cwd = Just dir
-                                       , env = Just env
-                                       })
-            >>= waitForProcess >>= (`shouldBe` ExitSuccess)
+          (ps, asy) <- createProcessWithLogging (
+            (proc (postgresBinDir </> "initdb") [dbDirName
+                                                , "--username", toString username
+                                                , "-A", "md5"
+                                                , "--pwfile", pwfile
+                                                ]) {
+                cwd = Just dir
+                , env = Just env
+                })
+          finally (waitForProcess ps >>= (`shouldBe` ExitSuccess))
+                  (cancel asy)
 
         -- Turn off the TCP interface; we'll have it listen solely on a Unix socket
         withFile (dir </> dbDirName </> "postgresql.conf") AppendMode $ \h -> liftIO $ do
@@ -287,7 +290,8 @@
                                       , "-o", [i|--unix_socket_directories='#{unixSockDir}'|]
                                       , "start" , "--wait"
                                       ]) { cwd = Just dir })
-          >>= waitForProcess >>= (`shouldBe` ExitSuccess)
+          >>= \(ps, asy) -> finally (waitForProcess ps >>= (`shouldBe` ExitSuccess))
+                                    (cancel asy)
 
         -- Create the default db
         createProcessWithLogging ((proc (postgresBinDir </> "psql") [
@@ -296,7 +300,8 @@
                                       [i|postgresql://#{username}:#{password}@/?host=#{unixSockDir}|]
                                       , "-c", [i|CREATE DATABASE #{database};|]
                                       ]) { cwd = Just dir })
-          >>= waitForProcess >>= (`shouldBe` ExitSuccess)
+          >>= \(ps, asy) -> finally (waitForProcess ps >>= (`shouldBe` ExitSuccess))
+                                    (cancel asy)
 
 
         files <- listDirectory unixSockDir
@@ -356,17 +361,18 @@
   -> m a
 withPostgresContainer options action = do
   bracket (createPostgresDatabase options)
-          (\(containerName, _p) -> timeAction "cleanup Postgres database" $ do
-              info [i|Doing #{postgresContainerContainerSystem options} rm -f --volumes #{containerName}|]
-              (exitCode, sout, serr) <-  liftIO $ readCreateProcessWithExitCode (shell [i|#{postgresContainerContainerSystem options} rm -f --volumes #{containerName}|]) ""
-              when (exitCode /= ExitSuccess) $
-                expectationFailure [i|Failed to destroy Postgres container. Stdout: '#{sout}'. Stderr: '#{serr}'|]
+          (\(containerName, _p, asy) -> timeAction "cleanup Postgres database" $ do
+              flip finally (cancel asy) $ do
+                info [i|Doing #{postgresContainerContainerSystem options} rm -f --volumes #{containerName}|]
+                (exitCode, sout, serr) <-  liftIO $ readCreateProcessWithExitCode (shell [i|#{postgresContainerContainerSystem options} rm -f --volumes #{containerName}|]) ""
+                when (exitCode /= ExitSuccess) $
+                  expectationFailure [i|Failed to destroy Postgres container. Stdout: '#{sout}'. Stderr: '#{serr}'|]
           )
           (waitForPostgresDatabase options >=> action)
 
 createPostgresDatabase :: (
   HasCallStack, MonadUnliftIO m, MonadLogger m, HasBaseContextMonad context m
-  ) => PostgresContainerOptions -> m (Text, ProcessHandle)
+  ) => PostgresContainerOptions -> m (Text, ProcessHandle, Async ())
 createPostgresDatabase (PostgresContainerOptions {..}) = timeAction "create Postgres database" $ do
   containerName <- maybe (("postgres-" <>) <$> makeUUID) return postgresContainerContainerName
 
@@ -386,13 +392,13 @@
 
   info [i|cmd: #{containerSystem} #{T.unwords args}|]
 
-  p <- createProcessWithLogging (proc (show containerSystem) (fmap toString args))
-  return (containerName, p)
+  (p, asy) <- createProcessWithLogging (proc (show containerSystem) (fmap toString args))
+  return (containerName, p, asy)
 
 waitForPostgresDatabase :: (
   MonadUnliftIO m, MonadLoggerIO m, MonadMask m
-  ) => PostgresContainerOptions -> (Text, ProcessHandle) -> m PostgresContext
-waitForPostgresDatabase (PostgresContainerOptions {..}) (containerName, p) = do
+  ) => PostgresContainerOptions -> (Text, ProcessHandle, Async ()) -> m PostgresContext
+waitForPostgresDatabase (PostgresContainerOptions {..}) (containerName, p, _) = do
   containerID <- waitForProcess p >>= \case
     ExitSuccess -> containerNameToContainerId postgresContainerContainerSystem containerName
     _ -> expectationFailure [i|Failed to start Postgres container.|]
diff --git a/lib/Test/Sandwich/Contexts/ReverseProxy/TCP.hs b/lib/Test/Sandwich/Contexts/ReverseProxy/TCP.hs
--- a/lib/Test/Sandwich/Contexts/ReverseProxy/TCP.hs
+++ b/lib/Test/Sandwich/Contexts/ReverseProxy/TCP.hs
@@ -14,13 +14,13 @@
 import Data.String.Interpolate
 import Network.Socket
 import Relude
-import Test.Sandwich (expectationFailure)
-import UnliftIO.Async
+import Test.Sandwich (expectationFailure, HasBaseContextMonad, managedWithAsync_)
+import UnliftIO.Async (concurrently_)
 import UnliftIO.Exception
 import UnliftIO.Timeout
 
 
-withProxyToUnixSocket :: MonadUnliftIO m => FilePath -> (PortNumber -> m a) -> m a
+withProxyToUnixSocket :: (MonadUnliftIO m, HasBaseContextMonad context m) => FilePath -> (PortNumber -> m a) -> m a
 withProxyToUnixSocket socketPath f = do
   portVar <- newEmptyMVar
   let ss = DCN.serverSettings 0 "*"
@@ -30,7 +30,7 @@
                SockAddrInet6 port _ _ _ -> putMVar portVar port
                x -> expectationFailure [i|withProxyToUnixSocket: expected to bind a TCP socket, but got other addr: #{x}|]
            )
-  withAsync (liftIO $ DCN.runTCPServer ss app `onException` (tryPutMVar portVar (-1))) $ \_ ->
+  managedWithAsync_ "tcp-reverse-proxy" (liftIO $ DCN.runTCPServer ss app `onException` (tryPutMVar portVar (-1))) $
     timeout 60_000_000 (readMVar portVar) >>= \case
       Nothing -> expectationFailure [i|withProxyToUnixSocket: didn't get port within 60s|]
       Just (-1) -> expectationFailure [i|withProxyToUnixSocket: TCP server threw exception|]
diff --git a/sandwich-contexts.cabal b/sandwich-contexts.cabal
--- a/sandwich-contexts.cabal
+++ b/sandwich-contexts.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.38.0.
+-- This file has been generated from package.yaml by hpack version 0.38.1.
 --
 -- see: https://github.com/sol/hpack
 
 name:           sandwich-contexts
-version:        0.3.0.3
+version:        0.3.0.4
 synopsis:       Contexts for the Sandwich test library
 description:    Please see the <https://codedownio.github.io/sandwich documentation>.
 author:         Tom McLaughlin
@@ -74,7 +74,7 @@
     , relude
     , retry
     , safe
-    , sandwich >=0.3.0.0
+    , sandwich >=0.3.1.0
     , streaming-commons >=0.2.3.0
     , string-interpolate
     , temporary
@@ -115,10 +115,12 @@
   build-depends:
       base >=4.11 && <5
     , filepath
-    , postgresql-simple
     , relude
-    , sandwich >=0.3.0.0
+    , sandwich >=0.3.1.0
     , sandwich-contexts
     , string-interpolate
     , unliftio
   default-language: Haskell2010
+  if !os(windows)
+    build-depends:
+        postgresql-simple
