Create the mounted folders, record your user ID, run airflow-init once, then start the rest. up.sh in demos/ch07/airflow/ wraps these steps with BookNest's extras:
mkdir -p dags logs plugins config include
echo "AIRFLOW_UID=$(id -u)" > .env
docker network create l2-booknest && docker network connect l2-booknest l2-pg
docker compose -p l2-airflow up airflow-init
docker compose -p l2-airflow up -d
docker compose -p l2-airflow ps --format 'table {{.Service}}\t{{.Status}}'Output
airflow-init-1 | User "airflow" created with role "Admin" airflow-init-1 | 3.3.2 airflow-init-1 exited with code 0 ... SERVICE STATUS airflow-apiserver Up About a minute (healthy) airflow-dag-processor Up About a minute (healthy) airflow-scheduler Up About a minute (healthy) airflow-triggerer Up About a minute (healthy) postgres Up 3 minutes (healthy)
From an empty volume to five healthy containers took 200-205 seconds in two runs. The UI is at http://localhost:32880. down removes the containers but keeps the metadata volume; down -v deletes it too. Before anyone else can reach the stack, change the admin password, FERNET_KEY (which encrypts stored connection passwords) and the JWT secret (Securing Orchestration).