Uninstall
Removing a project, and the four things that survive deleting its directory — with the exact names, and the two list commands that lie to you.
There is no evestack uninstall. evestack --help lists seven commands and none of them
removes anything. Nothing here is automated, and that is the honest state of it rather than a
design position — this page exists because removal was undocumented and the evidence was five
orphaned Postgres volumes on one development machine, four of them belonging to projects whose
directories no longer existed.
Everything below destroys data and does not ask twice. docker compose down -v deletes the
Postgres volume: every session, every trace, every memory, every approval record and every
schedule in that project, gone, with no undo and no backup taken for you.
What removal actually involves
A project is not installed anywhere. It is a directory, plus things Docker holds on its behalf, plus caches that belong to other tools. Deleting the directory removes the first of those and none of the rest.
| Thing | Who owns it | Removed by deleting the project directory? | Measured size |
|---|---|---|---|
the project directory (node_modules, .eve/, your agent code) | you | yes | ~300 MB, mostly node_modules |
the <project>_evestack-pgdata volume | Docker | no | 68–78 MB light, 147.2 MB measured on a busy one |
ghcr.io/sammytourani/evestack-dashboard:<tag> | Docker | no | 1.05 GB unpacked |
pgvector/pgvector:pg17 | Docker | no | 646 MB |
| the eve base image | Docker | no | 665 MB |
eve-sandbox-template:<hash>, one per project | Docker | no | 665 MB apparent, ~66 kB unique per extra one |
| session sandbox containers | Docker | no | ~20 kB writable layer each, but they persist |
~/.npm/_npx | npm | no | 99 MB when this was written; 2.2 GB on the same machine later |
Ollama models (qwen3, nomic-embed-text) | Ollama | no | several GB |
The last two are not evestack's to delete and are named here only because nothing else names them as a consequence of having run evestack.
Read that last column as an order of magnitude, not as your machine. Every figure in it was
measured, but three of them move: the volume grows with your sessions, ~/.npm/_npx grows with
every npx invocation of anything, and the dashboard image changes size per tag. The commands in
each section below print the real number for your machine, which is the one to act on.
The sandbox-template row is the one worth reading carefully, because docker images reports it
misleadingly. Each eve-sandbox-template shows a 665 MB size, but that is almost entirely
layers shared with the eve base image; docker system df -v breaks the two apart, and the
UNIQUE SIZE column is what you actually get back:
REPOSITORY SIZE SHARED SIZE UNIQUE SIZE
eve-sandbox-template 665MB 665.3MB 65.77kB
eve-sandbox-template 665MB 665.3MB 65.77kB
ghcr.io/vercel/eve 665MB 665.3MB 33.42kBSo removing three orphaned sandbox templates recovers about 200 kB, not 2 GB. Removing the eve base image underneath them is where the 665 MB is — and nothing does that while a sandbox template still references those layers.
Two list commands that lie, and the rule that follows
docker ps --filter name=X and docker volume ls --filter name=X are substring matches, not
equality. --filter name=agent matches my-agent, agent-2, and a container called
payments-agent-prod that belongs to something else entirely.
This is not theoretical here: a bulk delete driven by one of those filters destroyed a live container in this project's own history. The data was recoverable; it should not have had to be.
So every removal on this page is two steps, and the first one is a list. Read the whole
output, decide with your eyes, then remove by exact name. Do not pipe a --filter name= result
into rm, rmi or docker rm, in a script or otherwise.
1. Take one project down, from inside it
Do this before you delete the directory. The compose file is the only thing that knows the project's Compose identity, and once it is gone Docker will not associate the leftovers with it — that is what produced the four orphans.
First: which compose file is this? Everything below runs docker compose with no -f, which
means whatever docker-compose.yml is in the directory. In a project from evestack create
that is evestack's file and this is correct. In a project from evestack attach it may not
be: when the project already had a docker-compose.yml of its own, attach refuses to overwrite
it and writes docker-compose.evestack.yml beside it instead. Bare docker compose there
reads their file, resolves their project name, and down -v deletes their volumes.
Measured, in a directory holding both files:
$ docker compose --profile dashboard config --volumes
their-precious-dataNot one evestack resource in the answer. So look before anything else:
ls docker-compose*.ymlIf docker-compose.evestack.yml is there, add -f docker-compose.evestack.yml to every
docker compose command on this page, and read attach's own dashboard
below — an attached project's dashboard is not a Compose service at all.
cd ~/my-agent
# The project name and the real volume name, both as Docker stores them.
# `config --volumes` alone prints `evestack-pgdata`, which is the key inside the
# file and is the same string in every evestack project — not a name you can act on.
docker compose --profile dashboard config --format json \
| node -p "const c=JSON.parse(require('fs').readFileSync(0,'utf8')); \
c.name + '\n' + Object.keys(c.volumes||{}).map(v => ' ' + c.name + '_' + v).join('\n')"
# and the containers, named exactly
docker compose --profile dashboard ps -aRead both. The volume name that command prints is the one — and the only one — that the rest of this page is about.
Then, keeping the data:
# containers and network go; the Postgres volume stays
docker compose --profile dashboard down --remove-orphansOr destroying it:
# the same, plus the volume — every session, trace, memory, approval and schedule
docker compose --profile dashboard down -v --remove-orphans--profile dashboard matters, and it is not optional. Without it Compose does not consider the
dashboard service part of this run and its container is left behind — and --remove-orphans
does not catch it, because Compose knows that service, it just filtered it out. Measured on
Compose v5.1.0, against a two-service project whose second service is profile-gated:
$ docker compose down --remove-orphans
Network probe_default Removing
Network probe_default Resource is still in use
$ docker ps -a --format '{{.Names}}'
probe-dashboard-1The container survives, the network cannot be removed because the container is still attached to
it, and nothing said the word "orphan". Re-run the same command with --profile dashboard and
both go.
The attached dashboard is not a Compose service
evestack attach writes a compose file for Postgres only. Its dashboard is started by the
docker run command attach prints, so no docker compose down of any kind touches it — it is
not in the file, it carries no Compose project label, and it will still be there after the
compose project is gone.
It is named after the same Compose project name the volume is, with -dashboard on the end, so
you can find it exactly:
# list first — read the name, then use the name you read
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' | grep -- -dashboard
docker rm -f <the-name-you-just-read>Finally the directory:
rm -rf ~/my-agent.env and .env.local in there hold a generated Postgres password, a dashboard sign-in
password and a trace-ingest token, all at mode 0600. rm -rf is enough — none of them is
registered anywhere else — but if you keep a backup of the directory, those three secrets are in
it.
2. If the directory is already gone
The volume name is the only surviving reference, and it is derived rather than random:
<compose project name>_evestack-pgdatawhere the Compose project name is the directory's basename, slugged, plus the first six hex
characters of the SHA-256 of the directory's absolute path. The path is in there deliberately —
two projects both called my-agent would otherwise be one Compose project sharing one database,
which happened twice before the hash was added. It also means moving a project directory orphans
its volume, which is a second way to arrive at this section.
List what is there, read it, and remove by full name:
# every evestack Postgres volume on this machine, with its size
docker system df -v | grep evestack-pgdata
# or the full picture, unfiltered, if you want to see everything
docker volume lsIf you remember where the project used to live, you can name its volume exactly:
node -p "const p=require('node:path').resolve('/Users/you/old-project'); \
(p.split(/[\\\\/]/).filter(Boolean).pop().toLowerCase().replace(/[^a-z0-9_-]+/g,'-').replace(/^[^a-z0-9]+/,'')||'evestack') \
+ '-' + require('node:crypto').createHash('sha256').update(p).digest('hex').slice(0,6) + '_evestack-pgdata'"For the path in that example it prints exactly this, and you can check the derivation by running it yourself:
old-project-c94571_evestack-pgdataCheck it against the list above before you act on it. The one-liner reconstructs a name; it
does not confirm one exists. If the name it prints is not in docker volume ls, do not go looking
for the nearest match — the two ways to get a near miss are a path that is not byte-for-byte the
one the project was scaffolded at (a symlinked /tmp, a different capitalisation, a trailing
slash: create hashes the argument it was given, and resolve() here strips a trailing slash it
may not have), and a project that was scaffolded somewhere else entirely. Both mean you have the
wrong directory, not the wrong volume.
Then:
docker volume rm old-project-c94571_evestack-pgdatadocker volume rm refuses a volume a container still uses, which is a useful second opinion: if it
refuses, something is still running and you are about to delete a live project's database.
3. The images, once no project needs them
Only do this when you have removed every evestack project on the machine — these are shared, so removing them while another project exists just means it pulls or rebuilds them again.
# list first, with sizes, and read it
docker images ghcr.io/sammytourani/evestack-dashboard
docker images pgvector/pgvector
# then remove the exact tags you saw — substitute the tags from YOUR output,
# these two are only the shape of the command.
#
# THE-TAG-YOU-SAW is deliberately not a version number. Do not "fix" it to one:
# the publish gate scans the tree for evestack-dashboard:<digit>… and requires
# every hit to equal packages/dashboard/package.json, so a real version here is
# either a duplicate of the pin or a release blocker. It was 0.3.1 once and
# would have failed the 0.4.0 release at tag-push time. A placeholder also fails
# loudly if pasted verbatim — docker answers "No such image" instead of removing
# whichever version you happened to have.
docker rmi ghcr.io/sammytourani/evestack-dashboard:THE-TAG-YOU-SAW
docker rmi pgvector/pgvector:pg17pgvector/pgvector:pg17 is a public Postgres image, not an evestack one. Anything else on
the machine may be using it — another project's database, something you pulled by hand — and
docker rmi on it takes it away from them too. docker rmi refuses while a container still
references it, which catches the common case, but a stopped project you intend to start again
is not protected. Check what depends on it before removing it:
docker ps -a --filter ancestor=pgvector/pgvector:pg17 \
--format 'table {{.Names}}\t{{.Status}}'If that lists anything you did not scaffold, leave the image alone. It costs 646 MB and it will be re-pulled on demand; a database you cannot start is worth more than the disk.
Naming the repository as an argument, rather than --filter name=, is the point: docker images <repo> matches that repository and nothing else.
The per-project sandbox image
eve builds an eve-sandbox-template:<hash> image per project on first run and nothing removes
it — not docker compose down -v, not deleting the project directory, not any evestack command.
Three orphaned ones were on the development machine when this was written. The commands are in
Local setup; the short version
is that --filter reference='eve-sandbox-template:*' matches the whole reference as a glob, so
it names that repository exactly and leaves only the tag open — unlike --filter name=.
Do it when no project is running. The tag carries no hint of which project it belongs to, and a live project simply rebuilds its own on the next turn.
Session sandbox containers
The Docker sandbox keeps one long-lived container per durable session, with no idle timeout, so they accumulate for as long as sessions do. List them and read the list before removing anything:
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'4. The caches that are not evestack's
npx. Every npx create-evestack and npx evestack leaves a full install under
~/.npm/_npx — 99 MB on a machine that had run the scaffolder a few times, 2.2 GB on the same
machine after a month of npx use of everything else. npm cache clean --force does not touch
it. It is shared with every other tool you run through npx, so du -sh first and expect most
of it not to be evestack's.
du -sh ~/.npm/_npx # look first
rm -rf ~/.npm/_npx # safe: it is a cache, and npx refills it on demandOllama. If you took the $0 local-model path, the models are still on your machine and nothing in evestack references them. They are yours and may be in use by something else, so list before removing:
ollama list
ollama rm qwen3
ollama rm nomic-embed-textThe globally installed CLI, if you installed one rather than using npx:
npm ls -g --depth=0 | grep evestack # confirm it is there and named exactly
npm rm -g evestack5. Check your work
Nothing evestack-shaped should be left. Each of these prints nothing on a clean machine:
docker ps -a --format '{{.Names}}\t{{.Image}}' | grep -E 'evestack|pgvector|eve-sandbox'
docker volume ls --format '{{.Name}}' | grep evestack-pgdata
docker images --format '{{.Repository}}:{{.Tag}}' | grep -E 'evestack|pgvector|eve-sandbox'These three are a question, not a to-do list, and the difference matters most here. They are
deliberately wide — wider than evestack — so that nothing hides from them. pgvector in
particular matches on the image column, so every container on the machine running
pgvector/pgvector prints, whoever owns it. Run on the machine this page was written on, the
first line printed a container belonging to no evestack project at all:
evestack-audit-pg pgvector/pgvector:pg17
evestack-postgres-1 pgvector/pgvector:pg17
evestack-dashboard-1 evestack-dashboardOnly the second and third are a scaffolded project's. The first is a database somebody started by hand and is still using.
So do not read "whatever these print, delete it". Read each line, decide whether it is one of
the projects you removed above, and act only on the ones you recognise — by the exact name
printed, one command at a time. A line you cannot account for is a reason to stop and look, not
a reason to run rm.
What is deliberately not here: a script. Every candidate one has to select things by pattern, and a pattern is the failure mode this page is written around. The lists above are short enough to read, and reading them is the safeguard.