How to integrate various services for building?

Hello.

I have a project that requires npm and gradle for build, and docker for building and pushing the image.

At first I thought that I should create my own ubuntu image with gradle and npm setup, but I found out that is not what docker images are for.

So I hoped to run official Gradle and node images as a service so that my script can call those commands, but that is not happening for some reason.

My .gitlab-ci.yml:

variables:
  IMAGE_NAME: my.registry.production/project
  IMAGE_TAG: $CI_COMMIT_BRANCH
  GIT_SUBMODULE_STRATEGY: recursive

stages:
  - build
  - deploy

build_project:
  stage: build
  image: ubuntu:jammy
  services:
    - name: node:12.20
      alias: npm
    - name: gradle:6.3.0-jre8
      alias: gradle
  before_script:
    - git submodule init && git submodule update --remote --recursive
  script:
    - cd project-server && npm install && gradle clean build -Pprod -Pwar -x test -x integrationTest

deploy_image:
  stage: deploy
  image: docker:20.10.17
  services:
    - name: docker:20.10.17-dind
      alias: docker
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_TLS_CERTDIR: ""
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD my.registry.production
    - docker build -t $IMAGE_NAME:$IMAGE_TAG .
    - docker push $IMAGE_NAME:$IMAGE_TAG

If anyone has any info on how to solve this I would greatly appreciate it, since I’m a novice DevOps.