Gitlab CI/CD простого проекта?
ну примерно вот так:

image: # имя докер-образа 

stages:
  - build
  - tests
  - deploy

build_my_project:
  stage: build
  tags: 
    - тэг раннера где запустить
  script:
    - ... # собственно действия для билда
    - ... 
    - ...
    - ...
  artifacts:
    name: как будет обзываться артефакт сборки
    paths:
    - путь до файлов в артефакт
    expire_in: 1 hour # сколько ему жить
test1: 
  stage: tests
  tags: 
    - тэг раннера где запустить
  needs:
    - build
  scripts:
    - # действия по выполнению теста

test2: 
  stage: tests
  tags: 
    - тэг раннера где запустить
  scripts:
    - # действия по выполнению теста 2

deploy_to_dev:
  stage: deploy
  tags: 
    - тэг раннера где запустить
  needs:
    - tests
  rules:
    - if: $CI_COMMIT_BRANCH == "development"
  scripts:
    - # действия деплою в dev


deploy_to_prod:
  stage: deploy
  tags: 
    - тэг раннера где запустить
  needs:
    - tests
  rules:
    - if: $CI_COMMIT_BRANCH == "master"
  scripts:
    - # действия деплою в dev

словами: на первом шаге - build выполнится то что прописано в scripts (последовательно, по строкам)
на втором шаге - test - параллельно выполнится два (ну или сколько надо блоков тестов)
на третьем - deploy - выполнится или deploy_to_prod или deploy_to_dev или ничего в зависимости от того в какой ветке идет сборка ($CI_COMMIT_BRANCH) 
image: # имя докер-образа  - имя соответсвующего docker-образа с подготовленной средой разработки (node:14 - для npm,  mcr.microsoft.com/dotnet/sdk:6.0 - для .net6 и так далее)
можно и любой свой

needs: - описывает от каких шагов зависит шаг (это относительно свежее, ранее более жесткое dependencies:)
Я не работал с GitLab (Jenkins, GitHub workflows, AWS Codebuiuld, TravisCI, ...), но в целом все одинаково.

1) Первое и главное - расписать и проделать вручную все что должен делать CI pipeline.  Советую начать с самого простого - просто построить образ и задейлоить на сервере. Потом добавлять проверки и проч. - вариантов много https://qna.habr.com/q/1016852#answer_1981278.   И добавлять разные вариации для разных branches and targets (типа - для master branch больше всего тестов и проч.)
Как деплоить - ИМХО, стоит это делать простыми контейнерами, без compose, тогда можно будет деплоить всюду - это сегодня самый универсальный формат.

2) Когда четко знаем что - искать как это имплементировать в gitlab или другом инструменте, сочинить самый простой сценарий, отладить, добавать что-то посложнее, отладить, и т.п. 
Все как с программированием.
Примеров в интернете много.