From the team behind aidrop.it — one workspace to build, host, and keep changing your code.

It worked locally. It saves uploads to ./uploads, writes a cache to /tmp, and keeps a small SQLite file next to the code. Then it goes to a container, and the uploads vanish every time it restarts.

Nothing failed. The container did exactly what containers do: it started from the image, wrote to a layer that lives as long as the process, and threw that layer away when it stopped.

It is one more of the operational decisions an AI coding tool does not make for you. The rule underneath is worth learning once, because everything else follows from it: a running container's filesystem is scratch space, not storage. Where an application may write is a decision somebody makes; where it may keep something is a different decision entirely.

The three things people accidentally put on disk

Uploads. A user's file written to a local directory. It exists until the next deploy, then it does not, and the database still has a row pointing at it. This is the one that produces support tickets months later.

A local database file. SQLite next to the code is genuinely excellent — on a machine that persists. In a container it means every deploy is a fresh, empty product.

A cache that became a source of truth. Rendered output, generated tokens, a session store. Fine while it is genuinely a cache, fatal the moment something reads it expecting the value to be there.

The pattern is the same in all three: something was written where it could be written, rather than where it would still be.

Read-only is a feature, not an obstacle

A read-only root filesystem with a small scratch area is a deliberate constraint, and it is on your side. It makes the question explicit at deploy time instead of at 2am: an application that cannot write has to say where its state goes before it runs, not discover it afterwards.

It also removes a class of attack. Code that cannot modify itself cannot be modified — no dropped webshell, no rewritten binary, no persistence between restarts for anything that got in.

What you get instead of a disk is usually enough: a temporary area for genuinely temporary things — a file being processed, a compiled asset, a socket — that is expected to disappear, and does.

Where state actually goes

  • Records → a database. Anything you would be upset to lose. This is the boring answer and it is almost always the right one, and it does not have to be a database your host runs.
  • Files → object storage. Uploads, exports, generated documents. A URL and a key, not a path.
  • Ephemeral things → the scratch area, written in the knowledge that a restart clears it.
  • Sessions and counters → a cache, chosen because losing them costs a re-login rather than an order.
  • Nothing → the image. A file baked at build time is in every copy of that image, which is the same reasoning that keeps credentials out of the artefact.

The awkward middle case is a tier that has no database at all. Then there is genuinely nowhere for state to live, and "we'll write it to a file for now" is not a smaller version of a database — it is a product that forgets. Better to know before building the form, which is the case for reading the runtime before the code.

FAQ

Why did my uploads disappear after a deploy? They were written into the container's own filesystem, which is replaced when the container is. Nothing deleted them; the place they were in stopped existing.

Can I just attach a volume? Sometimes, and it solves persistence while creating a new question: a volume ties the application to one machine, which is exactly what makes moving or scaling it hard later.

Is SQLite unusable in a container? Not unusable — unpersisted. It needs storage that outlives the container, and once you have that you have most of the complexity of a database anyway.

What if my plan has no database? Then the honest answer is that nothing survives a restart. On aidrop.it an application always runs on a read-only root with scratch space only, and volumes exist for managed services — so a tier without one has no disk at all, which is stated rather than discovered.

Does /tmp count as safe? Safe to use, not safe to rely on. Treat it as a workspace for the current request, never as a place something waits.


Cover: https://unsplash.com/photos/rN6zOBGSZjM by Adrien Olichon on Unsplash. Alt text: Tall industrial warehouse shelving holding stored goods.

Before the next deploy

Get it running from the session you are already in

Connect your coding agent over MCP and ask it to deploy. aidrop builds the repository and runs it on a public address; when a build or the app fails, the log says why, and your agent fixes it and builds again.