Docker Setup
This document defines how Docker and Docker Compose should be used for local Tripinger development and selected operational workflows.
Table of Contents
- Document Purpose
- Overview
- Dockerization Goals
- Planned Services
- Container Strategy
- Recommended Docker Compose Layout
- Ports and Service Endpoints
- Volumes and Persistence
- Environment Variable Strategy
- Development Workflow
- Sample Docker Compose Skeleton
- Build and Runtime Conventions
- Local Commands
- Troubleshooting
- Security Notes
- Assumptions
Document Purpose
This document defines how Docker and Docker Compose should be used for local Tripinger development and selected operational workflows. It focuses on the planned containerized local environment, expected services, port layout, persistence strategy, and command conventions.
This document does not claim that all Docker assets already exist in the repository. It provides the approved setup direction for implementation.
Overview
Tripinger is planned as a multi-application platform with a public web app, backend API, admin dashboard, partner portal, and supporting infrastructure such as PostgreSQL, Redis, search, media-related services, and background processing. Docker is intended to provide a predictable local development environment for infrastructure dependencies and, where useful, application runtime containers as well.
The investor blueprint also indicates a deployment direction that includes Docker, GitHub Actions, and container-friendly hosting. This makes Docker useful not only for local development but also for environment parity and CI-oriented workflows.
Dockerization Goals
The Docker setup should achieve the following goals:
- Standardize local infrastructure across developer machines.
- Reduce setup friction for PostgreSQL, Redis, and search services.
- Support consistent environment bootstrapping for the API and related workers.
- Allow optional containerized execution of web, admin, and partner surfaces.
- Make CI and deployment packaging easier by using aligned runtime assumptions.
- Keep the local workflow simple enough for an early-stage team.
Planned Services
Based on the current architecture and technology direction, the local Docker environment is expected to include the following categories of services.
| Service | Purpose | Local Docker Priority |
|---|---|---|
| PostgreSQL | Primary transactional database | Required |
| Redis | Caching, ephemeral coordination, optional pub/sub | Required |
| Elasticsearch / OpenSearch-compatible service | Search and indexing support | Optional early, expected later |
| API app | NestJS backend runtime | Recommended |
| Worker app | Async jobs such as notifications or indexing | Optional early |
| Web app | Public frontend runtime | Optional in Docker |
| Admin app | Internal dashboard runtime | Optional in Docker |
| Partner app | Partner portal runtime | Optional in Docker |
External services not expected to run locally as full Docker dependencies
The following systems are expected to remain external, sandboxed, mocked, or partially simulated in local development:
- PayHere
- Stripe
- OpenAI or other AI providers
- Email delivery provider
- SMS / WhatsApp provider
- Cloudinary or equivalent media delivery service
- Cloud-hosted object storage
Container Strategy
Tripinger should use Docker in two distinct ways:
1. Local infrastructure containers
This is the minimum expected use case. PostgreSQL, Redis, and optional search infrastructure should run in Docker for reliable local setup.
2. Optional application containers
The applications themselves may run either:
- directly on the host machine for faster frontend iteration, or
- inside Docker containers for parity and onboarding simplicity.
Recommended default for early development
- Run infrastructure services in Docker.
- Run frontend applications on the host machine unless the team prefers fully containerized development.
- Run the API in either Docker or host mode depending on developer preference and debugging needs.
This hybrid approach reduces rebuild overhead while preserving reliable infrastructure setup.
Recommended Docker Compose Layout
The Docker setup should be centered around one main Compose file for local development.
Recommended files
| File | Purpose |
|---|---|
docker-compose.yml | Main local development stack |
docker-compose.override.yml | Developer-specific or optional local overrides |
Dockerfile per app | Container build logic for each application |
.dockerignore per app or root | Faster builds and smaller contexts |
Suggested service groups
- Core infrastructure: PostgreSQL, Redis, search.
- Core runtime: API, optional worker.
- Optional UI runtimes: web, admin, partner.
Ports and Service Endpoints
The final local ports are not yet confirmed. The table below provides a consistent placeholder convention that can be updated later without changing the architectural intent.
| Service | Container Port | Suggested Host Port | Notes |
|---|---|---|---|
| PostgreSQL | 5432 | 5432 | Primary relational database |
| Redis | 6379 | 6379 | Cache and ephemeral coordination |
| Elasticsearch | 9200 | 9200 | Search API endpoint |
| Elasticsearch internal transport | 9300 | 9300 | Internal cluster transport if needed |
| API | 3000 | 3000 | Main backend HTTP API |
| Web app | 5173 | 5173 | Vite development server placeholder |
| Admin app | 5174 | 5174 | Separate frontend surface placeholder |
| Partner app | 5175 | 5175 | Separate frontend surface placeholder |
| Worker | n/a | n/a | Background service without direct public port |
Assumption: These ports are placeholders aligned with common local defaults and may be adjusted later to match the actual app configurations.
Volumes and Persistence
Local Docker volumes should be used to preserve state for infrastructure services that developers do not want recreated every restart.
Recommended persistent volumes
| Volume | Purpose |
|---|---|
tripinger_postgres_data | PostgreSQL data files |
tripinger_redis_data | Optional Redis persistence if enabled |
tripinger_search_data | Search index data for local search service |
Bind mounts
Bind mounts are useful for application code during development:
- Mount source code into API containers if running the API in watch mode.
- Avoid mounting heavy dependency directories unless the container strategy requires it.
- Be careful with
node_moduleshandling to avoid host/container mismatch issues.
Persistence guidance
- Database volumes should persist across restarts.
- Search volumes may be reset when index changes are easier than migration.
- Temporary services should not persist more than necessary.
Environment Variable Strategy
Docker Compose should consume environment variables from the project environment files without storing real secrets in source control.
Directional rules
- Use
.env.exampleas the reference file for required variables. - Use a local
.envfile for developer-specific values. - Do not hardcode secrets into Compose files.
- Separate app-level config from infrastructure credentials where practical.
Example variable categories
- Database connection values
- Redis connection values
- Search endpoint values
- API base URLs
- Frontend app URLs
- External provider sandbox keys
See also .env.example and docs/ENVIRONMENTS.md.
Development Workflow
The local Docker workflow should support at least three modes.
Mode 1: Infrastructure-only Docker
Recommended for frontend-heavy work.
- Start PostgreSQL, Redis, and optional search via Docker Compose.
- Run API and frontend apps on the host machine.
- Use local hot reload tooling without rebuilding containers repeatedly.
Mode 2: API + infrastructure Docker
Recommended for backend and onboarding consistency.
- Start PostgreSQL, Redis, search, and API containers together.
- Run frontend apps on the host machine.
- Use container logs for API diagnostics.
Mode 3: Fully containerized local stack
Useful for parity testing or simplified onboarding.
- Start infrastructure and all applications in Compose.
- Use mounted source code plus watch mode where practical.
- Accept slower iteration speed in exchange for consistency.
Sample Docker Compose Skeleton
The following example is intentionally generic and uses placeholders where implementation details are not yet confirmed.
version: '3.9'
services:
postgres:
image: postgres:16
container_name: tripinger-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "5432:5432"
volumes:
- tripinger_postgres_data:/var/lib/postgresql/data
redis:
image: redis:7
container_name: tripinger-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- tripinger_redis_data:/data
search:
image: docker.elastic.co/elasticsearch/elasticsearch:8.14.0
container_name: tripinger-search
restart: unless-stopped
environment:
discovery.type: single-node
xpack.security.enabled: "false"
ES_JAVA_OPTS: -Xms512m -Xmx512m
ports:
- "9200:9200"
volumes:
- tripinger_search_data:/usr/share/elasticsearch/data
api:
build:
context: .
dockerfile: ./apps/api/Dockerfile
container_name: tripinger-api
restart: unless-stopped
depends_on:
- postgres
- redis
environment:
DATABASE_URL: ${DATABASE_URL}
REDIS_URL: ${REDIS_URL}
SEARCH_URL: ${SEARCH_URL}
ports:
- "3000:3000"
volumes:
- ./:/app
working_dir: /app
command: sh -c "<<API_START_COMMAND>>"
volumes:
tripinger_postgres_data:
tripinger_redis_data:
tripinger_search_data:Notes on the sample
searchis optional for very early local development.- The exact API Dockerfile path and startup command are placeholders.
- Frontend services can be added later if the team chooses a fully containerized workflow.
Build and Runtime Conventions
Dockerfile guidance
Each app Dockerfile should:
- Use a pinned Node.js base image version once confirmed.
- Separate dependency installation from source copy where possible.
- Minimize image size for non-development builds.
- Support both development and production-friendly variants if needed.
Suggested conventions
- Root build context only when shared workspace files are required.
- App-specific working directories inside the container.
- Explicit startup commands rather than implicit shell assumptions.
- Health checks for longer-running service containers where useful.
Early-stage preference
For the local environment, favor readability and onboarding simplicity over maximum Docker optimization.
Local Commands
The final command set depends on the chosen package manager and actual Compose file names. The examples below are placeholders to standardize expected workflow.
Start infrastructure only
docker compose up -d postgres redis searchStart the whole local stack
docker compose up -dView running services
docker compose psTail API logs
docker compose logs -f apiStop services
docker compose downStop services and remove volumes
docker compose down -vRebuild selected services
docker compose build apiTroubleshooting
PostgreSQL connection failures
Possible causes:
- Incorrect
DATABASE_URL - PostgreSQL container not healthy yet
- Port conflict on host
5432 - Local migration not yet applied
Redis connection failures
Possible causes:
- Wrong
REDIS_URL - Redis container unavailable
- App starting before Redis is ready
Search not available
Possible causes:
- Search service disabled intentionally
- Memory allocation too low
- Port
9200conflict
Slow app container rebuilds
Possible causes:
- Oversized Docker build context
- Missing
.dockerignore - Reinstalling dependencies on every change
Node module mismatch issues
Possible causes:
- Host
node_modulescolliding with containernode_modules - Different Node versions between host and image
- Mixed package manager usage
Security Notes
Even for local development, Docker assets should follow basic security hygiene.
- Do not commit real credentials.
- Use sandbox keys for payment and provider integrations.
- Avoid exposing unnecessary ports publicly.
- Keep local admin credentials out of shared defaults where possible.
- Treat partner documents and other sensitive test data carefully.
Production container hardening, image scanning, and deployment controls will be documented in docs/DEVOPS.md, docs/DEPLOYMENT.md, and SECURITY.md.
Assumptions
- Assumption: Docker Compose is the primary local orchestration tool.
- Assumption: PostgreSQL and Redis are required local containers from the beginning.
- Assumption: Search infrastructure is optional for very early development but part of the intended architecture.
- Assumption: Frontend applications may run outside Docker during active UI development.
- Assumption: The API will eventually have a dedicated Dockerfile under
apps/api/. - Assumption: The exact package manager, Node version, app start commands, and final port map are still to be confirmed.