Personal trainer app
make
make setup-git-hooks # if you want to develop straight to main branch
make dev
Navigate to http://localhost:4000 to see the service in action. You can attach a debugger to it.
If you get something like the following error when running the below commands:
Error: the config for your app is missing an app name, add an app field to the fly.toml file or specify with the -a flag
Then, you need to select the fly app you have deployed:
export FLY_APP=petrapp
This project uses Fly.io for infrastructure and Litestream
for SQLite database backups. It's a single instance Dockerized application with a persistent
volume. Try fly launch to configure your own. You might also need to add some secrets to with fly secrets.
The container image contains sqlite3 binary to make it easy to manipulate the live production database.
make fly-sqlite3One way to recover a lost or broken database is to restore it with Litestream. The process could still use some
improvements but at least it works. Notably, you need to have a working machine running so that you can run commands on
it. Another alternative is to clone the machine with an empty volume and populate it yourself using the fly sftp shell
command.
# list databases
fly ssh console --user petrapp -C "/dist/litestream databases"
# list snapshot generations of selected database
fly ssh console --user petrapp -C "/dist/litestream snapshots /data/petrapp.sqlite3"
# restore latest snapshot to /data/petrapp4.sqlite
fly ssh console --user petrapp -C "/dist/litestream restore -o /data/petrapp4.sqlite -generation db5b998e60a203a3 /data/petrapp.sqlite3"
# Edit fly.toml env PETRAPP_SQLITE_URL = "/data/petrapp.sqlite3" before deploying to take new database into use
vim fly.toml
# Deploy the new configuration
fly deploy
Use pprof for perfomance investigation.
Proxy the pprof server to your local machine.
fly proxy 6060:6060Capture a CPU profile of the running app.
go tool pprof --http=: "http://localhost:6060/debug/pprof/profile?seconds=30"Capture a goroutine stack traces.
go tool pprof -top "http://localhost:6060/debug/pprof/goroutine"When a request times out, the app writes a trace to a file and logs something like the following line:
{
"time": "2025-09-13T10:02:11.604995985+03:00",
"level": "WARN",
"msg": "captured timeout trace",
"service_name": "pr-29-myrjola-petrapp",
"file": "/data/traces/timeout-20250913-070211.trace",
"bytes": 709652,
"trace_id": "HBGYTREFLURSGLEQGR2OX4XEBK",
"proto": "HTTP/1.1",
"method": "GET",
"uri": "/api/test/timeout?sleep_ms=3000"
}This file can be downloaded with the following replacing FLY_APP and file name with service_name and file from the log line:
FLY_APP=pr-29-myrjola-petrapp fly sftp get /data/traces/timeout-20250913-070211.trace
Once you have the file, you can analyze it with:
go tool trace timeout-20250913-070211.trace
This project uses GitHub Actions for CI/CD.
Prerequisite: Ensure you have Fly set up correctly with fly auth whoami.
Create a new app with a globally unique name.
fly apps create petrapp-stagingCreate a bucket for the database backups. This should configure the secrets automatically matching the configuration in litestream.yml.
fly storage create --app petrapp-staging --name petrapp-staging-backupNow we are ready to deploy the app.
fly deploy --app petrapp-stagingPetra logo made by Martin Yrjölä using Inkscape.