KubeKanvas Logo
FeaturesPricingTemplatesBlogFAQsContactBook a Demo
Book a Demo
FeaturesPricingTemplatesBlogFAQsContactBook a Demo

Building a Modern Blog with Strapi & Kubernetes: Your First CMS in the Cloud

Learn how to build and run a modern blog CMS using Strapi in Kubernetes. This first part walks you through building a Strapi Docker image, deploying it in Kubernetes, testing it via port-forwarding, and exposing it using a service. Perfect for developers who want full control and flexibility over their content backend.

Shamaila Mahmood

Shamaila Mahmood

July 23, 2025

Cloud-Native Web Applications
Building a Modern Blog with Strapi & Kubernetes: Your First CMS in the Cloud

Welcome to your journey of building a modern blog platform! This is Part 1 of a 3-part series where we'll go from zero to a production-ready blog.

🎯 What We're Building

By the end of this series, you'll have:

  • Part 1: A Strapi CMS running in Kubernetes (that's today! πŸš€)
  • Part 2: A beautiful Next.js frontend
  • Part 3: Everything secured and production-ready

Let's start simple and build our way up. Today, we're just getting Strapi running!


Why Start with Strapi?

Think of Strapi as your content creation headquarters. It's where you (or your team) will write blog posts, upload images, and manage everything content-related.

The best part? Strapi gives you a nice admin interface while providing APIs that any frontend can consume. It's like having a WordPress admin panel, but way more flexible.

What You Get Out of the Box

  • ✏️ Content Editor: Write and manage your blog posts
  • πŸ“ Media Library: Upload and organize images
  • πŸ‘₯ User Management: Control who can access what
  • πŸ”Œ APIs: RESTful and GraphQL endpoints ready to go. For blog my personal favorite is GraphQL and I have almost always used it for all the blogs that I have built with strapi.

Step 1: Build Your Own Strapi Image

Here's the thing: the official Strapi Docker images on Docker Hub are quite outdated and can cause compatibility issues. The best approach is to build your own fresh Strapi image with the latest version. If you don't want to do that you can search a strapi image on docker hub. While choosing make sure to find an image which was recently updated and contains some documentation to make it easy for you to get started. If you have found the correct image feel free to jump to step 2.

If you make the right decision and do it yourself, don't worry - it's easier than it sounds!

1.1: Create a New Strapi Project

First, let's create a fresh Strapi project locally:

# Create a new directory for our project
mkdir my-strapi-blog
cd my-strapi-blog

# Create a new Strapi project (this will take a few minutes)
npx create-strapi-app@latest . --quickstart

The --quickstart flag sets up Strapi with SQLite, which is perfect for our first deployment.

Note: You'll need Node.js 18+ installed on your machine. If you don't have it, download it from nodejs.org.

You should see something like the following if the project creation was successful.

Running strapi locally

1.2: Create a Dockerfile

In your my-strapi-blog directory, create a Dockerfile (Following was simply copied from strapi website):

FROM node:22-alpine
# Installing libvips-dev for sharp Compatibility
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}

WORKDIR /opt/
COPY package.json package-lock.json ./
RUN npm install -g node-gyp
RUN npm config set fetch-retry-maxtimeout 600000 -g && npm install
ENV PATH=/opt/node_modules/.bin:$PATH

WORKDIR /opt/app
COPY . .
RUN chown -R node:node /opt/app
USER node
RUN ["npm", "run", "build"]
EXPOSE 1337
CMD ["npm", "run", "develop"]

If you face issues building the image with this file, simply search and find the example of docker file provided at Strapi website and use it instead of the above.

1.3: Build Your Docker Image

Now let's build the image:

# Build the Docker image (this will take a few minutes)
docker build -t my-strapi-blog:latest .

Troubleshooting Build Issues: If you encounter esbuild version mismatch errors during the build, try:

# Clear npm cache and rebuild
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
docker build -t my-strapi-blog:latest .

What just happened?

  • We created a custom Docker image with the latest Strapi version
  • The image includes all dependencies and is ready to run
  • We tagged it as my-strapi-blog:latest for easy reference

1.4: Test Your Image Locally (Optional)

Want to make sure it works? Test it locally first:

# Run the container locally
docker run -p 1337:1337 my-strapi-blog:latest

Visit http://localhost:1337/admin to see if it works, then stop the container with Ctrl+C.


Step 2: Deploy to Kubernetes

Now let's deploy our custom image to Kubernetes! Just like you ran the container in your local now you have to do the exact same step in kubernetes cluster. So imagine one container running in your local kubernetes and you goal is to be able to reach it like you reached your local one.

In Kubernetes language you need a pod or a deployment running strapi. I am using deployment because we almost never use pods in real life, so lets start right.

Your Kubernetes Deployment

Create a file called strapi-deployment.yaml:


apiVersion: apps/v1
kind: Deployment
metadata:
  name: strapi
spec:
  replicas: 1
  selector:
    matchLabels:
      app: strapi
  template:
    metadata:
      labels:
        app: strapi
    spec:
      containers:
        - name: strapi
          image: my-strapi-blog:latest
          imagePullPolicy: Never
          ports:
            - containerPort: 1337

Important: The imagePullPolicy: Never tells Kubernetes to use the local Docker image we just built instead of trying to pull it from a registry.

If you are using any other image e.g. from docker hub or an image from your own organization's registry replace the my-strapi-blog:latest with your image name and also remove imagePullPolicy line.

Deploy it to your cluster:

kubectl apply -f strapi-deployment.yaml

That's it! Your custom Strapi is now running in Kubernetes. πŸŽ‰

Check If It's Working

Let's see if our pod is running:

kubectl get pods -l app=strapi

You should see something like:

NAME                      READY   STATUS    RESTARTS   AGE
strapi-7d4b8c9f4d-xyz123  1/1     Running   0          1m

If the status shows "Running", you're golden!

Note: If you see "ContainerCreating", don't worry! This just means Kubernetes is pulling the Strapi image and starting up the container. This usually takes 30-60 seconds depending on your internet connection. If it's taking longer, you can check what's happening:

kubectl describe pod -l app=strapi

Look at the "Events" section at the bottom - it'll show you if the image is being downloaded or if there are any issues.


Step 3: Access Your Strapi Admin

Right now, Strapi is running inside your cluster, but you can't access it from your browser yet. Let's use Kubernetes port-forwarding to tunnel into your cluster:

kubectl port-forward deployment/strapi 1337:1337

Now open your browser and go to: http://localhost:1337/admin

🎊 Magic moment: You should see the Strapi setup page!

Strapi Home Page

Troubleshooting Connection Issues: If you get connection errors like "Connection refused" when port-forwarding, it usually means Strapi is still starting up. Strapi can take 2-3 minutes to fully initialize on first run. Check if it's ready:

# Check if Strapi is fully started
kubectl logs -f deployment/strapi

You'll see Strapi starting up:

> my-strapi-blog@0.1.0 start
> strapi start

[2025-06-21 14:15:30.451] info: Starting Strapi application...
[2025-06-21 14:15:32.123] info: Server started on port 1337

Since we're using a pre-built image, startup is much faster - usually under 30 seconds!

Once you see that, try the port-forward command again:

kubectl port-forward deployment/strapi 1337:1337

Create Your Admin Account

Follow the setup wizard to create your first admin user. Pick a username, email, and password that you'll remember.

Once you're in the admin panel, take a moment to explore. This is your content management headquarters!


Step 4: Create Your First Blog Post

Let's make this real by creating a blog post structure:

  1. Go to "Content Manager" β†’ "Articles"
  2. Click "Create new entry"
  3. Write a sample blog post
  4. Click "Save" and then "Publish"

Congratulations! You just created your first piece of content. 🎯


What Just Happened? (The Magic Explained)

Let's take a moment to appreciate what we accomplished:

Kubernetes Deployment

We used a Deployment to tell Kubernetes: "I want one copy of Strapi running at all times." If the pod crashes, Kubernetes automatically starts a new one.

Container Magic

The my-strapi-blog:latest image contains your fresh Strapi v4 installation with all the latest dependencies. No compatibility issues, no outdated packages – just a clean, modern setup.

SQLite for Simplicity

By default, Strapi creates an SQLite database file inside the container. This means:

  • βœ… Super simple to get started
  • ❌ Data disappears when the pod restarts

That's fine for learning, but we'll fix the data persistence issue in our next iteration.


Step 5: Make It Accessible (Create a Service)

Port-forwarding is great for testing, but let's make Strapi accessible within the cluster properly. Create a strapi-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: strapi-service
  labels:
    app: strapi
spec:
  selector:
    app: strapi
  ports:
    - port: 1337
      targetPort: 1337
  type: ClusterIP

Apply it:

kubectl apply -f strapi-service.yaml

Now other applications in your cluster can reach Strapi using the DNS name strapi-service on port 1337. Pretty neat, right? In practice we will use this service in the next part of the series. For now you can use port-forward to this newly created service to access strapi deployment.

kubectl port-forward service/strapi-service 8080:1337

In browser you can now access the strapi instance using http://localhost:8080

What's Next?

You now have a working Strapi CMS running in Kubernetes! πŸš€

But there's a catch: If your pod restarts, all your content disappears because we're using SQLite inside the container.

In Part 2 of this series, we'll:

  • Start building a Next.js frontend to display your blog posts.
  • Make Strapi accessible from the internet

In part 3 of this series, we'll:

  • Add a proper PostgreSQL database with persistent storage
  • Store images on S3.

For now, enjoy exploring Strapi and creating some test content. Get familiar with the admin interface – this is where you'll be managing your blog content.


Quick Troubleshooting

Pod not starting?

kubectl describe pod -l app=strapi
kubectl logs -l app=strapi

Getting "Connection refused" during port-forward? This usually means Strapi is still starting up. Check the logs:

kubectl logs -f deployment/strapi

Wait for the message "Server started on port 1337" before trying port-forward again.

Can't access localhost:1337? Make sure port-forwarding is still running:

kubectl port-forward deployment/strapi 1337:1337

Want to start fresh?

kubectl delete deployment strapi
kubectl delete service strapi-service

See you in Part 2! πŸ‘‹

KubernetesDevOpsVisual design of Kubernetes architecture

Related Articles

Strapi and NextJS on Kubernetes - Part 2
Building and Deploying a Modern Blog Platform with Next.js, Strapi, and Kubernetes – Part 2: Adding the Frontend

Deploy Next.js + Strapi blog on Kubernetes with Docker, Ingress routing, and service discovery. Comp...

Shamaila Mahmood

Shamaila Mahmood

July 29, 2025

Cloud-Native Web Applications
Kubernetes Architecture Series – Part 2: Designing Scalable and Resilient Applications
Kubernetes Architecture Series – Part 2: Designing Scalable and Resilient Applications

This is the second part of our three-part Kubernetes architecture series.

Khurram Mahmood

Khurram Mahmood

July 27, 2025

Kubernetes Architecture
Kubernetes Architecture Series - Part 1: From Containers to Cloud-Native Orchestration
Kubernetes Architecture Series - Part 1: From Containers to Cloud-Native Orchestration

Part 1 of the three-part blog series on Kubernetes architecture

Khurram Mahmood

Khurram Mahmood

July 23, 2025

Kubernetes Architecture
Deep Dive: The Magic Behind KubeKanvas – Feature by Feature
Deep Dive: The Magic Behind KubeKanvas – Feature by Feature

Visualize, validate, and deploy Kubernetes configs with easeβ€”discover the power of KubeKanvas beyond...

Essa Hashmi

Essa Hashmi

July 15, 2025

KubeKanvas Features
KubeKanvas Logo

Visual Kubernetes cluster design tool that helps you create, manage, and deploy your applications with ease.

Product

  • Features
  • Pricing
  • Templates

Resources

  • Blog
  • Tutorials

Company

  • About Us
  • Contact
  • Terms of Service
  • Privacy Policy
  • Impressum
XGitHubLinkedIn
Β© 2025 KubeKanvas. All rights reserved.