Run the notes examples locally
Local testing is optional; the deployment walkthrough uses managed PaaS resources.
These commands use only the disposable services in the example’s compose.yaml.
The supplied passwords are local demo values, not PaaS credentials.
1. Start the services
Install Docker with Compose. From an unpacked notes download, run:
docker compose up -d --wait
cp .env.example .env
set -a
. ./.env
set +a
From a repository checkout, use docker compose -f ../../compose.yaml up -d --wait
inside examples/<language>/notes instead. The file starts PostgreSQL, MariaDB,
MongoDB, Redis, and a SeaweedFS S3 service.
All published ports bind to 127.0.0.1. They use unusual port numbers to avoid
colliding with your existing development databases.
2. Choose a primary database
The default .env.example selects PostgreSQL. For another engine, change these two
values in your local .env, then load it again in both web and worker terminals:
DATABASE_ENGINE | DATABASE_URL (local demo only) |
|---|---|
postgresql | postgresql://tutorial:tutorial@127.0.0.1:18432/notes |
mariadb | mysql://tutorial:tutorial@127.0.0.1:18306/notes |
mongodb | mongodb://tutorial:tutorial@127.0.0.1:18017/notes?authSource=admin |
REDIS_URL=redis://:tutorial@127.0.0.1:18379/0 is shared by the web and worker.
Run one language at a time against this local queue; otherwise one language’s worker
can pick up another’s export request. Use distinct Redis database numbers for
independent simultaneous examples.
3. Install and start the chosen app
Follow the download’s README to install dependencies. Initialize the schema once, then start the web process and worker in separate terminals with the same environment:
| Language | Initialize schema | Web | Worker |
|---|---|---|---|
| Node.js | node app.mjs migrate | npm start | node app.mjs worker |
| Rails | bundle exec ruby bin/rails runner 'NotesStore.migrate' | bundle exec puma -b tcp://0.0.0.0:3000 | bundle exec ruby worker.rb |
| Python | python app.py migrate | gunicorn --bind 0.0.0.0:3000 app:app | python app.py worker |
| Go | go run . migrate | go run . web | go run . worker |
| Rust | cargo run --locked --bin migrate | cargo run --locked --bin web | cargo run --locked --bin worker |
Activate .venv in each Python terminal. For Rails, set a local SECRET_KEY_BASE
using ruby -rsecurerandom -e 'puts SecureRandom.hex(64)'; use RAILS_ENV=development locally.
Open http://localhost:3000, save a note, and export it. Without the optional S3
variables, the worker stores the generated JSON in Redis.
4. Enable local object storage
Uncomment all five S3/AWS variables in .env and reload it. With the AWS CLI installed,
create the local bucket once:
aws --endpoint-url "$S3_ENDPOINT" --region "$S3_REGION" s3 mb "s3://$S3_BUCKET"
Restart both processes with those variables and request a new export. List its file:
aws --endpoint-url "$S3_ENDPOINT" --region "$S3_REGION" s3 ls "s3://$S3_BUCKET/exports/"
These settings point at the local S3-compatible service. On PaaS, bucket attachments supply the actual endpoint, region, name, and credentials instead.
5. Stop and reset
Stop web/worker processes with Ctrl+C. docker compose stop retains local service state;
docker compose down -v removes the local tutorial containers and data. From the repo
checkout, include -f ../../compose.yaml again. These commands do not touch your PaaS resources.
Return to your language tutorial for hosted deployment, or continue with production preparation.