How to set up a gitlab-ci.yml for deploying a mern-stack

Hello everyone, I am learning currently ci/cd with gitlab, using docker and kubernetes. I have taken a small mern-stack app I have built before. Then I created Dockerfiles for backend and frontend. I have used a docker-compose.yml for building the images. This is the docker-compose.yml:

services:
  backend:
    build:
      context: .
      dockerfile: Dockerfile-backend
    command: ["npm", "run", "server"]
    environment:
      - NODE_ENV=production
      - MONGO_URL=mongodb+srv://${MONGO_USER}:${MONGO_PASSWORD}@cluster0.58ybmho.mongodb.net/
      - MONGO_USER=${MONGO_USER}
      - MONGO_PASSWORD=${MONGO_PASSWORD}
      - PORT=${PORT}
      - JWT_SEC=${JWT_SEC}
    ports:
      - "5000:5000"
    depends_on:
      - mongo
    networks:
      - private
      - public
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 1G 
  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - mongo_data:/data/db
    restart: always
    networks:
      - private
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    command: ["npm", "start"]
    environment:
      - REACT_APP_EMAIL_SERVICE_ID=${REACT_APP_EMAIL_SERVICE_ID}
      - REACT_APP_EMAIL_TEMPLATE_ID=${REACT_APP_EMAIL_TEMPLATE_ID}
      - REACT_APP_EMAIL_PUBLIC_KEY=${REACT_APP_EMAIL_PUBLIC_KEY}
    networks:
      - public
    volumes:
      - frontend_node_modules:/node_modules
    depends_on:
      - backend
    ports:
      - "3000:3000"
    deploy:
        resources:
          limits:
            cpus: '0.70'
            memory: 2G
networks:
  private: {}
  public: {}

volumes:
  mongo_data:
    driver: local
  frontend_node_modules:
    driver: local

Then I have built the yml files for kubernetes, with this deployment.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: portfolioapp
  namespace: prod
spec:
  replicas: 2
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: portfolio
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: portfolio
    spec:
      containers:
      - name: backend
        image: myName/portfolioapp-backend:v1
        imagePullPolicy: Always
        resources:
          requests:
            memory: "128Mi"
            cpu: "250m"
          limits:
            memory: "500Mi"
            cpu: "500m"
        ports:
        - containerPort: 5000
        env:
        - name: PORT
          value: "5000"
        - name: MONGO_URL
          valueFrom:
            secretKeyRef:
              key: connectionStringStandardSrv
              name: my-atlas-connection
      - name: frontend
        image: myName/portfolioapp-frontend:v1
        imagePullPolicy: Always
        resources:
          requests:
            memory: "224Mi"
            cpu: "250m"
          limits:
            memory: "500Mi"
            cpu: "500m"
        ports:
        - containerPort: 3000

Now I wanted to set this all in the gitlab pipelines and have built this gitlab-ci.yml:

cache:
  key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
  paths:
    - frontend/node_modules/
    - /node_modules/
    - backend/node_modules/
variables:
  IMAGE_NAME_FRONTEND: myName/portfolioapp-frontend
  IMAGE_NAME_BACKEND: myName/portfolioapp-backend
  IMAGE_TAG: v1 
  PORT: $PORT
  JWT_SEC: $JWT_SEC
  MONGO_URL: $MONGO_URL
  MONGO_USER: $MONGO_USER
  MONGO_PASSWORD: $MONGO_PASSWORD
before_script:
  - docker info
  - docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD
stages:
  - build
  - deploy
build_image:
  stage: build
  image: docker:27.0.0-rc.1-alpine3.20
  services:
    - docker:27.0.0-rc.1-dind-alpine3.20
  variables:
    DOCKER_TLS_CERT_DIR: "/certs"
  script:
    - docker-compose build
    - docker tag portfolioapp-frontend $IMAGE_NAME_FRONTEND:$IMAGE_TAG 
    - docker tag portfolioapp-backend $IMAGE_NAME_BACKEND:$IMAGE_TAG 
    - docker push $IMAGE_NAME_FRONTEND:$IMAGE_TAG 
    - docker push $IMAGE_NAME_BACKEND:$IMAGE_TAG 
deploy:
  stage: deploy
  image: 
    name: bitnami/kubectl:latest
    entrypoint: [""]
  script:
    - kubectl apply -f namespace.yml
    - kubectl apply -f secret.yml
    - kubectl apply -f service.yml
    - kubectl apply -f deployment.yml
    - kubectl apply -f ingress.yml
  environment:
    name: production
    url: https://MyNameDevPortfolio.com
  only:
    - master

The first stage is running and I see in the console of gitlab that backend and frontent are running and the connection to mongodb is successfull. But the deploy stage is not running, because the docker command that runs in the before_script successfully for the build stage gives back this error for the deploy stage: $ docker info
(https://gitlab.com/myName1/portfolioapp/-/jobs/7243521521#L23)/usr/bin/bash: line 170: docker: command not found. Perhaps the docker command is not available in this bitnami/kubectl: latest image, but this is the most recommended image for deploying kubernetes and I found not really an alternative. But perhaps is the way I created this gitlab-ci.yml wrong? Has someone experience with docker, kubernetes and gitlab?
Thanks for help.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.