Fortune is a service for serving fortune cookies. It reuses internal code from pkgsite (the Go package index), adapted for MySQL, and implements a lean, GCP-native stack with full observability. The project showcases a production-ready Go setup you can build on or deploy as-is.
Below are instructions for running the service locally or with Kind.
Ensure you have the following installed before proceeding:
- Go (โฅ v1.23.3)
- golang-migrate (โฅ v4.18.2)
- Goreleaser (โฅ v2.1.0)
- Docker (latest recommended version)
- Kind (โฅ v0.27)
- kubectl (latest recommended version)
- Terraform (โฅ v1.2.9)
git clone [email protected]:tetsuo/fortune.git
cd fortune
git fetch --tags # Ensure tags are fetched for build versioning
make tidy
Run the following script to start a MySQL 8.0 container with the fortune_db
database:
./scripts/docker_mysql.sh
This starts MySQL, sets the root password, and enables general query logging.
๐ก You can modify values in this script, but it's recommended to stick to defaults for simplicity.
Check if fortune_db
exists:
docker exec -it mysql mysql -u root -p -e "SHOW DATABASES LIKE 'fortune_db';"
Run migrate_db.sh
to apply or manage database migrations.
Ensure go-migrate is installed, then verify the current migration version:
./scripts/migrate_db.sh version
๐ก If you see error: no migration
, it means no migrations have been applied yet.
Run the MySQL migrations from etc/migrations:
./scripts/migrate_db.sh up
docker exec -it mysql \
mysql -u root -p -e "USE fortune_db; SHOW TABLES LIKE 'fortune_cookies';"
make build
LOG_LEVEL=debug ./bin/frontend
(Or run with go run ./cmd/frontend/...
.)
If everything works, you should see logs like this:
2025-03-14T13:24:43.766+0100 INFO frontend/main.go:116 debug server listening on localhost:8081
2025-03-14T13:24:43.772+0100 INFO frontend/main.go:192 frontend server listening on localhost:8080
Try retrieving a fortune cookie:
curl localhost:8080 ; echo
๐จ Expected output: Not Found
(because we haven't added fortunes yet).
Bulk insert a fortunes.txt
file containing 2,000+ fortunes:
curl -X POST -H "Content-Type: text/plain" \
--data-binary @fortunes.txt \
http://localhost:8080 -v
curl localhost:8080 ; echo
๐ฎ Example output: "One planet is all you get."
Visit localhost:8081 for debugging insights, metrics, and other useful details.
Before deploying, ensure all tests pass:
./all.bash ci
This installs linters and runs tests. If everything is โ , continue to release preparation.
Goreleaser handles packaging and release generation.
goreleaser release -f .goreleaser.yml --snapshot --clean
๐ This outputs the build to the dist/
folder.
Quick build (no release):
goreleaser build -f .goreleaser.yml --snapshot --clean --single-target
docker build -t fortune-frontend:latest .
kind create cluster
kind load docker-image fortune-frontend:latest
From the root directory:
kind get kubeconfig --name kind > terraform/kubeconfig.yaml
Navigate to terraform/
and run:
terraform init
terraform apply
kubectl port-forward -n fortune services/mysql 3306:3306
DATABASE_USER=kinduser DATABASE_PASSWORD=kindpassword ./scripts/migrate_db.sh up
๐จ In production, run migrations securely. The included mysql chart is not meant for production use.
kubectl port-forward --namespace ingress-controller service/haproxy-kubernetes-ingress 8080:80
Update your /etc/hosts
file, ensure it contains:
127.0.0.1 local.haproxy.kind
127.0.0.1 www.local.haproxy.kind
curl -X POST -H "Content-Type: text/plain" \
--data-binary @fortunes.txt \
http://local.haproxy.kind:8080 -v
curl local.haproxy.kind:8080 ; echo
๐ I hope it's a good one!
MIT license