Sign inSign up

neuman1812/gigtracker

By neuman1812

•Updated 5 days ago

A tracking app for gig workers.

Image
0

4.1K

neuman1812/gigtracker repository overview

⁠Docker Setup for GigTracker

⁠Screenshots

⁠Web Application
DashboardFinancialsTax Center
DashboardFinancialsTax Center
⁠Mobile App
DashboardActivityFinancesProfile
DashboardActivityFinancesProfile

This guide explains how to run GigTracker using Docker and Docker Compose.

⁠Prerequisites

  • Docker (version 20.10 or higher)
  • Docker Compose (version 2.0 or higher)

⁠Quick Start

  1. Start all services:

    docker compose up
    

    This will start:

    • PostgreSQL database (port 5433)
    • Django backend (port 5353)
    • React frontend (port 5173)
  2. Access the application:

⁠Common Commands

⁠Start services in the background:
docker compose up -d
⁠Stop services:
docker compose down
⁠View logs:
# All services (live stream via Docker)
docker compose logs -f

# Specific service
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f db
⁠Application Logs

GigTracker writes structured OWASP-compliant JSON logs to the ./logs/ directory on the host (bind-mounted from the container's /app/logs/).

FileContents
logs/gigtracker.logAll application logs (JSON lines)
logs/error.logERROR and FATAL entries only
logs/gigtracker.log.1 … .5Rotated backups

Live viewing — logs are output to both files and stdout, so docker compose logs -f backend shows them in real time.

Log levels are configurable via the Django admin panel (Site Configuration → Logging Configuration) or the API (PUT /api/logs/config/):

LevelDescription
Info / Warn (default)Standard operational logging
DebugVerbose flow-level detail for troubleshooting
Trace⚠️ Maximum verbosity — captures request details. Generates large files.

Rotation defaults: 10 MB per file, 5 backups (~50 MB total). Configurable via admin panel.

Log viewer UI: Navigate to /logs in the web app (admin users only) to browse, filter, search, and download logs.

Sensitive data masking: Tokens, API keys, passwords, credit card numbers, emails, and credential URLs are automatically redacted in all log output.

⁠Rebuild containers (after dependency changes):
docker compose up --build
⁠Run Django management commands:
# Create migrations
docker compose exec backend poetry run python manage.py makemigrations

# Apply migrations
docker compose exec backend poetry run python manage.py migrate

# Create superuser
docker compose exec backend poetry run python manage.py createsuperuser

# Django shell
docker compose exec backend poetry run python manage.py shell
⁠Access the database:
docker compose exec db psql -U postgres -d gigtracker
⁠Clean up everything (including volumes):
docker compose down -v

⁠Development Workflow

⁠Hot Reload

Both frontend and backend support hot reload:

  • Backend: Code changes in ./backend are automatically detected
  • Frontend: Code changes in ./frontend trigger automatic rebuild
⁠Installing New Dependencies
⁠Backend (Python/Poetry):
  1. Add dependency to backend/pyproject.toml
  2. Rebuild the backend container:
    docker compose up --build backend
    
⁠Frontend (Node/Yarn):
  1. Add dependency to frontend/package.json or run:
    docker compose exec frontend yarn add <package-name>
    
  2. If needed, rebuild:
    docker compose up --build frontend
    

⁠Troubleshooting

⁠Port already in use:

If you get port conflicts, you can modify the ports in docker-compose.yml:

ports:
  - "8001:8000"  # Change host port (left side)
⁠Database issues:

Reset the database:

docker compose down -v  # Removes volumes
docker compose up       # Recreates database
⁠Permission issues:

If you encounter permission issues with volumes on Linux:

sudo chown -R $USER:$USER backend/logs backend/media backend/static
⁠Container won't start:

Check the logs:

docker compose logs <service-name>
⁠Clean rebuild:
docker compose down
docker compose build --no-cache
docker compose up

⁠Architecture

┌─────────────────────────────────────────────────────────┐
│                    Docker Compose                        │
├──────────────┬──────────────────┬────────────────────────┤
│   Frontend   │     Backend      │      Database          │
│   (Vite)     │    (Django)      │    (PostgreSQL)        │
│   Port 5173  │    Port 5353     │    Port 5433           │
│              │                  │                        │
│   Node 20    │   Python 3.12    │   PostgreSQL 16        │
│   Alpine     │   Slim           │   Alpine               │
└──────────────┴──────────────────┴────────────────────────┘

⁠Environment Variables

Default values are set in docker-compose.yml. For custom configuration:

  1. Copy .env.docker to .env:

    cp .env.docker .env
    
  2. Modify values as needed

  3. Restart containers:

    docker compose down
    docker compose up
    

⁠Production Deployment

GigTracker includes a production-ready Docker setup that bundles the frontend and backend into a single container using Nginx + Gunicorn.

⁠Quick Start (Production)
# 1. Copy and edit the environment file
cp .env.prod.example .env.prod
# Edit .env.prod — set SECRET_KEY, DB_PASSWORD, Firebase keys, etc.

# 2. Build the production image
docker compose -f docker-compose.prod.yml build

# 3. Start in the background
docker compose -f docker-compose.prod.yml up -d

The app will be available at http://localhost:8080⁠.

⁠Equivalent docker run
# Start PostgreSQL
docker run -d --name gigtracker_prod_db \
  -e POSTGRES_DB=gigtracker \
  -e POSTGRES_USER=gigtracker \
  -e POSTGRES_PASSWORD=your-db-password \
  -v gigtracker_pgdata:/var/lib/postgresql/data \
  --network gigtracker \
  postgres:16-alpine

# Start GigTracker
docker run -d --name gigtracker \
  -p 8080:80 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e UMASK=002 \
  -e TZ=America/New_York \
  -e SECRET_KEY=your-secret-key \
  -e DEBUG=False \
  -e ALLOWED_HOSTS=yourdomain.com \
  -e DB_NAME=gigtracker \
  -e DB_USER=gigtracker \
  -e DB_PASSWORD=your-db-password \
  -e DB_HOST=gigtracker_prod_db \
  -e DB_PORT=5432 \
  -e GEMINI_API_KEY=your-gemini-key \
  -v gigtracker_media:/app/media \
  -v gigtracker_static:/app/staticfiles \
  -v gigtracker_config:/config \
  -v ./logs:/app/logs \
  --network gigtracker \
  --restart unless-stopped \
  neuman1812/gigtracker:latest
⁠Environment Variables
⁠Container Settings (Runtime)
VariableDescriptionDefault
PUIDUser ID for file permissions1000
PGIDGroup ID for file permissions1000
UMASKFile creation mask002
TZTimezoneAmerica/New_York
⁠Django Settings (Runtime)
VariableDescriptionDefault
SECRET_KEYRequired. Django secret key—
DEBUGDebug mode (never True in prod)False
ALLOWED_HOSTSComma-separated hostnames*
GEMINI_API_KEYGoogle Gemini AI key for receipt OCR—
GUNICORN_WORKERSNumber of Gunicorn workers3
GUNICORN_TIMEOUTGunicorn request timeout (seconds)120
⁠Database Settings (Runtime)
VariableDescriptionDefault
DB_NAMEDatabase namegigtracker
DB_USERDatabase usergigtracker
DB_PASSWORDRequired. Database password—
DB_HOSTDatabase hostdb
DB_PORTDatabase port5432
⁠Firebase Settings (Build-time)

These are baked into the frontend JavaScript bundle during docker build. You must rebuild the image if these change.

VariableDescription
VITE_FIREBASE_API_KEYFirebase API key
VITE_FIREBASE_AUTH_DOMAINFirebase auth domain
VITE_FIREBASE_PROJECT_IDFirebase project ID
VITE_FIREBASE_STORAGE_BUCKETFirebase storage bucket
VITE_FIREBASE_MESSAGING_SENDER_IDFirebase messaging sender ID
VITE_FIREBASE_APP_IDFirebase app ID
VITE_FIREBASE_MEASUREMENT_IDFirebase measurement ID
⁠Architecture
┌─────────────────────────────────────────────────┐
│          Production Container (:8080)             │
│                                                   │
│  Nginx (:80)                                      │
│    /            → React SPA (static files)        │
│    /api/*       → Gunicorn → Django               │
│    /admin/*     → Gunicorn → Django               │
│    /static/*    → Django collected static files    │
│    /media/*     → User uploads                    │
│                                                   │
│  Gunicorn (:8000) → Django WSGI                   │
│                                                   │
│  Logging → /app/logs/ (bind mount → ./logs/)      │
│    gigtracker.log  (JSON, rotating, all levels)    │
│    error.log       (JSON, rotating, ERROR+)        │
│                                                   │
│  Init: PUID/PGID → migrations → collectstatic     │
└────────────────────┬──────────────────────────────┘
                     │
              ┌──────▼──────┐
              │ PostgreSQL 16 │
              └──────────────┘
⁠Volumes
MountContainer PathDescription
gigtracker_media/app/mediaUser-uploaded files (receipts, etc.)
gigtracker_static/app/staticfilesDjango collected static files
gigtracker_config/configPersistent configuration
./logs/app/logsApplication log files (JSON, rotating)

Note: The ./logs bind mount ensures logs persist on the host and are accessible outside the container for monitoring or aggregation tools. Log rotation is handled by the application — defaults to 10 MB per file with 5 backups.

⁠Security Notes
  • Container starts as root only to adjust UID/GID, then drops to appuser via gosu
  • No secrets are hardcoded in the Dockerfile or compose file
  • TLS is handled externally (Cloudflare, Traefik, etc.) — the container serves HTTP only
  • DEBUG=False is enforced in the production compose file
  • Image uses python:3.12-slim base for minimal attack surface
⁠Updating
# Pull latest image (if using pre-built from Docker Hub)
docker compose -f docker-compose.prod.yml pull

# Or rebuild from source
docker compose -f docker-compose.prod.yml build --no-cache

# Restart
docker compose -f docker-compose.prod.yml up -d

⁠Support

For issues or questions:

  • Check the main README.md
  • Review logs: docker compose logs
  • Open an issue in the repository

Tag summary

Content type

Image

Digest

sha256:d39002607…

Size

100.4 MB

Last updated

5 days ago

docker pull neuman1812/gigtracker