Cloud Native 16 min read

Deploy PHP and Java Applications on Kubernetes: A Complete Step‑by‑Step Guide

This article walks beginners through the full process of preparing a Kubernetes environment and deploying both PHP (WordPress) and Java (Tomcat) web applications, covering image creation, namespace setup, secrets, deployments, services, ingress configuration, and host binding.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Deploy PHP and Java Applications on Kubernetes: A Complete Step‑by‑Step Guide

Traditional Deployment vs K8S Deployment Differences

Traditional web deployment often follows a monolithic architecture, while Kubernetes enables elastic scaling, resource efficiency, and faster release cycles.

Preparing the Environment

Master node: 192.168.73.138 Node01: 192.168.73.139 Node02: 192.168.73.140 Harbor registry: 192.168.73.136

1. PHP Project Deployment Process

1.1 Build the Docker Image

Clone the repository, edit the WordPress configuration, and create a Dockerfile that packages the application.

# git clone https://github.com/zhangdongdong7/php-demo.git
# cd php-demo
# ls
deployment.yaml  ingress.yaml  mysql.yaml  namespace.yaml  README.md  service.yaml  wordpress
# cd wordpress
# vim wp-config.php   # modify DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, etc.

Create a Dockerfile and build the image, then push it to the Harbor registry.

# vim Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/sunsharing/nginx-php:latest
MAINTAINER www.ctnrs.com
ADD . /usr/local/nginx/html
# login and push
docker login 192.168.73.136
docker build -t 192.168.73.136/test/php-demo:latest .
docker push 192.168.73.136/test/php-demo:latest

1.2 Create Controller to Manage Pods

Create a namespace, a secret for Harbor authentication, and a Deployment manifest.

# vim namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: test
kubectl apply -f namespace.yaml

# create secret
kubectl create secret docker-registry registry-pull-secret \
  --docker-username=admin \
  --docker-password=Harbor12345 \
  [email protected] \
  --docker-server=192.168.73.136 -n test

# deployment.yaml (excerpt)
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: php-demo
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      project: www
      app: php-demo
  template:
    metadata:
      labels:
        project: www
        app: php-demo
    spec:
      imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: nginx
        image: 192.168.73.136/test/php-demo:v3
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "0.5"
            memory: 256Mi
          limits:
            cpu: "1"
            memory: 1Gi
        livenessProbe:
          httpGet:
            path: /status.php
            port: 80

1.3 Pod Data Persistence

The example uses a static website, so no persistent volume is required; the code is baked into the image.

1.4 Expose the Application

Create a Service and an Ingress to make the application reachable.

# service.yaml (excerpt)
apiVersion: v1
kind: Service
metadata:
  name: php-demo
  namespace: test
spec:
  selector:
    project: www
    app: php-demo
  ports:
  - name: web
    port: 80
    targetPort: 80
kubectl apply -f service.yaml

# ingress.yaml (excerpt)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: php-demo
  namespace: test
spec:
  rules:
  - host: php.ctnrs.com
    http:
      paths:
      - path: /
        backend:
          serviceName: php-demo
          servicePort: 80
kubectl apply -f ingress.yaml

1.5 Bind Host Entries for Verification

Add the following line to your hosts file (Windows: C:\Windows\System32\drivers\etc\hosts, macOS: /private/etc/hosts): 192.168.73.139 php.ctnrs.com After updating DNS, open http://php.ctnrs.com in a browser to complete the WordPress setup.

2. Java Project Deployment Process

2.1 Build the Docker Image

Clone the Java demo, install JDK and Maven, build the WAR, and create a Dockerfile.

# git clone https://github.com/zhangdongdong7/java-demo.git
# cd java-demo
# unzip tomcat-java-demo-master.zip
# cd tomcat-java-demo-master
# yum install java-1.8.0-openjdk maven -y
# mvn clean package -Dmaven.test.skip=true
# cat Dockerfile
FROM lizhenliang/tomcat
LABEL maintainer www.ctnrs.com
RUN rm -rf /usr/local/tomcat/webapps/
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
# login and push
docker login 192.168.73.136
docker build -t 192.168.73.136/test/java-demo:latest .
docker push 192.168.73.136/test/java-demo:latest

2.2 Create Controller to Manage Pods

Create the same namespace and secret as for PHP, then define a Deployment for the Tomcat container.

# namespace.yaml (same as before)
kubectl apply -f namespace.yaml

# secret (same as before)
kubectl create secret docker-registry registry-pull-secret \
  --docker-username=admin \
  --docker-password=Harbor12345 \
  [email protected] \
  --docker-server=192.168.73.136 -n test

# deployment.yaml (excerpt)
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      project: www
      app: java-demo
  template:
    metadata:
      labels:
        project: www
        app: java-demo
    spec:
      imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: tomcat
        image: 192.168.73.136/test/java-demo:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "0.25"
            memory: 1Gi
          limits:
            cpu: "1"
            memory: 2Gi
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 20
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 60
kubectl apply -f deployment.yaml

2.3 Expose the Application

Create a Service and an Ingress similar to the PHP example.

# service.yaml (excerpt)
apiVersion: v1
kind: Service
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  selector:
    project: www
    app: java-demo
  ports:
  - name: web
    port: 80
    targetPort: 8080
kubectl apply -f service.yaml

# ingress.yaml (excerpt)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  rules:
  - host: java.ctnrs.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-java-demo
          servicePort: 80
kubectl apply -f ingress.yaml

2.4 Bind Host Entries for Verification

Add the following line to your hosts file: 192.168.73.139 java.ctnrs.com Open http://java.ctnrs.com in a browser to verify the Java application is reachable.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaCloud NativeDockerDeploymentKubernetesPHP
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.