Skip to content

4. Deploying PrestaShop From cPouta Server With Internal Docker Images

This guide shows how to deploy PrestaShop and MariaDB from private internal Docker images on a cPouta-hosted Kubernetes cluster using MicroK8s, and an Ingress with HTTPS.

Original Author: Tuukka Peltomäki
Last checked by Petri Peltomaa
Lastmod: 5.12.2025
Status: In progress

Notes#

This guide uses private internal images from the ref-product-line-v1-2025 registry.
If these move to an “official" repository later, this guide must be updated.

TODO: Add persistence to PrestaShop

Introduction#

This document walks through deploying PrestaShop and MariaDB on a cPouta VM running MicroK8s.
The deployment uses:

  • internal Docker images stored in GitLab Container Registry
  • Kubernetes Docker registry secrets
  • HTTPS-enabled Ingress (using cert-manager)

Prerequisites#

  • Product Platform v2 documentation steps 1, 2 and 3 reviewed
  • Internal PrestaShop & MariaDB images have been built in GitLab CI/CD
  • cert-manager and nginx-ingress installed on MicroK8s (Platform v2 step 2)

Domain & registry secret#

Before deploying PrestaShop, make sure you have:

  • your cPouta VM domain

  • a gitlab-registry-secret for pulling private images

You can obtain your domain name and create the registry secret as described in the previous guide “3. Setting Up a Service”, so follow the same steps here without repeating them.

Creating and deploying YAML file#

Using these image:

  • PrestaShop Image:

    gitlab.labranet.jamk.fi:4567/ref-product-line-v1-2025/ref-product-presta-shop-service-container-v1
    

  • MariaDB Image:

    gitlab.labranet.jamk.fi:4567/ref-product-line-v1-2025/ref-product-service-mysql-database-container-v1
    

Create a prestashop-deplyoment.yaml

# MariaDB Service
---
apiVersion: v1
kind: Service
metadata:
  name: prestashop-db
spec:
  ports:
    - port: 3306
  selector:
    app: prestashop-db
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prestashop-db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prestashop-db
  template:
    metadata:
      labels:
        app: prestashop-db
    spec:
      containers:
      - name: mariadb
        image: gitlab.labranet.jamk.fi:4567/ref-product-line-v1-2025/ref-product-service-mysql-database-container-v1:latest
        imagePullPolicy: "Always"
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        - name: MYSQL_DATABASE
          value: prestashop
        - name: MYSQL_USER
          value: prestashop
        - name: MYSQL_PASSWORD
          value: password
      imagePullSecrets:
      - name: gitlab-registry-secret

# Prestashop Service
---
apiVersion: v1
kind: Service
metadata:
  name: prestashop-service
spec:
  selector:
    app: prestashop
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prestashop
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prestashop
  template:
    metadata:
      labels:
        app: prestashop
    spec:
      containers:
      - name: prestashop
        image: gitlab.labranet.jamk.fi:4567/ref-product-line-v1-2025/ref-product-presta-shop-service-container-v1
        imagePullPolicy: "Always"
        ports:
        - containerPort: 80
        env:
        - name: DB_SERVER
          value: "prestashop-db"
        - name: DB_USER
          value: "prestashop"
        - name: DB_PASSWD
          value: "password"
        - name: DB_NAME
          value: "prestashop"
        - name: PS_INSTALL_AUTO
          value: "1"
        - name: PS_DOMAIN
          value: "<YOUR-DOMAIN-NAME>"
        - name: PS_LANGUAGE
          value: "fi"
        - name: PS_FOLDER_ADMIN
          value: "admin228" # Rename admin folder for security
        - name: PS_ENABLE_SSL
          value: "1"
        - name: ADMIN_MAIL
          value: "<EMAIL>"
        - name: ADMIN_PASSWD
          value: "password"
      imagePullSecrets: 
      - name: gitlab-registry-secret

# Ingress
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prestashop-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: "<YOUR-DOMAIN-NAME>"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prestashop-service
            port:
              number: 80
  • This will deploy PrestaShop as HTTP

Deploy PrestaShop from the server:

[rocky@rocky-vm ~]$ microk8s kubectl apply -f prestashop-deployment.yaml
service/prestashop-db created
deployment.apps/prestashop-db created
service/prestashop-service created
deployment.apps/prestashop created
ingress.networking.k8s.io/prestashop-ingress created
clusterissuer.cert-manager.io/letsencrypt-prod created

# See the status of the pods
[rocky@rocky-vm ~]$ microk8s kubectl get pods -w
NAME                            READY   STATUS    RESTARTS   AGE
prestashop-6474ccfff9-68wdf     1/1     Running   0          15s
prestashop-db-7b54c8cdf-jtl6m   1/1     Running   0          15s

Note on HTTP Deployment:

When deploying PrestaShop as HTTP (as shown here), you might face some issues, particularly with the admin pages not loading properly or performing inconsistently. This could happen due to missing secure cookies, mixed content issues, or PrestaShop's expectation of SSL for certain features. If you encounter issues, consider deploying PrestaShop over HTTPS as outlined in the next section.

The deployment might take some time. After a while, you should be able to access your PrestaShop at the Domain you defined earlier.

Viewing installation logs:

[rocky@rocky-vm ~]$ microk8s kubectl logs -f prestashop-6474ccfff9-68wdf # <prestashop-pod-name>

# Shortened output

* Installing PrestaShop, this may take a while ...

* Launching the installer script...
-- Installation successful! --

* Removing install folder...

* No post-install script found, let's continue...

* Setup completed, removing lock file...

* Almost ! Starting web server now


* No init script found, let's continue...
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.1.248.117. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.1.248.117. Set the 'ServerName' directive globally to suppress this message
[Fri Dec 05 09:51:12.261224 2025] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.54 (Debian) configured -- resuming normal operations
[Fri Dec 05 09:51:12.261309 2025] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

Deploying PrestaShop as HTTPS#

To enable HTTPS, update your prestashop-deployment.yaml to include annotations and TLS settings in the Ingress configuration. Also, add the ClusterIssuer for Let's Encrypt at the end of the file.

# MariaDB Service
---
apiVersion: v1
kind: Service
metadata:
  name: prestashop-db
spec:
  ports:
    - port: 3306
  selector:
    app: prestashop-db
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prestashop-db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prestashop-db
  template:
    metadata:
      labels:
        app: prestashop-db
    spec:
      containers:
      - name: mariadb
        image: gitlab.labranet.jamk.fi:4567/ref-product-line-v1-2025/ref-product-service-mysql-database-container-v1:latest
        imagePullPolicy: "Always"
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        - name: MYSQL_DATABASE
          value: prestashop
        - name: MYSQL_USER
          value: prestashop
        - name: MYSQL_PASSWORD
          value: password
      imagePullSecrets:
      - name: gitlab-registry-secret

# Prestashop Service
---
apiVersion: v1
kind: Service
metadata:
  name: prestashop-service
spec:
  selector:
    app: prestashop
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prestashop
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prestashop
  template:
    metadata:
      labels:
        app: prestashop
    spec:
      containers:
      - name: prestashop
        image: gitlab.labranet.jamk.fi:4567/ref-product-line-v1-2025/ref-product-presta-shop-service-container-v1
        imagePullPolicy: "Always"
        ports:
        - containerPort: 80
        env:
        - name: DB_SERVER
          value: "prestashop-db"
        - name: DB_USER
          value: "prestashop"
        - name: DB_PASSWD
          value: "password"
        - name: DB_NAME
          value: "prestashop"
        - name: PS_INSTALL_AUTO
          value: "1"
        - name: PS_DOMAIN
          value: "<YOUR-DOMAIN-NAME>"
        - name: PS_LANGUAGE
          value: "fi"
        - name: PS_FOLDER_ADMIN
          value: "admin228" # Rename admin folder for security
        - name: PS_ENABLE_SSL
          value: "1"
        - name: ADMIN_MAIL
          value: "<EMAIL>"
        - name: ADMIN_PASSWD
          value: "password"
      imagePullSecrets: 
      - name: gitlab-registry-secret

# Ingress
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prestashop-ingress
  annotations:                                            # Add these to enable HTTPS
    cert-manager.io/cluster-issuer: "letsencrypt-prod"    #
    acme.cert-manager.io/http01-edit-in-place: "true"     # 
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - "<YOUR-DOMAIN-NAME>"
    secretName: prestashop-tls
  rules:
  - host: "<YOUR-DOMAIN-NAME>"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prestashop-service
            port:
              number: 80

# Add the ClusterIssuer to enable HTTPS
# ClusterIssuer (Let's Encrypt)
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: "<EMAIL>"
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx