Как на хостовой Ubuntu установить автономный GitLab и GitLab Runner с Docker Executor с помощью Vagrant

Пайплайн исполняется не на GitLab-сервере, а на GitLab Runner'ах, которые можно запускать хоть локально, хоть на другой машине, хоть на выделенном сервере. GitLab Runner — это отдельный агент, который подключается к GitLab и выполняет job'ы, определённые в .gitlab-ci.yml. Сейчас установим GitLab Runner на той же машине, где находится GitLab. С помощью "Executor docker" Runner запускает каждую job в отдельном Docker контейнере, изолированном от хоста и других job-ов. Особенно рекомендуется для командной разработки.

1. Предварительные шаги

Выполним шаги 1, 2 и 3 из этого мануала: https://fkn.ktu10.com/?q=node/17437
Нужно клонировать три репозитория: ktu-articles, ktu-backend-pack, ktu-backend-test
Подтягивать зависимости командой "composer install" не обязательно.

2. Редактирование provision.sh — вставьте в файл следующее содержимое:

#!/bin/bash
# provision.sh — автоматическая установка и настройка окружения с GitLab, Docker и GitLab Runner

# Не взаимодействовать с пользователем при установке (для предотвращения зависаний)
export DEBIAN_FRONTEND=noninteractive
 
# Прерывать выполнение скрипта при любой ошибке команды
set -e

LOGFILE="/var/log/provision.log"
exec > >(tee -a "$LOGFILE") 2>&1

echo "=== Начало provisioning $(date) ==="

echo "Проверка и восстановление dpkg, если был прерван..."
dpkg --configure -a || true
 
echo "Обновление списка пакетов..."
apt-get update -y
apt-get upgrade -y
 
echo "Установка Make и необходимых утилит..."
apt-get install -y make ca-certificates curl gnupg lsb-release dkms build-essential linux-headers-$(uname -r) 

# --- Удаление Apache, если он установлен и блокирует порт 80 ---
# echo "Проверка на наличие Apache..."
# if systemctl list-unit-files | grep -q apache2; then
#   echo "⚠️ Найден Apache. Удаляем, чтобы освободить порт 80..."
#   systemctl stop apache2 || true
#   systemctl disable apache2 || true
#   apt-get purge -y apache2 apache2-utils apache2-bin apache2.2-common || true
#   apt-get autoremove -y || true
#   echo "✅ Apache удалён"
# else
#   echo "✅ Apache не установлен — всё ок"
# fi

echo "Установка GPG ключа Docker (если ещё нет)..."
if [ ! -f /etc/apt/keyrings/docker.gpg ]; then
  install -m 0755 -d /etc/apt/keyrings
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  chmod a+r /etc/apt/keyrings/docker.gpg
fi

echo "Добавление репозитория Docker (если не добавлен)..."
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
  echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | tee /etc/apt/sources.list.d/docker.list > /dev/null
fi

echo "Повторное обновление пакетов..."
apt-get update -y
 
echo "Установка Docker и Compose Plugin..."
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
echo "Добавление пользователя vagrant в группу docker..."
if getent group docker > /dev/null; then
  usermod -aG docker vagrant
fi

echo "Проверка, входит ли пользователь vagrant в группу docker..."
if id vagrant | grep -q '\\bdocker\\b'; then
  echo 'Пользователь vagrant уже в группе docker.'
else
  echo '⚠️ ВНИМАНИЕ: Пользователь vagrant ещё не в группе docker.'
  echo 'Для применения групп выполните команду: "vagrant reload" или "vagrant destroy && vagrant up" чтобы применить изменения.'
fi

echo "✅ Установка Docker завершена."

if command -v gitlab-ctl >/dev/null 2>&1; then
  echo "✅ GitLab уже установлен. Пропускаем установку."
else
  echo "Установка зависимостей GitLab..."
  apt-get install -y openssh-server tzdata perl postfix
 
  echo "Добавление официального репозитория GitLab..."
  curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | bash
 
  echo "[INFO] Установка GitLab CE..."
  EXTERNAL_URL="http://192.168.56.10" apt-get install -y gitlab-ce
fi

echo "Оптимизация / настройка gitlab.rb с отключёнными службами..."
cat <<EOF > /etc/gitlab/gitlab.rb
external_url 'http://192.168.56.10'
nginx['listen_port'] = 80
nginx['listen_https'] = false
puma['worker_processes'] = 1
puma['worker_timeout'] = 60
sidekiq['max_concurrency'] = 5
prometheus_monitoring['enable'] = false
alertmanager['enable'] = false
node_exporter['enable'] = false
redis_exporter['enable'] = false
postgres_exporter['enable'] = false
EOF

echo "Применение конфигурации GitLab..."
RUBYOPT='-W0' gitlab-ctl reconfigure

echo "Ожидание запуска GitLab..."
timeout 300 bash -c 'until curl -s http://localhost/users/sign_in | grep -q GitLab; do echo "Ждём загрузки GitLab..."; sleep 5; done'

echo "Установка пароля root-пользователя..."
# root-пароль 'mytest12' задан только для локальной разработки. Не используйте в продакшене!
gitlab-rails runner "
  u = User.find_by_username('root');
  u.password = 'mytest12';
  u.password_confirmation = 'mytest12';
  u.save!
" || echo "⚠️ Не удалось установить пароль root"

echo "✅ Установка или настройка GitLab завершена. Доступен по адресу: http://192.168.56.10 (Логин: root, Пароль: mytest78)" | tee /tmp/gitlab_ready.log

echo "Установка GitLab Runner..."
if ! dpkg -s gitlab-runner &> /dev/null; then
  curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | bash
  apt-get install -y gitlab-runner
fi

gitlab-runner unregister --all-runners || true

# Параметры
PHP_IMAGE="php:8.3-cli"  # ← одна точка правки
RUNNER_NAME="docker-runner"
RUNNER_TAGS="docker,vagrant"
GITLAB_URL="http://192.168.56.10"
# Попытка получить токен автоматически из GitLab через rails
REG_TOKEN=$(gitlab-rails runner -e production "puts Gitlab::CurrentSettings.current_application_settings.runners_registration_token" 2>/dev/null || echo "")

if [ -z "$REG_TOKEN" ]; then
  echo "⚠️ Не удалось получить токен"
  exit 1
fi

# Проверка, зарегистрирован ли Runner
EXISTING_RUNNER=$(gitlab-runner list 2>/dev/null | grep "$RUNNER_NAME" || true)

if [ -z "$EXISTING_RUNNER" ]; then
  echo "Регистрируем GitLab Runner..."
  gitlab-runner register --non-interactive \
    --url "$GITLAB_URL/" \
    --registration-token "$REG_TOKEN" \
    --executor "docker" \
    --description "$RUNNER_NAME" \
    --tag-list "$RUNNER_TAGS" \
    --docker-image "$PHP_IMAGE" \
    --docker-volumes "/cache" \
    --run-untagged=true \
    --locked=false
else
  echo "GitLab Runner уже зарегистрирован."
fi

systemctl enable gitlab-runner
systemctl restart gitlab-runner

# Установка Codeception (если ещё не установлен в vendor)
if [ -d "$PROJECT_DIR" ]; then
  if [ ! -f "$PROJECT_DIR/vendor/bin/codecept" ]; then
    echo "Установка Codeception в проект..."
    su - vagrant -c "cd $PROJECT_DIR && composer require codeception/codeception --dev"
  else
    echo "✅ Codeception уже установлен"
  fi
fi

echo "=== Provisioning завершён $(date) ==="

3. Редактирование composer.json в микросервисе ktu-articles

Переменные "minimum-stability" и "repositories" должны иметь следующие значения:

{
    "minimum-stability": "dev",
    "repositories": [
        {
            "type": "vcs",
            "url": "http://192.168.56.10/root/ktu-backend-pack.git"
        },
        {
            "type": "vcs",
            "url": "http://192.168.56.10/root/ktu-backend-test.git"
        }
    ]
}

4. Создание .gitlab-ci.yml в микросервисе ktu-articles

Если нужно, чтобы GitLab запускал CI/CD (например, пайплайны сборки или тестов), создайте в корне микросервиса файл .gitlab-ci.yml с таким содержимым:

stages:
  - test

codeception_functional_tests:
  stage: test
  image: php:8.3-cli
  services:
    - name: postgres:14
      alias: db
  variables:
    POSTGRES_DB: ktu-articles_db
    POSTGRES_USER: ktu-articles_user
    POSTGRES_PASSWORD: ktu-articles_password
    DATABASE_URL: "pgsql://ktu-articles_user:ktu-articles_password@db:5432/ktu-articles_db"
    APP_ENV: test
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - vendor/
      - ~/.composer/cache
  before_script:
    - export DATABASE_URL="postgresql://ktu-articles_user:ktu-articles_password@db:5432/ktu-articles_db?serverVersion=14.2&charset=utf8"
    - |
      echo "Установка зависимостей..."
      apt-get update && apt-get install -y unzip git curl zip postgresql-client libpq-dev autoconf make gcc g++ libc-dev pkg-config
      docker-php-ext-install pdo_pgsql pgsql
      curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
      echo "Ждём PostgreSQL..."
      until pg_isready -h db -p 5432 -U $POSTGRES_USER; do echo "Ещё не готов..."; sleep 2; done
      echo "Конфигурируем  composer..."
      composer config --global secure-http false
      composer config --unset platform.php || true
      rm -rf vendor composer.lock tests/_output
    - |
      export COMPOSER_AUTH='{"http-basic": {"192.168.56.10": {"username": "root", "password": "mytest12"}}}'
    - composer clear-cache || true
    - echo "Установка composer-зависимостей..."
    - composer install --prefer-dist --no-interaction --no-progress --no-scripts
  script:
    - echo "Cоздание или проверка базы данных (если база уже существует, то скрипт не прервётся)..."
    - php bin/console doctrine:database:create --env=test || true
    - echo "Создание схемы..."
    - php bin/console doctrine:schema:create --env=test
    - echo "Запуск функциональных тестов..."
    - vendor/bin/codecept run functional --debug
  tags:
    - docker

5. Запуск виртуальной машины

Из папки проекта (my-vagrant) выполним команду:
если Vagrant-проект был создан сейчас и ранее никогда не запускался:

vagrant up

после выполнения команды свободное место на диске уменьшится на ~10ГБ
если Vagrant-проект существовал ранее и сейчас только внесли изменения в Vagrantfile и provision.sh:

vagrant up --provision

после выполнения команды свободное место на диске уменьшится на ~7ГБ
Время выполнения команды может занять до одного часа.

6. Настройка и работа с GitLab

Если всё прошло успешно, из браузера из хостовой системы GitLab будет доступен по адресу:
http://192.168.56.10
Логин "root" пароль "mytest12". Не используйте этот пароль в продакшене!
Добавим второй remote для каждого из трёх репозиториев микросервисов, чтобы оставить обе платформы — и Bitbucket и GitLab:
Из папки репозитория ktu-articles:

git remote add gitlab http://192.168.56.10/root/ktu-articles.git
git push -u gitlab master

Из папки репозитория ktu-backend-pack:

git remote add gitlab http://192.168.56.10/root/ktu-backend-pack.git
git branch -M master
git push -u gitlab master

Из папки репозитория ktu-backend-test:

git remote add gitlab http://192.168.56.10/root/ktu-backend-test.git
git branch -M master
git push -u gitlab master

Подробнее здесь (6-ой шаг): https://fkn.ktu10.com/?q=node/17437
После этого наши проекты должны быть доступны по адресу:
http://192.168.56.10/root/ktu-articles
http://192.168.56.10/root/ktu-backend-pack
http://192.168.56.10/root/ktu-backend-test

7. Проверка работоспособности пайплайнов

Из папки репозитория ktu-articles выполним команды:

composer config --global secure-http false
composer update

Добавим все изменения, закоммитим и запушим:

git add . && git commit . -m "Add .gitlab-ci.yml" && git push gitlab master

Проверить пайплайны можно на странице:
http://192.168.56.10/root/ktu-articles/-...