A platform for discovering and contributing location-based community stories through a map and feed interface.
Live: https://storymap.page
| Layer | Technology |
|---|---|
| Backend | Django REST Framework + Gunicorn |
| Frontend | React + Vite |
| Mobile | Expo (React Native) |
| Database | MySQL 8.0 |
| Reverse proxy | nginx |
| Infrastructure | Docker Compose |
Install Docker:
- Windows / macOS — Docker Desktop
- Linux —
curl -fsSL https://get.docker.com | sh
cp .env.example .env # Windows CMD: use 'copy' instead of 'cp'Open .env and fill in the values (at minimum SECRET_KEY, DB_PASSWORD, DB_ROOT_PASSWORD).
docker compose up --build # first time
docker compose up # subsequent runs| Service | URL |
|---|---|
| API | http://localhost:8000 |
| Frontend | http://localhost:5173 |
docker compose down# Full test suite
docker compose run --rm --entrypoint="" web sh -c "pytest -v"
# Single app
docker compose run --rm --entrypoint="" web sh -c "pytest apps/users/tests/ -v"
# Single file
docker compose run --rm --entrypoint="" web sh -c "pytest apps/users/tests/test_models.py -v"Migrations run automatically on startup. After adding or changing a model:
docker compose exec web python manage.py makemigrations# Shell inside the backend container
docker compose exec web bash
# Reset database (wipes all data, keeps schema)
docker compose exec web python manage.py flush --noinput
# Wipe database volume entirely and reinitialise
docker compose down -v && docker compose upThe fastest way to test on a device — no build required.
cd mobile
cp .env.example .env # Windows CMD: use 'copy'
nano .env # fill in EXPO_PUBLIC_API_BASE_URL and EXPO_PUBLIC_MAP_API_KEY
npm install
npx expo startScan the QR code with the Expo Go app on your device.
For
EXPO_PUBLIC_API_BASE_URL: usehttps://storymap.page/apito point at production, or your machine's LAN IP (http://192.168.x.x:8000) for local development. Android emulator useshttp://10.0.2.2:8000.
APK builds run automatically via GitHub Actions — no Expo account required.
Automatic build (recommended)
Every merge to main triggers the Mobile APK workflow which builds the APK and uploads it as a GitHub Actions artifact. To download:
- Go to the Actions tab
- Open the latest successful run
- Download
local-history-story-map-apkfrom the Artifacts section
When a GitHub Release is published, the APK is also attached to it directly.
Manual trigger
You can also trigger a build manually from the Actions tab without merging — useful for testing a branch. Click Mobile APK → Run workflow.
Install on device
- Download the
.apkfile to an Android device - Allow "Install from unknown sources" when prompted
- Install and open
- Ubuntu 24.04 VPS (1 GB RAM minimum — 2 GB swap required, see below)
- A domain with an A record pointing to the server IP
- Ports 80 and 443 open
# Install Docker
curl -fsSL https://get.docker.com | sh
# Install Certbot
apt install -y certbot
# Add 2 GB swap (required — npm build OOMs on 1 GB RAM without it)
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstabcd /opt
git clone https://github.com/bounswe/bounswe2026group4.git
cd bounswe2026group4certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
mkdir -p nginx/certs
cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem nginx/certs/
cp /etc/letsencrypt/live/yourdomain.com/privkey.pem nginx/certs/
chmod 644 nginx/certs/*.pemcp .env.prod.example .env.prod
nano .env.prodFill in all values. The fields that must match your domain:
ALLOWED_HOSTS=yourdomain.com
CORS_ALLOWED_ORIGINS=https://yourdomain.com
VITE_API_URL=https://yourdomain.com/api
NGINX_HOST=yourdomain.com
Generate a secret key:
python3 -c "import secrets; print(secrets.token_urlsafe(50))"set -a && source .env.prod && set +a
docker compose -f docker-compose.prod.yml up -d --buildcurl -I https://yourdomain.com # → 200 OK
curl https://yourdomain.com/api/stories/ # → JSONdocker compose -f docker-compose.prod.yml psdocker compose -f docker-compose.prod.yml logs nginx --tail 50
docker compose -f docker-compose.prod.yml logs web --tail 50
docker compose -f docker-compose.prod.yml logs db --tail 50cd /opt/bounswe2026group4
git pull origin main
set -a && source .env.prod && set +a
docker compose -f docker-compose.prod.yml up -d --buildDeployments are also automated via the CD pipeline — merging to
maintriggers a GitHub Actions workflow that runs the above steps automatically.
# Stop all containers
docker compose -f docker-compose.prod.yml down
# Restart a single service
docker compose -f docker-compose.prod.yml restart webdocker compose -f docker-compose.prod.yml exec web python manage.py flush --noinput