Skip to content

Step 11 — Files: a drive and a bucket

About 25 minutes. Branch: step-11.

The one new idea: a drive and a bucket are not two names for the same thing.

This is the end of the application. Everything after this step changes how you run Tally, not what it does.

Declare both

appmecca.yaml @ step-11
storage:
  drives:
    - name: digests
      size_gb: 1
  buckets:
    - name: digests

and mount the drive into the service that uses it:

    drives:
      - name: digests
        path: /data/digests

path is where it appears inside the container — an ordinary directory.

The difference, and it matters

A drive A bucket
Looks like a directory a key-value store
Reached by open(), listdir, rename an SDK, over the network
Shared by every replica that mounts it anything with the credentials
Good for files your code treats as files many, large, or browser-served things
Has a size ceiling you declare no directories, no partial writes

Reach for a drive when you want file operations. Reach for a bucket when the things are many, large, or served to browsers.

Tally's digest goes to both, which is contrived — it is one small text file — but it puts them side by side where you can compare them.

Credentials, and where the boundary actually is

Declaring a bucket injects APPMECCA_BUCKET_DIGESTS_NAME, a region, and a key — also under the AWS_* names most SDKs look for by default, so boto3.client("s3") just works.

That key can reach this app's buckets and nothing else

Not because the code is careful — because the permissions attached to the key say so. A boundary enforced where it cannot be argued with is worth more than one enforced by everybody remembering.

Do it

mecca app redeploy tally -b tutorial
mecca cron trigger tally weekly-digest

Then look, from outside the app:

mecca drive list tally -b tutorial
mecca drive ls tally digests -b tutorial
mecca drive download tally digests 2026-01-01.txt -b tutorial

mecca drive browses, uploads, downloads, moves and deletes without shelling into anything.

mecca bucket list tally -b tutorial
mecca bucket reveal tally -b tutorial     # shown once

The proof worth doing yourself

mecca app redeploy tally -b tutorial     # redeploy, replacing every container
mecca drive ls tally digests -b tutorial

The file is still there. A drive is not scratch space inside a container. The containers were replaced; the drive was not.

That is the one property people most often assume and most often assume wrongly in the other direction — anything written to a container's own filesystem is gone on the next deploy. A drive is how you keep it.

If it didn't work

Symptom Try Usually
Nothing written mecca logs tally --type container The mount is declared but not on that service
Read-only file system check the mount readonly: true
bucket: null in the API mecca debug tally Bucket declared but not deployed yet
Writes fail near the ceiling raise size_gb It is a hard cap, up to 100

Reset to the reference

git fetch upstream && git reset --hard upstream/step-11 && git push --force origin tutorial

That is the whole application. A React frontend, a Python API, a background worker, Postgres, Redis, a drive and a bucket — one app, one URL, one config file. A good place to stop.

If you carry on: Step 12 — Two branches, and the advanced track is about running it rather than building it.