This one cost me a whole bunch of time. Annoyingly I got a Docker version of Postgres 16 working on one machine, but a couple of days later I needed to update another and I hit this error:
docker-compose up
Creating postgres-test_db_1 ... done
Attaching to postgres-test_db_1
db_1 | popen failure: Cannot allocate memory
db_1 | initdb: error: program "postgres" is needed by initdb but was not found in the same directory as "/usr/lib/postgresql/16/bin/initdb"
Code language: Shell Session (shell)
Somewhat fortunately for me, this time around, was that this was a test setup I have used previous for Postgres testing. So I had a really slimmed down config in my docker-compose.yaml
:
# docker-compose.yaml
version: '3.9'
services:
db:
image: postgres:15.2
ports:
- "5445:5432"
environment:
POSTGRES_DB: app_db
POSTGRES_USER: app_user
POSTGRES_PASSWORD: my_top_secret_password
volumes:
- "./init.sql:/docker-entrypoint-initdb.d/init.sql"
Code language: YAML (yaml)
That’s the original starting point, though it doesn’t matter too much which version you are starting with.
I wanted to upgrade this to Postgres 16 as part of another blog post I am writing, and wanted to capture the error message I get on the terminal if just swapping out the Postgres image version to something higher.
However, when I swapped to this config:
# docker-compose.yaml
version: '3.9'
services:
db:
image: postgres:16
ports:
- "5445:5432"
environment:
POSTGRES_DB: app_db
POSTGRES_USER: app_user
POSTGRES_PASSWORD: my_top_secret_password
#volumes:
# - "./init.sql:/docker-entrypoint-initdb.d/init.sql"
Code language: YAML (yaml)
And then:
docker-compose up
Creating postgres-test_db_1 ... done
Attaching to postgres-test_db_1
db_1 | popen failure: Cannot allocate memory
db_1 | initdb: error: program "postgres" is needed by initdb but was not found in the same directory as "/usr/lib/postgresql/16/bin/initdb"
Code language: JavaScript (javascript)
Which totally threw me as I didn’t (thankfully) hit on this issue when recently upgrading my GitLab’s Postgres instance during a multi-hour outage.
The Fix (Err, Work Around)
So after comparing the two Docker Compose files – this one, and the working one I have for my GitLab – I found that the difference was in the working case I am using the alpine
image:
# docker-compose.yaml
version: '3.9'
services:
db:
image: postgres:16-alpine
ports:
- "5445:5432"
environment:
POSTGRES_DB: app_db
POSTGRES_USER: app_user
POSTGRES_PASSWORD: my_top_secret_password
Code language: YAML (yaml)
That’s it.
One small change and the whole thing boots without issue.
This looks to be a wider issue with any recent Docker image that relies on Debian.
The postgres:16
image uses Debian as its base. Whereas postgres:16-alpine
uses Alpine Linux as its base.
Somewhere in Debian, there is a problem way beyond my pay grade that needs to be addressed.
It actually works in my favour to use the Alpine variant, as the overall image size is smaller and I don’t need anything its fuller featured Debian variant brings. At least, not to my knowledge.
Thank you, you saved me a lot of time!
Thank you for the hint, you saved me a lot of time!