Skip to content

Fix a few issues in devcontainers.#2516

Merged
jackc merged 1 commit intojackc:masterfrom
abrightwell:abrightwell-fix-devcontainer
Mar 16, 2026
Merged

Fix a few issues in devcontainers.#2516
jackc merged 1 commit intojackc:masterfrom
abrightwell:abrightwell-fix-devcontainer

Conversation

@abrightwell
Copy link
Contributor

@abrightwell abrightwell commented Mar 12, 2026

While working on #2510 I encountered some issues with devcontainers that were
mostly introduced by 9b5e030e:

  • Unsupported client encoding for CRDB.
  • SSL command-line flags cause the temp server to fail before initdb has copied
    the certs.
  • :whoami user creation, when the user already exists.
  • Postgres instances sharing /var/run/postgresql race on the default socket
    port.

The client encoding issue was discovered through some failing tests.
Specifically, with error: no database or schema specified. Digging in, it
became clear that the issue was rooted in the init_crdb function in test.sh
but was being silenced as stderr is redirected to /dev/null.

On startup psql attempts to determine from the environment[1] which client
encoding to use, falling back to sqlascii[2] when not set. Unfortunately,
CRDB does not support this encoding[3], therefore attempts to setup CRDB
silently fails. We resolve this by simply setting PGCLIENTENCODING to utf8.

Removing the redirect demonstrates this:

❯ devcontainer exec --workspace-folder . ./test.sh crdb
==> Waiting for CockroachDB to be ready...
==> CockroachDB is ready
==> Ensuring pgx_test database exists on CockroachDB...
psql: error: connection to server at "localhost" (::1), port 26257 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (127.0.0.1), port 26257 failed: ERROR:  unimplemented: unimplemented client encoding: "sqlascii"
HINT:  You have attempted to use a feature that is not yet implemented.
See: https://go.crdb.dev/issue-v/35882/v25.4

The SSL flag is a bit of a chicken-egg issue. The Docker entrypoint starts a
temporary server, using it to run initialization scripts, passing it the same
command-line arguments as the final server[4,5]. So, the problem is that because
-c ssl=on is set, the temporary server looks for the cert files that it is
trying to create. The seemingly simplest solution to this is to just move the
SSL configuration out of the command-line arguments and into postgresql.conf
directly.

The :whoami user creation was an interesting one. The simple explanation is
that when the setup script is run by the container, the user is postgres,
which obviously already exists. And further, since ON_ERROR_STOP is set[6],
this causes the execution of the setup to halt. So, the solution is an attempt
to simulate what I believe CREATE USER ... IF NOT EXISTS would do if it were
actually supported.

For the pg-sockets volume issue, all instances share the same
/var/run/postgresql. Each container must have a unique PGPORT set, because the
entrypoint always appends -p ${PGPORT:-5432}[7] when starting the temporary
server, overriding any -c port= from the user command. Without it, all
temporary servers race to bind port 5432 on the shared socket volume.

[1] https://github.com/postgres/postgres/blob/03facc1211b0ff1550f41bcd4da09329080c30f9/src/bin/psql/startup.c#L157
[2] https://github.com/postgres/postgres/blob/03facc1211b0ff1550f41bcd4da09329080c30f9/src/interfaces/libpq/fe-misc.c#L1281-L1298
[3] https://go.crdb.dev/issue-v/35882/v25.4
[4] https://github.com/docker-library/postgres/blob/6edb0a8c4def40c371514b34aef9037ec82d9110/docker-entrypoint.sh#L355
[5] https://github.com/docker-library/postgres/blob/6edb0a8c4def40c371514b34aef9037ec82d9110/docker-entrypoint.sh#L377
[6] https://github.com/docker-library/postgres/blob/6edb0a8c4def40c371514b34aef9037ec82d9110/docker-entrypoint.sh#L207
[7] https://github.com/docker-library/postgres/blob/6edb0a8c4def40c371514b34aef9037ec82d9110/docker-entrypoint.sh#L292

@abrightwell abrightwell force-pushed the abrightwell-fix-devcontainer branch from 1f55cbe to 45533ef Compare March 12, 2026 22:20
@abrightwell
Copy link
Contributor Author

This was a curious one. At first I thought it might just have been my environment (and I'm happy to accept that it might be still). I also didn't I think it would be more than a single issue. So, if is helpful to vet, then I'm happy to provide debugging steps/details that led me to each issue and solution.

While working on jackc#2510 I encountered some issues with devcontainer that
were introduced by `9b5e030e`:

* Unsupported client encoding for CRDB.
* SSL command-line flags cause the temp server to fail before initdb has
  copied the certs.
* `:whoami` user creation, when the user already exists.
* Postgres instances sharing `/var/run/postgresql` race on the default
  socket port.

These changes should resolve each.
@jackc
Copy link
Owner

jackc commented Mar 16, 2026

Thanks! I had just noticed my own devcontainer setup was broken after a reset and this change seems to resolve it. Presumably, my initial SSL update only worked if the containers and volumes had already been set up by the original non-SSL testing devcontainer script.

@jackc jackc merged commit 1e9d0e9 into jackc:master Mar 16, 2026
9 of 14 checks passed
@abrightwell
Copy link
Contributor Author

Yeah, forgetting to clean up the volumes between setups was a 'gotcha' for me as well. But, I felt like it was the upstream docker image behaviors that presented the real head aches/scratchers. An interesting exercise nonetheless. 🙂

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