All I wanted was to launch a nice little Strapi inside a Docker container.
I type docker-compose up... and BAM → Strapi v3 😮.

“But… I asked for Strapi 4?!”

Spoiler: the official Docker image strapi/strapiit's version 3 (and it's old 😅).

Don't panic. Let me show you how to properly install Strapi v4 in Docker, without losing your sanity.

Let’s go 👇

🎯 Why doesn’t it work out of the box?

The Docker Hub image strapi/strapi was never updated for Strapi v4.
→ It always gives you Strapi v3.6.8 (RIP 🪦).

So if you want Strapi v4 + Docker → you gotta cheat a bit.

No worries, we love cheating in dev 😏.

🏗️ The correct method → use Node.js as base + mount your Strapi project.

Instead of asking for a magic “strapi v4” image,
create your Strapi v4 project locally
and run it inside a Node.js container.

Easy.

✅ 1️⃣ Create your Strapi v4 project locally

npx create-strapi@latest app

(or yarn create strapi@latest app)

Boom, you’ve got a fresh ./app folder with Strapi.

✅ 2️⃣ Write this magical docker-compose.yml

version: '3'

services:
  strapi:
    image: node:18-alpine
    container_name: techlink-strapi
    working_dir: /srv/app
    command: sh -c "yarn install && yarn build && yarn start"
    environment:
      DATABASE_CLIENT: postgres
      DATABASE_NAME: strapi
      DATABASE_HOST: postgres
      DATABASE_PORT: 5432
      DATABASE_USERNAME: strapi
      DATABASE_PASSWORD: strapi123
      NODE_ENV: production
    ports:
      - '1337:1337'
    volumes:
      - ./app:/srv/app
    depends_on:
      - postgres

  postgres:
    image: postgres:15
    container_name: techlink-postgres
    restart: always
    environment:
      POSTGRES_USER: strapi
      POSTGRES_PASSWORD: strapi123
      POSTGRES_DB: strapi
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

⚠️ Important → the ./app folder must contain your pre-created Strapi v4 project (see step 1).

✅ 3️⃣ Launch Docker, captain

docker-compose up -d

🎉 Done!
Your Strapi is available at:

👉 http://localhost:1337/admin

(and this time, it’s Strapi v4, not v3 😉)

🕵️ Why does it work?

  • We use node:18-alpine as the engine
  • We mount your local Strapi project inside the container
  • The container installs, builds, starts everything

No ghost official image needed.
YOU are the official image now 😎

🔥 Bonus option → a Dockerfile if you want a real Docker build

Want a “closed” image? Add a Dockerfile:

FROM node:18-alpine

WORKDIR /srv/app

COPY . .

RUN yarn install
RUN yarn build

EXPOSE 1337

CMD ["yarn", "start"]

Then adapt your docker-compose.yml:

strapi:
  build: .
  ports:
    - '1337:1337'
  depends_on:
    - postgres
  environment:
    DATABASE_CLIENT: postgres
    DATABASE_NAME: strapi
    DATABASE_HOST: postgres
    DATABASE_PORT: 5432
    DATABASE_USERNAME: strapi
    DATABASE_PASSWORD: strapi123

→ Docker will build it all in one go.

📝 TL;DR

strapi/strapi = Strapi v3 (DON’T use it)
✅ Create your Strapi v4 project locally
✅ Use node:18-alpine + mounted volume
✅ Or build a custom Dockerfile

There you go.

Now you can proudly say:

👉 “Yes, I have Strapi v4 running in Docker. Not v3. No cheating.”


💬 Need help with permissions, relations, API? Ping me 😉
Or share this article with your buddy struggling on Stack Overflow 🫠

TechLink powered. Peace ✌️