ZooKeeper practical with Docker

1. Install and open Docker Desktop.
2. Open a terminal in this folder (beside compose.yaml).
3. Run: docker compose up -d --build
4. Run: docker compose ps
5. Animal registrations: docker compose logs zebra giraffe deer bear elephant
6. Open a ZooKeeper client: docker compose exec zoo1 zkCli.sh -server zoo1:2181
   At its prompt: ls /zoo
   Then: get /zoo/zebra-status
7. In another terminal: docker compose logs -f zebra
   At the ZooKeeper prompt: set /zoo/water-limit "800 L"
   Zebra logs the change. Ctrl+C stops following logs.
8. Stop an animal: docker compose stop bear
   At the ZooKeeper prompt: ls /zoo
   Bear's ephemeral entry disappears on session close (or expiry after a crash).
   Restore it: docker compose start bear
9. Type quit to exit the ZooKeeper client.
10. Stop the example: docker compose down

Keep animal-service/ next to compose.yaml. First build needs internet access.
Three servers plus five animal clients run as eight containers on one computer.
ZooKeeper elects the leader; animal clients do not vote.
Water limit is initialized to 1000 L only if absent; existing data is retained.
Named volumes keep ZooKeeper data when the containers are removed.

TTL znodes are enabled on all servers with JVMFLAGS=-Dzookeeper.extendedTypesEnabled=true.
