GH GambleHub

Technologies and Infrastructure → Docker Compose and Dev Environment

Docker Compose and Dev environment

1) Why Compose

Docker Compose is a quick way to raise a replica of the production stack in locales/CI: applications, databases, queues, caches, reverse proxy, ioc services. Objectives:
  • Parity with sales (images, variables, networks) → less "works for me."
  • Fast start for beginners → 'make up' and into battle.
  • Isolated stands per developer/branch → parallel work without conflicts.
  • Integration tests on real dependencies.

2) Basic repository structure


project/
docker/
app/      # Dockerfile, скрипты web/      # Nginx/Traefik конфиги seed/      # сидеры/фикстуры compose.yaml       # общий базовый стек compose.override.yaml   # локальные оверрайды (в.gitignore)
compose.ci.yaml      # для CI
.env.example       # шаблон окружения
Makefile         # удобные цели devcontainer.json     # VS Code Dev Containers (опционально)
Recommendations:
  • compose. yaml - describes the "skeleton" (services, networks, volumes) the same for dev/CI.
  • override - only local edits: directory mappings, ports, debug flags.
  • .env. example → the developer copies to '.env' and substitutes the values.

3) Framework compose. yaml (example)

yaml name: project services:
gateway:
image: traefik:v3 command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.dev.acme.tlschallenge=true"
ports: ["80:80", "443:443"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro networks: [edge, core]

api:
build:
context:.
dockerfile: docker/app/Dockerfile target: dev env_file: [.env]
command:./scripts/dev-start.sh volumes:
-./:/app:cached depends_on: [db, redis, kafka]
labels:
- "traefik.http.routers.api.rule=Host(`${API_HOST}`)"
- "traefik.http.services.api.loadbalancer.server.port=8080"
networks: [core]

db:
image: postgres:16 environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
POSTGRES_DB: ${DB_NAME}
volumes:
- pgdata:/var/lib/postgresql/data healthcheck: {test: ["CMD-SHELL","pg_isready -U $$POSTGRES_USER"], interval: 5s, timeout: 3s, retries: 20}
networks: [core]

redis:
image: redis:7 command: ["redis-server","--appendonly","yes"]
volumes: [ "redisdata:/data" ]
networks: [core]

kafka:
image: bitnami/kafka:3 environment:
KAFKA_ENABLE_KRAFT: "yes"
KAFKA_CFG_PROCESS_ROLES: "controller,broker"
KAFKA_CFG_NODE_ID: 1
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 networks: [core]

mailhog:
image: mailhog/mailhog ports: ["8025:8025"]
networks: [core]

mock-psp:
image: wiremock/wiremock:3 command: ["--verbose","--global-response-templating"]
volumes: ["./docker/mocks/psp:/home/wiremock"]
labels:
- "traefik.http.routers.mockpsp.rule=Host(`${PSP_HOST}`)"
networks: [core]

volumes:
pgdata: {}
redisdata: {}

networks:
edge: {}
core: {}
Key points:
  • Traefik/NGINX as gateway: brings the routing scheme closer to the sales one.
  • Healthcheck and depends_on with'condition: service_healthy' (in v3 via waiting scripts) - an orderly start.
  • Volumes for persistence (DB/cache) and bind-mount for code (hot-reload).

4) Profiles and multiple files

Profiles ('profiles: [dev, ci, extras]') include/exclude services ('docker compose --profile extras up -d').

Multiple files:
  • `docker compose -f compose. yaml -f compose. dev. yaml up '- merging configurations.
Typical set:
  • `compose. yaml 'is basic.
  • `compose. dev. yaml '- bind-mounts, debags, phicheflags.
  • `compose. extras. yaml '- instrumental (Grafana, pgAdmin, Kafdrop).
  • `compose. ci. yaml '- "head without graphics," without bind-mounts.

5) Variables, secrets and settings

.env - common source of variables: hosts, test database credits, flags.

We do not keep secrets in dev explicitly; we use:
  • local dummy secrets (stub keys),
  • integration with skinny-vault/sops for extra sensitive.
  • Principle: minimum required data. PAN/PII - tokens/fixes.

6) Assemblies and speed

6. 1 Multi-stage + BuildKit

Dockerfile with targets' base ',' dev ',' prod '; shared cache-layer for dependencies.
Include BuildKit: 'DOCKER _ BUILDKIT = 1' (or in config).
Caching: '--mount = type = cache, target =/root/.cache/...' for pip/npm/maven.

6. 2 Fast cycle

Bind-mount кода + hot-reload (nodemon, uvicorn --reload, Spring Devtools).
A separate dev target with an assembly of only the desired one.
Makefile цели: `make up`, `make down`, `make logs`, `make rebuild`, `make seed`.

Makefile example:
make
ENV?= dev up:
docker compose --profile $(ENV) up -d down:
docker compose down -v logs:
docker compose logs -f --tail=200 rebuild:
DOCKER_BUILDKIT=1 docker compose build --pull --no-cache api seed:
docker compose run --rm api./scripts/seed.sh migrate:
docker compose run --rm api./scripts/migrate.sh test:
docker compose -f compose.yaml -f compose.ci.yaml run --rm api./scripts/test.sh

7) DB, migrations, siding

Migrations (Flyway/Liquibase/Alembic/Prisma) are launched by a hook script after the start of 'db' (waiting for healthcheck).
Siding: a separate 'seed' container with fixtures; repeatable and idempotent.
Data snapshots: the 'pgdata' volume can be reset/restored with the 'reset-db script. sh`.


8) Brokers, Caches, CDC

Kafka/Rabbit/Redpanda - as in prod (minimal configs).
Redis with AOF included for realism.
CDC connectors (optional): Debezium in a separate service for integration analytics tests.


9) External Supplier Mocks

WireMock/Prism for REST, MockServer for complex scenarios.
Mailhog/SMTP4Dev for letters.
Localstack/MinIO for cloud stores and S3 compatibility.

Politics: all external PSP/KYC/KMS - through the mock hub under contracts (OpenAPI), and not "on the Internet."


10) Reverse proxy and TLS

Traefik/NGINX distributes services to local domains ('.test', '.local'):
  • `api. local. test`, `mockpsp. local. test`.
  • TLS: mkcert to issue a trusted local certificate to test HSTS/secure-cookies.
  • Turn on sticky sessions only for cases where it is really important.

11) Developer Profiles: Node/Python/Java

Node: mount 'node _ modules' as cache (volume) to speed up install; 'CHOKIDAR _ USEPOLLING = 1' on Windows/WSL.
Python: `pip cache` как volume, `watchfiles`/`uvicorn --reload`.
Java: JRebel/Devtools, 'mvn -T 1C -o' + layer with dependencies.


12) Tests and quality

Integration tests race inside the Compose network: 'docker compose run test'.
Testcontainers (for JVM/Node/Python/.NET) is a good option for unit integration without a full stack.
Contract tests with the → gate mock hub in CI.
Linters/Pre-commit: run in container for repeatability.


13) Devcontainers and "IDE-as-code"

`devcontainer. json 'fixes the image of the developer (CLI, SDK, linters), mounts the project, runs' postCreateCommand '.
Profit: the same tools, do not "clog" the host, the new machine is ready in minutes.


14) Security in dev

Without root in application images; 'readOnlyRootFilesystem' when possible.
No battle keys/secrets, even temporarily.
Logs - without PII/PAN; masking at the formatter level.
Port and network segregation: external access via gateway only.


15) FinOps/performance in locale

Limit resources: 'deploy. resources. limits' (Compose reads partially, but helps discipline).
Reduce fan-out (fewer default services; extras - profiles).
BuildKit cache and volume caches for package managers.


16) CI с Compose

Use the same'compose. yaml` + `compose. ci. yaml 'without bind mounts.
Dependency caches are like attachable volumes between jobs/layers.
Parallel jabs: 'name:' in Compose is different (or prefix by branch) so that the stands do not conflict.


17) Trableshooting

'docker compose ps '/' logs -f '/' exec '- basic diagnostics.
Check DNS on the Compose network (service by name).
If bind-mount "slows down" on macOS/Windows - ': cached '/': delegated' or Mutagen/virtiofs.
Healthcheck is "green," but the service is "dead": check the 'readiness' of your uppka and the order of migrations.


18) Implementation checklist

1. Base stack (gateway, api, db, cache, queue) in compose. yaml.
2. Local edits - in override (v.gitignore).
3..env. example full and current; 'make bootstrap' copies it to '.env'.
4. Healthchecks and database/migration wait script.
5. WireMock/Localstack/MinIO for external providers.
6. Siding and migrations as' make seed/migrate'cmdlets.
7. BuildKit + multi-stage, dependency caches.
8. Devcontainers/Makefile for a fast start.
9. 'Extras' profiles for tools (Grafana/pgAdmin/Kafdrop).
10. CI uses the same compose (+ ci-overlide).


19) Anti-patterns

"Monster-compose" for 40 services, always running: turn on profiles.
Hard-nailed ports that conflict between developers.
Secrets/keys in Git or '.env. example`.
Dependence on the "Internet" for tests (real PSP/KYC).
Lack of healthcheck/expectation - migration and start races.
No siding → flaky integration tests.


20) The bottom line

Compose is the engine of development speed: one file describes your world of services, and profiles/overrides give flexibility. Maintain parity with sales, automate siding and migrations, keep moki and TLS "like in battle," speed up BuildKit builds - and you have a local environment in which it is convenient to work, easy to test and safely reproduce iGaming/fintech sales scenarios.

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.