SuperAPI AI Directory

ddd-devops-integration

Deployment & operations

View repository

Updated 10-15 21:48

About this skill

DDD DevOps Integration

DevOps for DDD projects — ArchUnit quality gates (P0 block / P1 warn / P2 report) in CI/CD, multi-module incremental builds, architecture-type-aware Dockerfiles, event-driven DB migration, domain event health monitoring.


Workflow

Step 1: Code & Build — Compile all modules. Domain must compile last (zero framework contamination).

Step 2: Unit Test — Per-module unit tests run independently.

Step 3: ArchUnit Validate — P0 (zero deps, layer compliance) blocks CI; P1 (cycle-free) warns; P2 (naming) reports.

Step 4: Integration Test — Cross-module interaction tests with event store and outbox.

Step 5: Containerize — Build Docker images (monolith fat JAR or split CQRS with tuned JVM args).

Step 6: Deploy — K8s deploy with per-BC namespace, DB migration init containers, health probes.

Step 7: Monitor — Domain metrics (event rate, outbox depth, aggregate load) → Prometheus alerts.

Quality gates run at build time, never against production. Violations block merge, not deployment.


Boundary

✅ Good at handling

  • Configuring ArchUnit quality gates (P0/P1/P2) for DDD projects, integrated into the CI/CD Pipeline
  • Incremental compilation optimization for multi-module DDD projects (Maven/Gradle), parallel build acceleration
  • Architecture-type-aware Dockerfile generation (monolith/CQRS/hexagonal architecture)
  • K8s deployment templates: Per-BC Namespace, DB migration initContainers, domain health probes
  • Event-driven database migration: Event Store, Outbox table creation and indexing strategies
  • Domain event health monitoring: Prometheus metric exposure and alert rule configuration

⚠️ Requires input

  • Project structure: Maven/Gradle module list, dependency graph → automatically generate ArchUnit rules
  • Deployment environment: K8s cluster version, Ingress strategy → generate adapted YAML templates
  • Database solution: whether Layered/CQRS/Event Sourcing pattern is used → customize migration strategy

❌ Out of scope (not applicable)

  • General CI/CD configuration (not applicable to non-DDD projects) → use general DevOps tools
  • Container orchestration basics (K8s introductory tutorial) → refer to official documentation
  • K8s cluster operations (node management, RBAC configuration) → use professional operations tools
  • General database management (backup, recovery, performance tuning) → use DBA tools
  • Infrastructure monitoring (CPU, memory, network) → use Prometheus + Grafana

Audience

This skill is designed for: Backend developers (implementing DDD architectures), Software architects (evaluating and selecting patterns), Tech leads (reviewing team implementations), and DDD beginners (learning domain-driven design fundamentals).

Rules

  1. ArchUnit P0 checks (domain purity, layer compliance) must block CI pipeline on failure.
  2. Dockerfiles must be architecture-type-aware (Monolith/CQRS/Hexagonal each get different builds).
  3. Domain event monitoring must be configured before production deployment.
  4. Database migrations for event-driven systems must include event store and outbox tables.

CI/CD Pipeline

stages:
  - build
  - unit-test
  - architecture-check    # DDD gate
  - integration-test
  - containerize
  - deploy

ArchUnit validation in architecture-check stage: P0 tests (DomainPurityTest, LayeringComplianceTest) block on failure; P1 (ModuleDependencyTest) warns with approval; P2 (NamingConventionTest) reports only. Key ArchUnit rules — domain must not depend on Spring/JPA/MyBatis; layer access restrictions (Domain only by Application, Infrastructure, Interface); no cyclic package dependencies. Full guide: references/ci-cd-archunit-setup.md


Multi-module build strategy

ddd-project/
├── domain/ (zero framework deps) → application/ (depends on domain only) → infrastructure/ (implements domain interfaces)
├── adapter/ (REST/event adapters) → start/ (boot entry)

Build optimization: mvn compile -pl domain -am (~60% faster changed-only), mvn -T 4 (~40% parallel), mvn verify -pl '!domain' (skip domain), actions/cache for target/ (~80%). Domain purity enforced via Maven Enforcer (bans Spring deps in domain module). Full config: references/multi-module-build-config.md


Containerized deployment

Monolith — Multi-stage fat JAR:

FROM eclipse-temurin:17-jdk-alpine AS builder
COPY . . && RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-alpine
COPY --from=builder start/target/*.jar app.jar
HEALTHCHECK --interval=30s CMD curl -f http://localhost:8080/actuator/health

CQRS — Separate images: Command (-Xms512m -Xmx2g -XX:+UseZGC, CPU-optimized); Query (-Xms1g -Xmx4g, memory-optimized). K8s Patterns: Per-BC Namespace, DB migration initContainers + Flyway, CQRS split HorizontalPodAutoscaler, NetworkPolicy isolation. Templates: dockerfile-patterns.md | k8s-ddd-reference.md


Database migration (event-driven)

CREATE TABLE domain_event_store (id UUID PRIMARY KEY, aggregate_id VARCHAR(36) NOT NULL,
    event_type VARCHAR(200) NOT NULL, event_data JSONB NOT NULL,
    occurred_at TIMESTAMPTZ NOT NULL, published BOOLEAN DEFAULT FALSE);
CREATE INDEX idx_events_pending ON domain_event_store(published) WHERE published = FALSE;
CREATE TABLE outbox_message (id UUID PRIMARY KEY, event_id UUID UNIQUE NOT NULL,
    payload JSONB NOT NULL, status VARCHAR(20) DEFAULT 'PENDING',
    retry_count INT DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW());
CREATE INDEX idx_outbox_pending ON outbox_message(status) WHERE status = 'PENDING';

Strategy: Layered single DB → Flyway/Liquibase sequential; CQRS L2 → Dual tracks + lag; Event Sourcing → Axon/EventStoreDB append-only; Per microservice → Per-BC Flyway. Full scripts: flyway-migration.md | db-strategies.md


Monitoring and alerting

Bus metrics: domain.events.published (Counter), domain.events.processing.duration (Histogram p50/p95/p99), domain.aggregate.load.duration (Histogram), domain.outbox.depth (Gauge).

Alert rules: DomainEventBacklog (rate > 100 for 2m, critical), OutboxQueueGrowing (depth > 1000 for 1m, critical), EventProcessingErrorRate (> 5% for 2m, warning). Full config: ddd-observability-config.md


Gotchas

  1. ArchUnit too strict, hindering development: First run in warning mode for 2-3 sprints, P1/P2 do not block CI, upgrade to error after the team adapts.
  2. CQRS read/write containers not separated: Command services are CPU-intensive, query services are memory-intensive, they should be built and deployed independently.
  3. Domain event monitoring omissions: Event delivery latency, Outbox backlog, and Consumer Lag are the most easily overlooked reliability metrics in event-driven architecture.
  4. Monolith packaged into microservice images: First assess whether the BC needs independent deployment; over-splitting loses the advantage of strong consistency within aggregates.
  5. Database migration does not consider event storage: When adding Event Store tables, backfill, indexing, and cleanup strategies must also be considered.
  6. ArchUnit does not check rich domain models: Needs to be combined with ddd-code-reviewer for domain model quality review.

FAQ

Q: ArchUnit CI fails but the code is correct? A: Check whether the Domain layer is polluted by framework annotations (e.g. @Service), move them to the infrastructure layer. Q: Monolith vs microservice DDD deployment strategy? A: Start with a monolith. Split only when a BC needs independent scaling, a single BC team exceeds 8 people, or deployment cadences differ greatly between BCs. Q: How to monitor domain events without adding latency? A: Asynchronous metrics (Micrometer Timer percentage sampling) + sampling tracing (1/100 OpenTelemetry). Never block event publishing. Q: Should CQRS read and write share the same pipeline? A: Only share the Domain module tests. The Command pipeline runs the full ArchUnit gate; the Query pipeline focuses on read model schema compatibility. Q: How to manage Event Sourcing schema? A: Event Store is append-only and does not require schema migration. Version compatibility is managed through event version numbers (event_type + version). Q: How is Bounded Context canary release implemented? A: Service Mesh (Istio) traffic weight distribution. The new version first receives 5% of traffic, and after monitoring domain event health metrics, it goes full volume.


Security & Safety

This skill is pure documentation. It does not collect user data, does not access external services or networks, and contains no executable scripts.

Keywords

ddd devops, ddd ci/cd, archunit ci, domain event monitoring, ddd docker, ddd kubernetes, ddd outbox, ddd database migration, ddd build optimization, ddd quality gate, ddd deployment, ddd alerting, ddd observability, cqrs deployment, event sourcing infrastructure

References

Examples