From the team behind aidrop.it — one workspace to build, host, and keep changing your code.
Keep uploaded files after a deployment by storing them outside the application container. Put the file bytes in persistent object storage and keep their owner, object key and upload status in your database. Test the complete path: upload a file, replace the application, then retrieve the same file through an authorized request.
Your customer attaches a document to an order. The app saves uploads/document.pdf and a database row with that path. After deployment, the order remains but the document disappears. The runtime storage check explains the boundary: a path inside a disposable container cannot preserve a customer's file.
Record file owners
Give each upload a server-generated identifier and object key. Keep the original filename as display metadata alongside the owner, size and status. Read the object through that record after checking the caller's access. A filename supplied by a customer should not decide which stored object the application replaces or who can download it.
Keep private documents in a private bucket. Generate a short-lived download link after authorization rather than storing an expiring link as the permanent reference. OWASP's upload guidance covers generated filenames, access checks and upload limits. Validate allowed formats and file content; a browser-supplied content type does not prove the file is safe.
Complete the upload
Treat the storage upload and database update as separate steps with a recovery path. Create a pending record, upload the bytes, then verify the expected object before marking the record ready. Show success after that final check. If the browser disconnects midway, retain enough state to resume or clean up the incomplete attempt.
You can pass the bytes through your backend or let an authenticated browser upload through a presigned URL. Amazon S3's upload contract limits that URL to the signer's permissions and allows replacing an existing object at the same key. Issue a distinct key for each attachment and keep storage credentials on the server.
Verify the object's size and ownership before accepting a browser's completion report. Define cleanup for objects without completed records and pending records without objects. The order retry contract helps you keep one upload attempt associated with one order when a customer retries.
Test after a deploy
Test persistence through the application's public URL after a deployment, using the account that uploaded the file. Compare the downloaded content with the original and try access from a different account. A storage bucket can retain the bytes while an application release loses the database reference or exposes the wrong customer's attachment.
Include file storage in the live-app operating record. Name the storage account, deletion policy and recovery owner. A database backup containing object keys does not contain the file bytes; plan recovery for both stores and test their relationship.
Upload check
Run this check with a disposable document and two test accounts before accepting customer files. Record the object key and database row so you can follow the same upload across application replacement. Include an interrupted transfer and an expired download link; a successful first upload leaves those recovery and access cases untested.
UPLOAD ACCEPTANCE CHECK
File owner and related order:
Persistent bucket and server-generated object key:
Database record, pending/ready states and size limit:
Authorization and download-link expiry:
Incomplete-upload cleanup and recovery owner:
[ ] Upload completes before the app reports success
[ ] Download after deployment matches the original bytes
[ ] Another account cannot download or replace the file
[ ] Interrupted upload stays pending or gets cleaned up
[ ] Repeated completion keeps the same attachment
[ ] Expired link needs a fresh authorized request
[ ] Recovery preserves both file bytes and their references
FAQ
Can I keep uploads in /tmp? Use /tmp while processing a file within a request. Move the bytes into persistent storage before treating the upload as complete. Application replacement can remove temporary files while the database still contains their paths.
Does a presigned URL make a file public? It gives anyone holding the URL the permitted access until it expires or the underlying authorization stops allowing it. Keep the bucket private, authorize the requester and avoid logging signed links or sharing them beyond the intended recipient.
Where should I store files on aidrop.it? An application Service on aidrop.it has a read-only root filesystem and temporary scratch paths, with no persistent application volume. Use an external object-storage provider over HTTPS. Configure a storage client that honors the runtime proxy and give the Service only the secret names it needs.
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.