From 8bca986fe89aaf74c922c4d0b54ce513c4c44120 Mon Sep 17 00:00:00 2001 From: rezayaghobi-dev Date: Sun, 4 Oct 2026 21:38:08 +0330 Subject: [PATCH] Add GitLab pipeline, gitlab stack docs and root include --- .gitlab-ci.yml | 2 + gitlab/.gitlab-ci.yml | 65 ++++++++++++++++++++++++++++++ gitlab/README.md | 16 ++++++++ gitlab/compose.yml | 92 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 gitlab/.gitlab-ci.yml create mode 100644 gitlab/README.md create mode 100644 gitlab/compose.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..0453991 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,2 @@ +include: + - local: gitlab/.gitlab-ci.yml diff --git a/gitlab/.gitlab-ci.yml b/gitlab/.gitlab-ci.yml new file mode 100644 index 0000000..92fd6e5 --- /dev/null +++ b/gitlab/.gitlab-ci.yml @@ -0,0 +1,65 @@ +stages: + - test + - build + - publish + - deploy + +variables: + GIT_DEPTH: "20" + PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" + +# ---------- 1. TEST ---------- +test: + stage: test + image: python:3.12-slim + cache: + key: pip-cache + paths: + - .cache/pip + script: + - cd webapp + - pip install -r requirements-dev.txt + - pytest -v --junitxml=report.xml + artifacts: + when: always + reports: + junit: webapp/report.xml + +# ---------- 2. BUILD ---------- +build: + stage: build + script: + - docker build -t webapp:latest -t webapp:$CI_COMMIT_SHORT_SHA webapp + - docker image ls webapp + +# ---------- 3. PUBLISH (opt-in: set CI/CD variable PUSH_TO_REGISTRY=true) ---------- +publish: + stage: publish + rules: + - if: '$PUSH_TO_REGISTRY == "true"' + script: + - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" + - docker tag webapp:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE/webapp:$CI_COMMIT_SHORT_SHA + - docker tag webapp:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE/webapp:latest + - docker push $CI_REGISTRY_IMAGE/webapp:$CI_COMMIT_SHORT_SHA + - docker push $CI_REGISTRY_IMAGE/webapp:latest + +# ---------- 4. DEPLOY (default branch only) ---------- +deploy: + stage: deploy + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + script: + - docker network inspect monitoring-net >/dev/null 2>&1 || docker network create monitoring-net + - docker compose -f webapp/compose.yml up -d --no-build + - | + for i in $(seq 1 12); do + status=$(docker inspect -f '{{.State.Health.Status}}' webapp) + echo "health: $status" + [ "$status" = "healthy" ] && exit 0 + sleep 5 + done + docker logs webapp --tail 50 + exit 1 + environment: + name: production \ No newline at end of file diff --git a/gitlab/README.md b/gitlab/README.md new file mode 100644 index 0000000..940c676 --- /dev/null +++ b/gitlab/README.md @@ -0,0 +1,16 @@ +# GitLab stack (self-hosted) + +GitLab CE and its container registry behind Traefik (TLS), plus a Docker-executor runner on the same network (`web_net`). +The pipeline for this repo is in `.gitlab-ci.yml` in this folder (included from the repo root). + +Register a runner (create it in Admin > CI/CD > Runners first, then use its token): + + docker exec gitlab-runner gitlab-runner register --non-interactive \ + --url http://gitlab:80 --token \ + --executor docker --docker-image docker:cli \ + --docker-network-mode web_net \ + --docker-volumes /var/run/docker.sock:/var/run/docker.sock \ + --clone-url http://gitlab:80 + +Where registry.gitlab.com is unreachable, add this to the runner's [runners.docker] section in config.toml: +`helper_image = "gitlab/gitlab-runner-helper:x86_64-latest"` diff --git a/gitlab/compose.yml b/gitlab/compose.yml new file mode 100644 index 0000000..a81ea92 --- /dev/null +++ b/gitlab/compose.yml @@ -0,0 +1,92 @@ +services: + gitlab: + image: gitlab/gitlab-ce:19.2.6-ce.0 + container_name: gitlab + restart: unless-stopped + hostname: gitlab.local + ports: + - "2224:22" + volumes: + - ./config:/etc/gitlab + - ./logs:/var/log/gitlab + - ./data:/var/opt/gitlab + shm_size: '256m' + environment: + GITLAB_OMNIBUS_CONFIG: | + gitlab_rails['monitoring_whitelist'] = ['127.0.0.1', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] + external_url 'https://gitlab.home.server' + + nginx['listen_port'] = 80 + nginx['listen_https'] = false + nginx['proxy_set_headers'] = { + "X-Forwarded-Proto" => "https", + "X-Forwarded-Ssl" => "on" + } + + gitlab_rails['gitlab_shell_ssh_port'] = 2224 + + # Trim workers for a 4-core / 8GB host + puma['worker_processes'] = 2 + puma['min_threads'] = 1 + puma['max_threads'] = 4 + sidekiq['max_concurrency'] = 10 + postgresql['shared_buffers'] = "256MB" + + # You already have this stack running — turn GitLab's copies off + prometheus_monitoring['enable'] = false + alertmanager['enable'] = false + node_exporter['enable'] = false + redis_exporter['enable'] = false + postgres_exporter['enable'] = false + gitlab_exporter['enable'] = false + + # Registry + registry['enable'] = true + registry_external_url 'https://registry.home.server' + gitlab_rails['registry_enabled'] = true + gitlab_rails['registry_host'] = "registry.home.server" + gitlab_rails['registry_port'] = "443" + registry_nginx['listen_port'] = 5050 + registry_nginx['listen_https'] = false + networks: + - web_net + labels: + - "traefik.enable=true" + - "traefik.docker.network=web_net" + + # --- Web UI --- + - "traefik.http.routers.gitlab.rule=Host(`gitlab.home.server`)" + - "traefik.http.routers.gitlab.entrypoints=websecure" + - "traefik.http.routers.gitlab.tls=true" + - "traefik.http.routers.gitlab.service=gitlab" + - "traefik.http.routers.gitlab.middlewares=security-headers@file" + - "traefik.http.routers.gitlab-http.rule=Host(`gitlab.home.server`)" + - "traefik.http.routers.gitlab-http.entrypoints=web" + - "traefik.http.routers.gitlab-http.service=gitlab" + - "traefik.http.routers.gitlab-http.middlewares=redirect-to-https@file" + - "traefik.http.services.gitlab.loadbalancer.server.port=80" + + # --- Container Registry --- + - "traefik.http.routers.registry.rule=Host(`registry.home.server`)" + - "traefik.http.routers.registry.entrypoints=websecure" + - "traefik.http.routers.registry.tls=true" + - "traefik.http.routers.registry.service=registry" + - "traefik.http.routers.registry.middlewares=security-headers@file" + - "traefik.http.routers.registry-http.rule=Host(`registry.home.server`)" + - "traefik.http.routers.registry-http.entrypoints=web" + - "traefik.http.routers.registry-http.service=registry" + - "traefik.http.routers.registry-http.middlewares=redirect-to-https@file" + - "traefik.http.services.registry.loadbalancer.server.port=5050" + + gitlab-runner: + image: gitlab/gitlab-runner:latest + container_name: gitlab-runner + restart: unless-stopped + volumes: + - ./runner-config:/etc/gitlab-runner + - /var/run/docker.sock:/var/run/docker.sock + networks: + - web_net +networks: + web_net: + external: true