Skip to content

feat: docker-compose support#734

Merged
magne4000 merged 55 commits into
mainfrom
magne4000/dev
May 26, 2026
Merged

feat: docker-compose support#734
magne4000 merged 55 commits into
mainfrom
magne4000/dev

Conversation

@magne4000

@magne4000 magne4000 commented May 19, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added Docker and Dokploy boilerplates with containerization support and pre-configured deployment files
    • SQLite database now requires explicit server selection (Express, H3, etc.)
  • Improvements

    • Enhanced YAML transformation for generated configuration files
    • Improved Bun package manager detection
    • Optimized dependency classification (build-only packages moved to devDependencies)

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 869f7689-fb98-45fe-a63e-dd170c3310ae

📥 Commits

Reviewing files that changed from the base of the PR and between fa35cce and bd8d066.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (82)
  • .github/workflows/reusable.run-tests.yml
  • .github/workflows/tests-entry.yml
  • boilerplates/aws/files/$package.json.ts
  • boilerplates/docker-compose/bati.config.ts
  • boilerplates/docker-compose/files/$.dockerignore.ts
  • boilerplates/docker-compose/files/$Dockerfile.ts
  • boilerplates/docker-compose/files/docker-compose.yml
  • boilerplates/docker-compose/package.json
  • boilerplates/docker-compose/tsconfig.json
  • boilerplates/dokploy/bati.config.ts
  • boilerplates/dokploy/files/$TODO.md.ts
  • boilerplates/dokploy/files/$package.json.ts
  • boilerplates/dokploy/package.json
  • boilerplates/dokploy/tsconfig.json
  • boilerplates/eslint/files/$package.json.ts
  • boilerplates/eslint/package.json
  • boilerplates/express/files/$package.json.ts
  • boilerplates/fastify/files/$package.json.ts
  • boilerplates/h3/files/$package.json.ts
  • boilerplates/hono/files/$package.json.ts
  • boilerplates/kysely/files/$vite.config.ts.ts
  • boilerplates/kysely/files/vite-plugin-input.ts
  • boilerplates/kysely/package.json
  • boilerplates/oxlint/bati.config.ts
  • boilerplates/pnpm/files/$pnpm-workspace.yaml.ts
  • boilerplates/shadcn-ui/files/$package.json.ts
  • boilerplates/shared/files/$package.json.ts
  • boilerplates/shared/files/package.json
  • boilerplates/sqlite/files/$package.json.ts
  • boilerplates/storybook/files/$package.json.ts
  • boilerplates/vercel/files/$package.json.ts
  • boilerplates/wip/VPS.md
  • packages/build/src/operations/transform.ts
  • packages/cli/index.ts
  • packages/cli/rules.ts
  • packages/core/src/dockerfile.ts
  • packages/core/src/index.ts
  • packages/core/src/loaders.ts
  • packages/core/src/parse.ts
  • packages/core/src/parse/yaml.ts
  • packages/core/src/runtime.ts
  • packages/core/tests/dockerfile.spec.ts
  • packages/core/tests/transform-ts.spec.ts
  • packages/core/tests/transform-vue.spec.ts
  • packages/core/tests/transform-yaml.spec.ts
  • packages/features/src/features.ts
  • packages/features/src/helpers.ts
  • packages/features/src/rules/enum.ts
  • packages/features/src/rules/rules.ts
  • packages/tests-utils/package.json
  • packages/tests-utils/src/describe.ts
  • packages/tests-utils/src/exec.ts
  • packages/tests-utils/src/index.ts
  • packages/tests-utils/src/is-docker-available.ts
  • packages/tests-utils/src/prepare.ts
  • packages/tests-utils/src/run-dev.ts
  • packages/tests-utils/src/run-docker-compose.ts
  • packages/tests-utils/src/run-prod.ts
  • packages/tests-utils/src/suite.ts
  • packages/tests-utils/src/types.ts
  • packages/tests-utils/src/wait-for-localhost.ts
  • packages/tests/src/common.ts
  • packages/tests/src/exec-bati.ts
  • packages/tests/src/index.ts
  • packages/tests/src/load-test-files.ts
  • packages/tests/src/prepare.ts
  • packages/tests/tests/FRAMEWORK+ANALYTICS.spec.ts
  • packages/tests/tests/FRAMEWORK+CSS.spec.ts
  • packages/tests/tests/FRAMEWORK+SERVER+AUTH.spec.ts
  • packages/tests/tests/FRAMEWORK+SERVER+DATA.spec.ts
  • packages/tests/tests/FRAMEWORK+aws.spec.ts
  • packages/tests/tests/FRAMEWORK+cloudflare.spec.ts
  • packages/tests/tests/FRAMEWORK+edgeone.spec.ts
  • packages/tests/tests/FRAMEWORK+netlify.spec.ts
  • packages/tests/tests/FRAMEWORK+prettier.spec.ts
  • packages/tests/tests/FRAMEWORK+prisma.spec.ts
  • packages/tests/tests/FRAMEWORK+sentry.spec.ts
  • packages/tests/tests/FRAMEWORK+storybook.spec.ts
  • packages/tests/tests/FRAMEWORK+vercel.spec.ts
  • packages/tests/tests/react+UI.spec.ts
  • packages/tests/tests/remove-linter-comments.spec.ts
  • website/components/RulesMessages.tsx

📝 Walkthrough

Walkthrough

This PR restructures E2E testing into sibling workspaces, introduces Docker/Dokploy boilerplate support with Dockerfile generation, implements a deterministic Suite API for test matrices, adds SQLite server requirement validation, supports YAML BATI comments, and reclassifies build tool dependencies as devDependencies across boilerplates.

Changes

Docker/Dokploy Support and E2E Test Workspace Infrastructure

Layer / File(s) Summary
Dockerfile Builder and Package Manager Utilities
packages/core/src/dockerfile.ts, packages/core/tests/dockerfile.spec.ts, packages/core/src/index.ts, packages/core/src/loaders.ts
Generic DockerfileBuilder class with chainable .from(), .run(), .copy(), .env(), .cmd() methods, support for multi-stage builds via stage aliases, conditional composition (.when(), .pipe()), and DockerPackageManager factory selecting npm/pnpm/yarn/bun with lockfile and corepack configuration.
Docker Compose Boilerplate Scaffolding
boilerplates/docker-compose/bati.config.ts, boilerplates/docker-compose/files/$.dockerignore.ts, boilerplates/docker-compose/files/$Dockerfile.ts, boilerplates/docker-compose/files/docker-compose.yml, boilerplates/docker-compose/package.json, boilerplates/docker-compose/tsconfig.json
New docker-compose boilerplate with Dockerfile generation (multi-stage build with conditional migration setup), docker-compose.yml service definition, .dockerignore with BATI_TEST-conditional e2e exclusions, and standard boilerplate package/tsconfig files.
Dokploy Boilerplate and Configuration
boilerplates/dokploy/bati.config.ts, boilerplates/dokploy/files/$TODO.md.ts, boilerplates/dokploy/files/$package.json.ts, boilerplates/dokploy/package.json, boilerplates/dokploy/tsconfig.json, boilerplates/wip/VPS.md
Dokploy boilerplate with configuration conditioned on dokploy flag, TODO.md generator with setup checklist, package.json prod script override to docker compose up -d --build, and PaaS comparison documentation.
GitHub Workflow E2E Directory Structure
.github/workflows/reusable.run-tests.yml, .github/workflows/tests-entry.yml
Workflows updated to create per-matrix .e2e sibling directories with TEST_DIR environment variable, reroute e2e setup/quality gates to execute from the dedicated e2e workspace, and update matrix definitions to map destinations to test files and flags.
E2E Workspace Creation and Management
packages/tests/src/common.ts
E2EWorkspaceOptions interface and createE2EWorkspace() function that generate sibling .e2e directories with package.json (vitest/knip pinned, @batijs/tests-utils reference, optional packageManager), vitest config, and bati config.
Test Utilities: Docker Compose and Availability
packages/tests-utils/src/is-docker-available.ts, packages/tests-utils/src/run-docker-compose.ts, packages/tests-utils/src/prepare.ts, packages/tests-utils/src/run-dev.ts, packages/tests-utils/src/run-prod.ts
Docker availability check, runDockerCompose()/stopDockerCompose() lifecycle management, updated prepare() with dynamic mode resolution, docker mode support, and conditional skip when docker unavailable; preHooks/postHooks replaced prior unified hooks lifecycle.
Suite API and Balancer for Deterministic Test Matrices
packages/tests-utils/src/suite.ts
Chainable Suite DSL with .matrix() (cartesian product), .case() (explicit combos), .linters() (appended flags); Balancer for round-robin axis selection; spread() markers for framework distribution; .flatten() resolves spreads, validates via execRules, and drops invalid combos with warnings.
Test File Loading with Suite-Based Matrices
packages/tests/src/load-test-files.ts
loadTestFileMatrix() updated to accept Balancer, expect default Suite export, flatten matrices deterministically, and validate all generated flags exist in @batijs/features.
Test Specification Migration to Suite API
packages/tests/tests/FRAMEWORK+*.spec.ts, packages/tests/tests/react+UI.spec.ts, packages/tests/tests/remove-linter-comments.spec.ts
All test specs migrated from static export const matrix to export default suite().matrix(...).linters(...) pattern; updated testMatch generics to use derived TestFlags type.
Test Execution and Index Updates
packages/tests/src/index.ts
Test index refactored to pack tests-utils, create per-matrix .e2e workspaces, load matrices sequentially with shared Balancer, and execute two-pass Nx targets (app targets excluding *-e2e, then *-e2e targets).
Test Preparation and E2E Workspace Setup
packages/tests/src/prepare.ts
prepare() updated to derive appName and packageManagerSpec from context, call createE2EWorkspace() with test file references, and remove prior in-app config mutations.
describeBati and Hook Restructuring
packages/tests-utils/src/describe.ts
describeBati updated to select vitest.describe.skip vs vitest.describe.concurrent based on skip flag, replace p.hooks() with explicit preHooks()/postHooks() lifecycle, and wire testMatch into test context.

Core Infrastructure: BatiSet, YAML, SQLite Rule, Dependencies

Layer / File(s) Summary
BatiSet Package Manager Field
packages/features/src/helpers.ts, packages/cli/index.ts, packages/core/tests/transform-ts.spec.ts, packages/core/tests/transform-vue.spec.ts
BatiSet constructor extended to accept and store pm: string; CLI and all test instantiations updated to pass pm.name as third argument.
YAML Transformation and BATI Comments
packages/core/src/parse/yaml.ts, packages/core/src/parse.ts, packages/core/tests/transform-yaml.spec.ts
transformYaml() function detects and processes BATI comment lines, removes YAML nodes when conditions are false, strips comments while preserving non-BATI comments when true; transformAndFormat() routes YAML files to YAML-specific transformer; comprehensive test coverage for sequence/mapping/top-level removal and non-BATI comment preservation.
SQLite Server Requirement Rule and Messages
packages/features/src/rules/enum.ts, packages/features/src/rules/rules.ts, packages/cli/rules.ts, website/components/RulesMessages.tsx
Enum member ERROR_SQLITE_R_SERVER and rule requiring "Server" feature for "sqlite" added; error message and website component updated with guidance.
Package Manager Runtime Detection (Bun)
packages/core/src/runtime.ts
packageManager() updated to detect Bun first via process.versions.bun, then fall back to npm_config_user_agent parsing, returning Bun-specific run/exec commands.
Vite Build Tool Dependency Reclassification
boilerplates/express/files/$package.json.ts, boilerplates/fastify/files/$package.json.ts, boilerplates/h3/files/$package.json.ts, boilerplates/hono/files/$package.json.ts, boilerplates/shared/files/$package.json.ts
Vite moved from dependencies to devDependencies; @types/node added where needed for TypeScript support.
Other Build Tool Dependency Updates
boilerplates/aws/files/$package.json.ts, boilerplates/shadcn-ui/files/$package.json.ts, boilerplates/kysely/files/$vite.config.ts.ts, boilerplates/kysely/files/vite-plugin-input.ts, boilerplates/kysely/package.json, boilerplates/vercel/files/$package.json.ts, boilerplates/eslint/files/$package.json.ts, boilerplates/eslint/package.json, boilerplates/oxlint/bati.config.ts, boilerplates/pnpm/files/$pnpm-workspace.yaml.ts, boilerplates/storybook/files/$package.json.ts, boilerplates/sqlite/files/$package.json.ts
AWS CDK tools, tw-animate-css, vite-plugin-vercel moved to devDependencies; eslint adds jiti; kysely vite plugin support; oxlint adds knip ignore rules; pnpm workspace restructures allowBuilds map; storybook and sqlite update dependency registration.
Test Utility Supporting Changes
packages/tests-utils/src/exec.ts, packages/tests-utils/src/wait-for-localhost.ts, packages/tests-utils/src/types.ts
Exec error messages include debug context (cwd); waitForLocalhost tightens signature to require port/timeout/debug; Modes type expanded to include docker mode.
Transform and Build Configuration
packages/build/src/operations/transform.ts, boilerplates/shared/files/$package.json.ts
Dockerfile and .dockerignore added to supported extensions; shared boilerplate generates package.json programmatically via transformer instead of static file.
Bati Execution Timeout Tuning
packages/tests/src/exec-bati.ts
execLocalBati() computes dynamic timeout based on storybook presence (120s for storybook, 30s otherwise) and applies to both execution paths.
Self-Hosted PaaS Comparison Documentation
boilerplates/wip/VPS.md
Added comparison document for Dokploy, Coolify, CapRover, Dokku, and Piku with feature matrices and platform-specific setup/monitoring details.

@magne4000

Copy link
Copy Markdown
Member Author

@copilot use https://github.com/ota-meshi/yaml-eslint-parser to add support for yaml in bati's builder. Update necessary code so that yaml "compilation" is also supported through "BATI.has(...)" comments.
Then update boilerplates/docker-compose/files/docker-compose.yml to use the comment-based syntax instead of squirelly

Copilot AI and others added 2 commits May 19, 2026 09:02
Agent-Logs-Url: https://github.com/vikejs/bati/sessions/b0dadd27-1f60-4787-9569-08e94867122d

Co-authored-by: magne4000 <1098371+magne4000@users.noreply.github.com>
Agent-Logs-Url: https://github.com/vikejs/bati/sessions/b0dadd27-1f60-4787-9569-08e94867122d

Co-authored-by: magne4000 <1098371+magne4000@users.noreply.github.com>

Copilot AI commented May 19, 2026

Copy link
Copy Markdown
Contributor

@copilot use https://github.com/ota-meshi/yaml-eslint-parser to add support for yaml in bati's builder. Update necessary code so that yaml "compilation" is also supported through "BATI.has(...)" comme...

Done in commit 7125bbd.

Instead of yaml-eslint-parser, I used the yaml library (already a dependency of @batijs/core) which turned out to be simpler and lighter — parseDocument + visit handles the AST traversal cleanly, and doc.toString() produces a perfect round-trip with no need for prettier.

What was added:

  • packages/core/src/parse/yaml.ts — new transformYaml() function that uses yaml's visit() to find commentBefore on:
    • Pair nodes (mapping key-value pairs) — handles # BATI.hasDatabase before volumes:
    • Scalar nodes within sequences — handles # BATI.has("authjs") before - AUTH_SECRET=...
    • Map nodes within sequences — handles map-type sequence entries (e.g. - key: value)
  • packages/core/src/parse.ts — YAML files are now routed through transformYaml instead of the ESLint transformer; squirelly still works for YAML if needed
  • boilerplates/docker-compose/files/docker-compose.yml — all /*{ @if ... }*/ blocks replaced with # BATI.has(...) / # BATI.hasDatabase comment syntax
  • packages/core/tests/transform-yaml.spec.ts — 10 unit tests covering all cases

@magne4000

Copy link
Copy Markdown
Member Author

@copilot generate Dockerfile dynamically (by transforming it to $Dockerfile.ts).
Then:

  • replace ni usage with packageManager variable do dynamically generate the right command
  • Condionally add additional commands when 'nextSteps' of type 'command' are present. The goal is to generate a Dockerfile that works OOTB, nextSteps included

Copilot AI and others added 2 commits May 19, 2026 11:58
…r support and nextSteps commands

Agent-Logs-Url: https://github.com/vikejs/bati/sessions/06bc5f0e-a594-4573-94e0-aa62ab057700

Co-authored-by: magne4000 <1098371+magne4000@users.noreply.github.com>
Agent-Logs-Url: https://github.com/vikejs/bati/sessions/06bc5f0e-a594-4573-94e0-aa62ab057700

Co-authored-by: magne4000 <1098371+magne4000@users.noreply.github.com>

Copilot AI commented May 19, 2026

Copy link
Copy Markdown
Contributor

@copilot generate Dockerfile dynamically (by transforming it to $Dockerfile.ts).
Then:

  • replace ni usage with packageManager variable do dynamically generate the right command
    ...

Done in commit a5e92bc (with bun.lockb fix in c643766).

The static Dockerfile has been replaced with a dynamic $Dockerfile.ts that:

  • Uses packageManager() for all install/run commands (e.g. npm ci, pnpm install --frozen-lockfile, etc.) with the correct lockfile per package manager
  • Adds RUN drizzle:generate in the builder stage when drizzle is selected
  • Prepends migration commands (sqlite:migrate, drizzle:migrate, kysely:migrate) to the startup CMD when the corresponding features are active, e.g. CMD ["sh", "-c", "npm run sqlite:migrate && node ./dist/server/index.mjs"]
  • Copies migration source files to the runner stage so migration scripts can find them
  • Installs all deps (not just prod) in the runner when migrations are needed, since tools like tsx and drizzle-kit are devDeps

@magne4000

Copy link
Copy Markdown
Member Author

@copilot remove dokploy dedicated e2e test file. Then:

  • Update existing SERVER+AUTH, SERVER+DATA to add dokploy in it, excluding most combinations so that they are only tested once per data-fetch (and without) layer and once per db (and without).
  • Add new tests in mode: "prod" that will actually run docker-compose and run relevant tests

@magne4000 magne4000 marked this pull request as ready for review May 26, 2026 14:09
@magne4000 magne4000 merged commit 8bd353a into main May 26, 2026
177 of 179 checks passed
@magne4000 magne4000 deleted the magne4000/dev branch May 26, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants