Skip to content

chore: monorepo devcontainer support, refactor db adapter and docker start script#16396

Open
AlessioGr wants to merge 36 commits intomainfrom
chore/devcontainers2
Open

chore: monorepo devcontainer support, refactor db adapter and docker start script#16396
AlessioGr wants to merge 36 commits intomainfrom
chore/devcontainers2

Conversation

@AlessioGr
Copy link
Copy Markdown
Member

@AlessioGr AlessioGr commented Apr 27, 2026

Devcontainers

Adds dev container configuration, so contributors can open the repo in VS Code without setting up Node, pnpm, or Docker on their own machine. Works for both "Reopen in Container" (your local clone bind-mounted in) and "Clone Repository in Container Volume" (a fresh clone inside an isolated Docker volume, useful when running multiple parallel sessions against the same repo without them stepping on each other).

test/generateDatabaseAdapter.ts was renamed to test/dbAdapters.ts and is the source of truth for anything db-adapter-related in one place: the source templates the codegen writes out, and the host/port/env-var defaults per adapter, which the new assertDbReachable.ts function uses to probe services.

This should enable running multiple agents conflict-free

DB Connection probe + docker:start script improvements

assertDbReachable is now run within pnpm dev. If the db connection fails, you now get immediate feedback through a helpful error, instead of having to wait for Next.js to compile and then be thrown off by a cryptic db seed error:

screenshot 2026-04-26 at 15 26 12@2x

pnpm docker:start is now an interactive picker. You can still pass profile names as args (pnpm docker:start postgres mongodb) to skip the prompt:

screenshot 2026-04-26 at 15 28 04@2x

These changes encourages contributors not to start every single service we have available (uses around 4gb of ram), and only start the database service that you're using => much less memory usage.


"name": "Payload Monorepo",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/payloadcms/devcontainer-features/mise-bootstrap:1": {},
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is new: https://github.com/payloadcms/devcontainer-features

Allows us to share the entire installation / package manager portion of this setup across our other repos without being repetitive.

// setup.sh auto-detects bind-mount vs volume-clone mode and handles both.
"postCreateCommand": ".devcontainer/setup.sh",
// Only the Next.js dev server should be forwarded
"forwardPorts": [3000],
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not want it to auto-forward all the databases that may be started within the container

Comment thread .devcontainer/setup.sh
fi

# Seed .env when absent
[ -f .env ] || cp .devcontainer/.env.example .env
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Through this, new clone => open in devcontainer will have an .env file with PAYLOAD_DATABASE=sqlite

Comment thread scripts/docker-clean.ts
@@ -0,0 +1,17 @@
import * as p from '@clack/prompts'
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality-wise same as before, but now a ts script, and uses clack for pretty terminal progress display

* Resolve the host:port to probe for an adapter, honoring the same URL env
* vars the adapter would. Returns null for adapters that don't need a probe.
*/
function getTarget(adapter: DatabaseAdapterType) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also work for users that use a manually installed, external db instead of our docker scripts, as it reads the db env vars just like our generated database adapter would

Comment thread test/dbAdapters.ts Outdated
}
return 'mongodb'

return 'sqlite'
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NEW: Changed the default db adapter from mongodb to sqlite. That way, this repo can be run on a fresh clone without having to install docker or doing any setup.

Comment thread test/dev.ts
process.env.TURBOPACK = '1'
}

await assertDbReachable(getCurrentDatabaseAdapter())
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early-exit if db can't connect with helpful error message, before Next.js runs

Comment thread package.json
"devsafe": "node ./scripts/delete-recursively.js '**/.next' && pnpm dev",
"docker:clean": "node ./scripts/docker-clean.js",
"docker:start": "pnpm docker:clean && docker compose -f test/docker-compose.yml --profile all up -d --wait",
"docker:clean": "node ./scripts/docker-clean.ts",
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monorepo requires a newer node version that supports running ts natively => no need for swc

@AlessioGr AlessioGr enabled auto-merge (squash) April 27, 2026 19:50
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖

Meta File Out File Size (raw) Note
packages/next/meta_index.json esbuild/index.js 985.21 KB 🆕 Added
packages/payload/meta_index.json esbuild/index.js 1.39 MB 🆕 Added
packages/payload/meta_shared.json esbuild/exports/shared.js 191.27 KB 🆕 Added
packages/richtext-lexical/meta_client.json esbuild/exports/client_optimized/index.js 287.17 KB 🆕 Added
packages/ui/meta_client.json esbuild/exports/client_optimized/index.js 1.18 MB 🆕 Added
packages/ui/meta_shared.json esbuild/exports/shared_optimized/index.js 16.32 KB 🆕 Added
Largest paths These visualization shows top 20 largest paths in the bundle.

Meta file: packages/next/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████████████▌ }}}$ 82.4%, 807.63 KB
dist/views/Version ${{\color{Goldenrod}{ █▎ }}}$ 5.3%, 51.49 KB
dist/views/Dashboard ${{\color{Goldenrod}{ ▌ }}}$ 2.2%, 21.37 KB
dist/views/Document ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 16.59 KB
dist/views/List ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 11.38 KB
dist/views/Root ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 9.90 KB
dist/views/Versions ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.17 KB
dist/views/API ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.13 KB
dist/elements/Nav ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 5.96 KB
dist/views/Account ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 5.55 KB
dist/elements/DocumentHeader ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 4.81 KB
dist/views/Login ${{\color{Goldenrod}{ }}}$ 0.4%, 4.40 KB
dist/layouts/Root ${{\color{Goldenrod}{ }}}$ 0.3%, 3.20 KB
dist/views/ForgotPassword ${{\color{Goldenrod}{ }}}$ 0.3%, 3.13 KB
dist/views/CreateFirstUser ${{\color{Goldenrod}{ }}}$ 0.3%, 2.81 KB
dist/templates/Default ${{\color{Goldenrod}{ }}}$ 0.3%, 2.64 KB
dist/views/BrowseByFolder ${{\color{Goldenrod}{ }}}$ 0.3%, 2.61 KB
dist/views/CollectionFolders ${{\color{Goldenrod}{ }}}$ 0.2%, 2.44 KB
dist/views/ResetPassword ${{\color{Goldenrod}{ }}}$ 0.2%, 2.40 KB
dist/views/Logout ${{\color{Goldenrod}{ }}}$ 0.2%, 1.94 KB
(other) ${{\color{Goldenrod}{ ████▍ }}}$ 17.6%, 172.90 KB

Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ █████████████████▏ }}}$ 68.7%, 951.98 KB
dist/fields/hooks ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 44.07 KB
dist/collections/operations ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 39.96 KB
dist/versions/migrations ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 18.50 KB
dist/auth/operations ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 15.63 KB
dist/fields/config ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 14.16 KB
dist/globals/operations ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 13.32 KB
dist/utilities/configToJSONSchema.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 13.13 KB
dist/queues/operations ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 12.71 KB
dist/fields/validations.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 10.54 KB
dist/bin/generateImportMap ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 9.08 KB
dist/collections/config ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 8.91 KB
dist/config/orderable ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 8.00 KB
dist/uploads/fetchAPI-multipart ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.80 KB
dist/index.js ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.79 KB
dist/database/migrations ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 7.54 KB
dist/config/sanitize.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 6.26 KB
dist/collections/endpoints ${{\color{Goldenrod}{ }}}$ 0.4%, 6.23 KB
dist/auth/strategies ${{\color{Goldenrod}{ }}}$ 0.4%, 5.50 KB
dist/queues/config ${{\color{Goldenrod}{ }}}$ 0.4%, 5.31 KB
(other) ${{\color{Goldenrod}{ ███████▊ }}}$ 31.3%, 433.11 KB

Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ███████████████████▊ }}}$ 79.4%, 148.89 KB
dist/fields/validations.js ${{\color{Goldenrod}{ █▍ }}}$ 5.6%, 10.54 KB
dist/config/orderable ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 3.13 KB
dist/fields/baseFields ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 2.79 KB
dist/utilities/deepCopyObject.js ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 2.54 KB
dist/auth/cookies.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 1.55 KB
dist/utilities/flattenTopLevelFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 1.42 KB
dist/fields/config ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 1.28 KB
dist/utilities/getVersionsConfig.js ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 1.04 KB
dist/utilities/flattenAllFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 943 B
dist/folders/utils ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 916 B
dist/utilities/unflatten.js ${{\color{Goldenrod}{ }}}$ 0.4%, 779 B
dist/utilities/sanitizeUserDataForEmail.js ${{\color{Goldenrod}{ }}}$ 0.4%, 713 B
dist/utilities/getFieldPermissions.js ${{\color{Goldenrod}{ }}}$ 0.3%, 651 B
dist/collections/config ${{\color{Goldenrod}{ }}}$ 0.3%, 570 B
dist/bin/generateImportMap ${{\color{Goldenrod}{ }}}$ 0.3%, 561 B
dist/auth/sessions.js ${{\color{Goldenrod}{ }}}$ 0.3%, 525 B
dist/fields/getFieldPaths.js ${{\color{Goldenrod}{ }}}$ 0.3%, 485 B
dist/utilities/getSafeRedirect.js ${{\color{Goldenrod}{ }}}$ 0.2%, 423 B
dist/utilities/deepMerge.js ${{\color{Goldenrod}{ }}}$ 0.2%, 413 B
(other) ${{\color{Goldenrod}{ █████▏ }}}$ 20.6%, 38.72 KB

Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
dist/features/blocks ${{\color{Goldenrod}{ ███▏ }}}$ 12.8%, 36.34 KB
dist/lexical/plugins ${{\color{Goldenrod}{ ██▉ }}}$ 11.5%, 32.65 KB
dist/lexical/ui ${{\color{Goldenrod}{ ██▏ }}}$ 8.6%, 24.36 KB
dist/features/experimental_table ${{\color{Goldenrod}{ ██ }}}$ 8.3%, 23.70 KB
dist/packages/@lexical ${{\color{Goldenrod}{ █▋ }}}$ 6.7%, 18.99 KB
dist/features/link ${{\color{Goldenrod}{ █▋ }}}$ 6.5%, 18.53 KB
dist/features/toolbars ${{\color{Goldenrod}{ █▍ }}}$ 5.7%, 16.08 KB
dist/features/upload ${{\color{Goldenrod}{ █▏ }}}$ 4.9%, 13.77 KB
dist/features/textState ${{\color{Goldenrod}{ ▉ }}}$ 3.9%, 11.08 KB
dist/features/relationship ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 9.03 KB
dist/lexical/utils ${{\color{Goldenrod}{ ▊ }}}$ 3.1%, 8.79 KB
dist/features/converters ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 8.36 KB
dist/features/debug ${{\color{Goldenrod}{ ▋ }}}$ 2.6%, 7.40 KB
dist/utilities/fieldsDrawer ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 7.15 KB
dist/lexical/config ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 5.08 KB
dist/features/lists ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 5.00 KB
dist/features/format ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 3.46 KB
dist/lexical/LexicalEditor.js ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.23 KB
dist/field/Field.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 2.80 KB
dist/lexical/nodes ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 2.66 KB
(other) ${{\color{Goldenrod}{ █████████████████████▊ }}}$ 87.2%, 247.60 KB

Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████▎ }}}$ 49.3%, 579.12 KB
dist/elements/FolderView ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 29.38 KB
dist/elements/BulkUpload ${{\color{Goldenrod}{ ▌ }}}$ 2.4%, 28.24 KB
dist/elements/WhereBuilder ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 17.36 KB
dist/views/Edit ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 17.30 KB
dist/forms/Form ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 15.91 KB
dist/fields/Relationship ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 15.79 KB
dist/elements/Table ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 15.77 KB
dist/fields/Upload ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 14.22 KB
dist/fields/Blocks ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 13.90 KB
dist/elements/QueryPresets ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 10.36 KB
dist/elements/PublishButton ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 9.11 KB
dist/providers/Folders ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.46 KB
dist/elements/HTMLDiff ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.38 KB
dist/elements/ListHeader ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.06 KB
dist/fields/Array ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 7.73 KB
dist/views/CollectionFolder ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.50 KB
dist/views/List ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.36 KB
dist/elements/ReactSelect ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.33 KB
dist/elements/LivePreview ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.03 KB
(other) ${{\color{Goldenrod}{ ████████████▋ }}}$ 50.7%, 595.21 KB

Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js

Path Size
dist/graphics/Logo ${{\color{Goldenrod}{ █████ }}}$ 20.0%, 3.12 KB
../../node_modules ${{\color{Goldenrod}{ ████▎ }}}$ 17.0%, 2.65 KB
dist/graphics/Icon ${{\color{Goldenrod}{ ██▍ }}}$ 9.8%, 1.52 KB
dist/utilities/formatDocTitle ${{\color{Goldenrod}{ ██▏ }}}$ 8.5%, 1.32 KB
dist/providers/TableColumns ${{\color{Goldenrod}{ █▍ }}}$ 5.5%, 862 B
dist/utilities/groupNavItems.js ${{\color{Goldenrod}{ █▎ }}}$ 5.2%, 814 B
dist/utilities/getGlobalData.js ${{\color{Goldenrod}{ █▏ }}}$ 4.9%, 762 B
dist/utilities/api.js ${{\color{Goldenrod}{ █▏ }}}$ 4.8%, 756 B
dist/elements/Translation ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 493 B
dist/utilities/handleTakeOver.js ${{\color{Goldenrod}{ ▋ }}}$ 2.8%, 440 B
dist/utilities/traverseForLocalizedFields.js ${{\color{Goldenrod}{ ▋ }}}$ 2.6%, 399 B
dist/elements/withMergedProps ${{\color{Goldenrod}{ ▌ }}}$ 2.2%, 339 B
dist/utilities/getVisibleEntities.js ${{\color{Goldenrod}{ ▌ }}}$ 2.1%, 329 B
dist/utilities/getNavGroups.js ${{\color{Goldenrod}{ ▍ }}}$ 1.9%, 301 B
dist/elements/WithServerSideProps ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 232 B
dist/utilities/handleGoBack.js ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 180 B
dist/fields/mergeFieldStyles.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 159 B
dist/utilities/handleBackToDashboard.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 152 B
dist/forms/Form ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 147 B
dist/utilities/abortAndIgnore.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 146 B
(other) ${{\color{Goldenrod}{ ████████████████████ }}}$ 80.0%, 12.51 KB
Details

Next to the size is how much the size has increased or decreased compared with the base branch of this PR.

  • ‼️: Size increased by 20% or more. Special attention should be given to this.
  • ⚠️: Size increased in acceptable range (lower than 20%).
  • ✅: No change or even downsized.
  • 🗑️: The out file is deleted: not found in base branch.
  • 🆕: The out file is newly found: will be added to base branch.

@AlessioGr AlessioGr disabled auto-merge April 27, 2026 20:06
@AlessioGr AlessioGr enabled auto-merge (squash) April 27, 2026 20:06
Copy link
Copy Markdown
Contributor

@GermanJablo GermanJablo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, thank you!

  1. My main suggestion would be to use @devcontainers/cli instead of the VS Code extension, as I mentioned in a comment below.
  2. It is great that we all share a unified environment. Still, I am a bit concerned this might hide bugs that only appear in specific setups like different operating systems or versions of Node or pnpm. I agree the tradeoff is probably worth it, and more testing is likely the only real safeguard. I just wanted to flag it.
  3. Aside from that, below I copy the review of Opus 4.7 after removing a couple of suggestions that seemed irrelevant to me:
Claude Review

Blockers

1) docker:clean and docker:start will not run on Node 18 / 20 (declared engines)

package.json runs them with bare node:

"docker:clean": "node ./scripts/docker-clean.ts",
"docker:start": "node ./scripts/docker-start.ts",

But engines.node is ^18.20.2 || >=20.9.0. Native TS stripping (--experimental-strip-types) only exists on Node 22.6+, and the imports use .ts extensions ('./docker-lib.ts', '../test/dbAdapters.ts'), which require additional flags even on Node 22+. The rest of the repo uses the pnpm runts wrapper (which loads @swc-node/register). These scripts should do the same:

"docker:clean": "pnpm runts ./scripts/docker-clean.ts",
"docker:start": "pnpm runts ./scripts/docker-start.ts",

Note that runts is defined with --no-experimental-strip-types, indicating the project intentionally avoids native stripping. Keep it consistent.

2) Inconsistent default DB adapter

The PR changes the default from mongodb to sqlite:

test/dbAdapters.ts:

export const getCurrentDatabaseAdapter = (): DatabaseAdapterType => {
  const dbAdapter = process.env.PAYLOAD_DATABASE as DatabaseAdapterType | undefined
  if (dbAdapter && Object.keys(dbAdapters).includes(dbAdapter)) {
    return dbAdapter
  }

  return 'sqlite'
}

test/vitest.setup.ts:

if (!process.env.PAYLOAD_DATABASE) {
  process.env.PAYLOAD_DATABASE = 'sqlite'
}

But test/initDevAndTest.ts was left on 'mongodb':

const dbAdapter: DatabaseAdapterType =
  (process.env.PAYLOAD_DATABASE as DatabaseAdapterType) || 'mongodb'

Pick one and apply it everywhere. Also call out the change in the PR description and update CLAUDE.md / CONTRIBUTING.md accordingly (current CLAUDE.md still says "Default database is MongoDB").

Pre-merge cleanup

3) pnpm-lock.yaml contains unrelated changes

A fair amount of churn around next@16.2.3(@babel/core@7.29.0)(...) peer-dep injection, unrelated to @clack/prompts. Likely a re-resolve from a stale lockfile. Rebase onto main and regenerate the lock so the diff stays scoped to the actual change.

4) package.json: @clack/prompts is alphabetically out of order

"@swc-node/register": "1.11.1",
"@swc/cli": "0.7.9",
"@swc/core": "1.15.3",
"@clack/prompts": "1.2.0",
"@types/fs-extra": "^11.0.2",

Should sit before @swc-node/register.

5) .devcontainer/.dockerignore is probably not honored

Docker reads .dockerignore from the build context root, not from .devcontainer/. Since devcontainer.json uses image: directly (no custom build context), this file does not take effect unless the config is restructured to use dockerfile + context. Either move it to the repo root or drop it.

Suggestions

6) assertDbReachable 2000 ms timeout

const result = await tcpPing(target.host, target.port, 2000)

In CI with loaded runners or cold-starting containers, 2 s can be tight. Locally it is great UX. Consider bumping to 5–10 s in CI or adding a short retry with backoff.

7) Misleading probe for cosmosdb / documentdb / firestore

These share the MONGO block, so they probe localhost:27018 even though they actually point to cloud services. If the user has not set MONGODB_URL, the probe can:

  • Pass deceptively when a local MongoDB happens to be running, or
  • Fail with a message suggesting pnpm docker:start mongodb, which does not apply

Skip the probe for these adapters unless MONGODB_URL is set.

8) scripts/docker-start.ts hardcodes storage ports

{
  name: 'storage',
  label: 'LocalStack, Azurite, fake-GCS, Vercel Blob',
  hint: '4443, 3100, 4566, 10000',
},

For postgres/mongo the hint is computed from dbAdapters, but storage is hardcoded. If compose ports change it drifts. Consider adding a port map for non-DB services in dbAdapters.ts or docker-lib.ts.

Comment thread CONTRIBUTING.md Outdated
@AlessioGr
Copy link
Copy Markdown
Member Author

  1. docker:clean and docker:start will not run on Node 18 / 20 (declared engines)

Done, I got rid of the engines property. We already have .tool-versions, and engines was out of date. Node 24.13.0 is expected in our monorepo, and we can get rid of runts in a separate PR

  1. Inconsistent default DB adapter

Done

  1. pnpm-lock.yaml contains unrelated changes

Lockfile is up-to-date, so doesn't matter

  1. package.json: @clack/prompts is alphabetically out of order

Done

  1. .devcontainer/.dockerignore is probably not honored

Done, deleted it

  1. assertDbReachable 2000 ms timeout

Done, bumped to 10s when in ci

  1. Misleading probe for cosmosdb / documentdb / firestore

We test against these db adapters using the same local mongodb but with compatibility options set, so I don't think the probe doesn't apply here

  1. scripts/docker-start.ts hardcodes storage ports

Don't think it matters whether the hardcoded ports are in docker-start.ts or docker-lib.ts since they are only read in one place. This is simpler


It is great that we all share a unified environment. Still, I am a bit concerned this might hide bugs that only appear in specific setups like different operating systems or versions of Node or pnpm. I agree the tradeoff is probably worth it, and more testing is likely the only real safeguard. I just wanted to flag it.

Yea, only way to address this is to run CI against different systems. This change is only optional though, people can still use their own machine / manually installed or external databases

@AlessioGr AlessioGr requested a review from GermanJablo April 28, 2026 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants