Recipes
Common pitfalls
Small problems that are easy to hit, and what to do instead. Each one came up while we wrote and tested these recipes.
Installs and files
- Installing packages on your machine for containers.
npm installorbun installon macOS (or on a different Linux) installs binaries for that platform, and a Linux container cannot load them. Install inside the container with a deps service. - Workspace packages write their own
node_modules. Bun and pnpm write anode_modulesfolder into each workspace package. Give each one a named volume, or the container writes it into your checkout. See Monorepos and workspaces. - A locked install does not repair a damaged one.
bun install --frozen-lockfilecan reportno changesover a broken package. Use--force, or remove the volume. See Recover a stale or half-written volume. - Root-owned files on Linux. With Docker Engine on Linux, files a container
writes into your checkout belong to root. That includes lockfiles changed by
hack run deps ...and the emptynode_modulesmount points Docker creates. Fix ownership withsudo chown "$(id -u):$(id -g)" <file>. Running the service as your user instead also changes who owns its volumes, so the installer may no longer be able to write them. - The shared cache label does nothing without a platform. If you see
Shared dependency cache disabled, setplatformon thedepsservice orDOCKER_DEFAULT_PLATFORMin your shell.
Env
- Editing an env file does not change running containers. Run
hack restart, orhack env apply --service <name>. hack execneeds the same--envashack up.hack restartandhack downreuse the overlay the stack started with;hack execrefuses a different one, and no--envmeans the default overlay.- A hook cannot change this start's env. Hack resolves managed env before
up.beforehooks run. A value a hook stores withhack env addreaches containers on the next start. See Sign in to another CLI. - Your shell expands
$VARbefore Hack sees it. Inhack run app echo "$APP_ENV", the variable comes from your shell, not from Hack. Usehack run app sh -c 'echo "$APP_ENV"', orhack host exec --shell '...'on your machine. - Secrets in command arguments. A token or a connection string with a
password, passed as an argument (
--token "$TOKEN",psql "$DATABASE_URL"), shows up in process listings. Let the tool read it from the environment Hack injects, or from a file. - Compose expands
$in the Compose file. To use a container variable in acommand, write$$VAR. - Keep
.hack/hack.env.default.yaml, even when it is empty. Without it,hack doctorwarns about a missing env file.hack initcreates it.
Networking
localhostin a container is the container. Use the Compose service name (db,queue) between containers.- Reaching your machine from a container on Linux. Add
extra_hosts: ["host.docker.internal:host-gateway"], make the host process listen on the Docker bridge address instead of127.0.0.1, and allow it in your firewall. See Remote database. - Publishing ports to your whole network. Write
"127.0.0.1:5432:5432", not"5432:5432", unless other machines must connect. - Routed services need the
hack-devnetwork. Services with Caddy labels join the externalhack-devnetwork, whichhack global installcreates. Without it,hack upfails. - Global-setup notices in command output. Until the global proxy is
installed,
hack runandhack execprint notices such asCoreDNS is not reachableon stdout, before the command's own output. Filter them out before you parse the output.
Lifecycle
- Lifecycle processes need tmux. Hack runs them in a tmux (or zellij) session. Install tmux first.
- A failing
up.afterhook leaves containers running.hack upreports the failure; runhack downif you want them stopped. - Quick tunnel URLs change on every start. Use a named tunnel for OAuth callbacks. See Tunnels.
Data and cleanup
hack downkeeps volumes. Your database survives. To start from an empty database, remove its volume. See Cleanup.- Deleting a worktree does not stop its containers. Run
hack downin the worktree first. See Cleanup. - An overlay name is not isolation.
--env prodlikestill runs on your machine, in the same instance. Use--branchfor a separate instance.