Local Docker Deployment

Run a complete Temp-Number App stack locally using Docker Compose. Perfect for development, testing, and learning how the system works.

Overview

Docker Compose provides:

  • βœ… Quick Setup: Get running in minutes with automated configuration
  • βœ… No Local Dependencies: Everything runs in containers
  • βœ… Automatic Migrations: Database setup handled automatically
  • βœ… Hot Reload: Development mode with live code changes (optional)
  • βœ… Easy Cleanup: Remove everything with one command
  • βœ… Isolated Environment: Doesn’t interfere with other projects

Architecture

Your Browser

Web Frontend :8080

Backend API :3333

Firebase Auth

Platfone API

MySQL :3336

Docker Network

Local Volume

Prerequisites

  • Web Frontend: Vue.js app served by Nginx on port 8080
  • Backend API: AdonisJS API server on port 3333
  • MySQL Database: MySQL 8.0 on port 3336 with persistent volume

Required Software

Install the following before proceeding:

  • Docker Desktop: Installation guide
    • Windows: Docker Desktop for Windows
    • Mac: Docker Desktop for Mac
    • Linux: Docker Engine + Docker Compose
  • Git: For cloning repositories (Download )

Verify installation:

# Check Docker
docker --version
# Output: Docker version 24.0.0 or higher

# Check Docker Compose
docker compose version
# Output: Docker Compose version 2.0.0 or higher

Required Accounts

Deployment

You can use the provided deployment scripts for automated deployment to your local machine. These scripts handle the entire deployment process, including building Docker images, starting containers, and configuring the necessary services.

git clone https://github.com/platfone-com/temp-number-deploy.git
cd temp-number-deploy
./docker-start.sh

Script will prompt for necessary configuration values.

For automated assistance with Firebase setup, consider using the Setup Wizard instead.

Setup Wizard

Interactive setup wizard that handles all prerequisites and configuration

🐒 Manual Deployment Steps

Step 1: Clone the Deployment Repository

git clone https://github.com/platfone-com/temp-number-deploy.git
cd temp-number-deploy

Step 2: Clone Application Repositories

# Clone backend repository
git clone https://github.com/platfone-com/temp-number-backend.git
# Clone frontend repository
git clone https://github.com/platfone-com/temp-number-web.git

Step 3: Prepare environment

# Prepare environment variables
cp config/env/backend.env.example config/env/backend.env
cp config/env/web.env.example config/env/web.env
# Prepare secrets
cp config/secrets/backend.secrets.example config/secrets/backend.secrets
echo "Fill in the configuration files with your values"

Step 4: Prepare Firebase

Step 4.1 : Create Firebase Project
  1. Go to Firebase Console
  2. Create a new Firebase project or select an existing one
Step 4.2: Configure Firebase Authentication

Configure Firebase Authentication (Email/Password, Google, etc.)

  1. Go to Firebase Console
  2. Select your project
  3. Go to Authentication β†’ Sign-in method
  4. Choose and enable desired sign-in providers (e.g., Email/Password, Google, Apple, Facebook)
  5. Save changes
Step 4.3: Set Email Templates
  1. Go to Authentication β†’ Templates
  2. Click on pencil icon to edit templates
  3. Click on “Customize action URL”
  4. Set the URL to http://localhost:8080/app/deeplink for local development

This ensures that email links redirect to your local frontend application.

Step 5: Download Firebase Service Account Key

  1. Go to Project Settings β†’ Service Accounts
  2. Click Generate New Private Key
  3. Save as config/secrets/firebase-service-account.json

Set correct permissions:

chmod 644 config/secrets/firebase-service-account.json

Run the interactive script:

./docker-start.sh

Select option 1 or 2 to start services:

What would you like to do?
  1) Start services (build and run)
  2) Start services in background
  3) Run migrations only
  4) View logs
  5) Stop services
  6) Clean up (remove containers and volumes)

Enter choice [1-6]: 2

Step 6: Verify Services

Check that all services are running:

docker compose ps

Expected output:

NAME                    IMAGE               STATUS              PORTS
temp-number-backend     docker-backend      Up 30 seconds       0.0.0.0:3333->3333/tcp
temp-number-mysql       mysql:8.0           Up 30 seconds       0.0.0.0:3336->3336/tcp
temp-number-web         docker-web          Up 30 seconds       0.0.0.0:8080->80/tcp

Check logs:

cd scripts/docker
docker compose --profile full logs -f

Understanding the Services

MySQL Database

Container: temp-number-mysql

Environment:
  MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-root_password}
  MYSQL_DATABASE: ${DB_DATABASE:-temp_number}
  MYSQL_USER: ${DB_USER:-temp_number_user}
  MYSQL_PASSWORD: ${DB_PASSWORD:-temp_number_password}

Volume:
  mysql_data:/var/lib/mysql  # Persists data

Health Check:
  mysqladmin ping every 10s

Access database:

# Using Docker
cd scripts/docker
echo "Use user and password from backend.env and backend.secrets file"
docker exec -it temp-number-mysql mysql -u YOUR_DB_USER -pYOUR_DB_PASSWORD

# From host (if port 3336 is exposed)
mysql -h 127.0.0.1 -P 3336 -u YOUR_DB_USER -pYOUR_DB_PASSWORD

Backend API

Container: temp-number-backend

Build Context: ../../temp-number-backend
Entry Point: /app/init-backend.sh (runs migrations)
Command: node bin/server.js

Environment Overrides:
  # Override specific values for Docker environment
  DB_HOST: mysql
  DB_PORT: 3306
  DB_PASSWORD: ${DB_PASSWORD:-temp_number_password}
  NODE_ENV: development
  HOST: 0.0.0.0

  # Use local Firebase credentials path
  GOOGLE_APPLICATION_CREDENTIALS: /app/config/secrets/firebase-service-account.json

  # Override CORS for local development
  ALLOWED_ORIGINS: http://localhost:${DOCKER_WEB_PORT:-8080}

Mounts:
  - Firebase credentials (read-only)
  - Initialization script

Automatic Initialization:

The backend automatically runs on startup:

  1. Waits for MySQL to be ready (30 retries, 2s interval)
  2. Runs database migrations: node ace migration:run --force
  3. Starts the API server

View backend logs:

docker compose --profile full logs backend -f

Access backend shell:

docker exec -it temp-number-backend bash

Web Frontend

Container: temp-number-web

Build Context: ../../temp-number-web
Build Args: All VITE_* environment variables
Server: Nginx on port 80 (mapped to 8080)

Health Check:
  curl -f http://localhost:80/app/ every 30s

Build process:

  1. Installs npm dependencies
  2. Builds Vue.js app with environment variables
  3. Serves static files via Nginx

View web logs:

docker compose --profile full logs web -f

Development Mode (Hot Reload)

For active development of Backend or Web components with hot reload use scripts/docker/docker-compose.dev.yml as additional compose file:

cd scripts/docker
docker compose --profile full -f docker-compose.yml -f docker-compose.dev.yml up

Now code changes will automatically reload!

  • Backend: Reloads on TypeScript changes
  • Frontend: Hot module replacement (HMR) on port 5173

To run migrations please, refer to running database migrations.

Common Operations

View Logs

# All services
docker compose --profile full logs -f

# Specific service
docker compose --profile full logs backend -f
docker compose --profile full logs web -f
docker compose --profile full logs mysql -f

# Last 100 lines
docker compose --profile full logs --tail=100 backend

Restart Services

# Restart all
docker compose --profile full restart

# Restart specific service
docker compose --profile full restart backend
docker compose --profile full restart web

Run Database Migrations

Migrations run automatically on startup, but you can run manually:

# Run pending migrations
docker exec -it temp-number-backend node ace migration:run

# Rollback last batch
docker exec -it temp-number-backend node ace migration:rollback

# Check migration status
docker exec -it temp-number-backend node ace migration:status

Access Service Shells

# Backend shell
docker exec -it temp-number-backend bash

# MySQL shell
docker exec -it temp-number-mysql mysql -u YOUR_DB_USER -pYOUR_DB_PASSWORD

# Web container shell
docker exec -it temp-number-web sh

Stop Services

# Stop services (keeps containers)
docker compose --profile full stop

# Stop and remove containers
docker compose --profile full down

# Stop, remove containers and volumes (deletes database!)
docker compose --profile full down -v

Rebuild After Code Changes

# Rebuild and restart
docker compose --profile full up --build -d

# Rebuild specific service
docker compose --profile full build backend
docker compose --profile full up -d backend

Reset Database

# Method 1: Drop and recreate via migrations
docker exec -it temp-number-backend node ace migration:rollback --batch=0
docker exec -it temp-number-backend node ace migration:run

# Method 2: Destroy volume and restart
docker compose --profile full down -v
docker compose --profile full up -d

Troubleshooting

⚠️ All docker compose ... commands should be run from scripts/docker directory.

Services Won’t Start

Check Docker is running:

docker info

If Docker is not running, start Docker Desktop.

Check port conflicts:

# Check if ports are already in use
lsof -i :8080  # Web frontend
lsof -i :3333  # Backend API
lsof -i :3336  # MySQL

# Or on Linux
netstat -tulpn | grep -E ':(8080|3333|3336)'

Change ports if needed in scripts/docker/docker-compose.env.sh.

MySQL Connection Errors

Symptom: Backend fails to connect to database

Check MySQL is healthy:

docker compose ps mysql
# Should show "healthy" status

docker compose --profile full logs mysql

Test connection manually:

docker exec -it temp-number-mysql mysqladmin ping -h localhost -u root -proot_password

Reset database:

docker compose --profile full down -v
docker compose --profile full up -d

Migration Failures

Symptom: Backend logs show migration errors

Check migration status:

docker exec -it temp-number-backend node ace migration:status

Rollback and retry:

docker exec -it temp-number-backend node ace migration:rollback
docker exec -it temp-number-backend node ace migration:run

Reset migrations:

docker exec -it temp-number-backend node ace migration:rollback --batch=0
docker exec -it temp-number-backend node ace migration:run --force

Firebase Authentication Issues

Symptom: Login fails or “Firebase not configured” errors

Verify credentials file:

# Check file exists and has correct permissions
ls -la config/secrets/firebase-service-account.json

# Should show: -rw-r--r-- (644)

Verify environment variable:

docker exec -it temp-number-backend printenv | grep GOOGLE_APPLICATION_CREDENTIALS
# Should show: GOOGLE_APPLICATION_CREDENTIALS=/app/config/secrets/firebase-service-account.json

# Check file is mounted
docker exec -it temp-number-backend ls -la /app/config/secrets/

Test Firebase connection:

docker compose --profile full logs backend | grep -i firebase

Frontend Build Errors

Symptom: Web container fails to build

Check environment variables:

cat scripts/docker/.env | grep VITE_

Build with verbose output:

docker compose --profile full build --no-cache --progress=plain web

Check Node.js version:

The frontend requires Node.js 18+. Check Dockerfile in temp-number-web.

Port Already in Use

Change ports:

Edit scripts/docker/docker-compose.env.sh:

export DOCKER_WEB_PORT=8081        # Changed from 8080
export DOCKER_BACKEND_PORT=3334    # Changed from 3333
export DOCKER_MYSQL_PORT=3307      # Changed from 3336

Restart:

docker compose --profile full down
./docker-start.sh

Container Disk Space

Check Docker disk usage:

docker system df

Clean up:

# Remove unused images
docker image prune -a

# Remove unused volumes
docker volume prune

# Full cleanup (WARNING: removes everything)
docker system prune -a --volumes

Logs Show EADDRINUSE

Symptom: Error: listen EADDRINUSE: address already in use

This means another process is using the port. Kill the process or change ports.

Find and kill process:

# Find process on port 3333
lsof -ti:3333

# Kill it
kill -9 $(lsof -ti:3333)

Performance Optimization

Resource Limits

Set resource limits in docker-compose.yml:

services:
  backend:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '1'
          memory: 1G

Volume Performance

Use delegated or cached volume mounts for better performance:

volumes:
  - ../../temp-number-backend:/usr/src/app:delegated

Build Cache

Speed up rebuilds with build cache:

# Use BuildKit
export DOCKER_BUILDKIT=1

# Build with cache
docker compose build --build-arg BUILDKIT_INLINE_CACHE=1

Security Best Practices

Protect Secrets

Never commit secrets to version control:

# .gitignore should include:
config/secrets/
scripts/docker/.env
*.pem
*.key
*-key.json

Generate Strong APP_KEY

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Use Strong Database Password

openssl rand -base64 32

Restrict Firebase Permissions

Set minimal file permissions:

chmod 600 config/secrets/firebase-service-account.json

Backup and Restore

Backup Database

# Create backup
docker exec temp-number-mysql mysqldump -u YOUR_DB_USER -pYOUR_DB_PASSWORD temp_number > backup-$(date +%Y%m%d).sql

# Or with Docker
docker exec temp-number-mysql mysqldump -u YOUR_DB_USER -pYOUR_DB_PASSWORD temp_number > backup.sql

Restore Database

# Restore from backup
docker exec -i temp-number-mysql mysql -u YOUR_DB_USER -pYOUR_DB_PASSWORD temp_number < backup.sql

Backup Entire Volume

# Stop services
docker compose --profile full stop backend web

# Create volume backup
docker run --rm \
  -v docker_mysql_data:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/mysql-data-backup.tar.gz -C /source .

# Restart services
docker compose --profile full start

Restore Volume

# Stop and remove containers
docker compose --profile full down

# Remove old volume
docker volume rm docker_mysql_data

# Create new volume
docker volume create docker_mysql_data

# Restore data
docker run --rm \
  -v docker_mysql_data:/target \
  -v $(pwd):/backup \
  alpine sh -c "cd /target && tar xzf /backup/mysql-data-backup.tar.gz"

# Start services
docker compose --profile full up -d

Advanced Topics

Custom Docker Network

Use a custom network for integration with other services:

networks:
  temp-number-network:
    external: true
    name: my-custom-network

Health Checks

Monitor service health:

# Check health status
docker compose ps

# Detailed health info
docker inspect temp-number-backend --format='{{json .State.Health}}'

Logging to File

Redirect logs to files:

# Log all services
docker compose --profile full logs -f > docker-compose.log 2>&1 &

# Log specific service
docker compose --profile full logs -f backend > backend.log 2>&1 &

Next Steps

Configuration

Configure authentication and payments

Development Guide

Customize and extend the application