본문 바로가기

WEB개발보조/CI&CD

gitlab + gitlab runner + docker, ci/cd

Ubuntu에서 진행~ 도커에서 gitlab, gitlab-runner를 띄우고 nginx컨테이너에 빌드 후 배포, 서버는 스프링부트 빌드 후 이미지화 컨테이너 실행 CI/CD

 

1. gitlab, gitlab-runner pull

docker pull gitlab/gitlab-runner:latest
docker pull gitlab/gitlab-ce:latest

 

 

2. 컨테이너 띄우기

docker run -d \
  --hostname woo06.ddns.net \
  -p 18080:80 -p 1443:443 -p 122:22 \
  --name gitlab \
  --restart always \
  -e GITLAB_EXTERNAL_URL="http://woo06.ddns.net:18080" \
  -v gitlab-config:/etc/gitlab \
  -v gitlab-logs:/var/log/gitlab \
  -v gitlab-data:/var/opt/gitlab \
  gitlab/gitlab-ce:latest

 

docker run -d --name gitlab-runner \
  --restart always \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

 

 

dood방식을 위한 호스트의 도커연결 

 -v /var/run/docker.sock:/var/run/docker.sock

 

DooD는 Docker Out Of Docker
의 약어로 호스트 도커 데몬이 사용하는 소켓을 공유하여 도커 클라이언트 컨테이너에서 컨테이너를 실행시키는 것입니다

 

 

gitlab-runner에서 docker io설치 및 npm 설치

apt-get update
apt-get install -y docker.io

curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \ apt-get install -y nodejs
RUN npm install -g pnpm

 

 

3. password 설정

docker exec -it gitlab bash
gitlab-rails console
user = User.find_by_username('root')
user.password = '새로운비밀번호'
user.password_confirmation = '새로운비밀번호'
user.save!
exit

 

 

4. gitlab 외부 URL설정

 

Admin > General > Visibility and access controls

 

 

5. gitlab-runner register 등록

docker exec -it gitlab-runner gitlab-runner register

 

 


 

GitlabRunner - Executor

 

 

 

1. Shell : 가장 기본적인 Executor로, 로컬 머신에서 shell 명령어를 직접 실행합니다. Linux, macOS, Windows 모두에서 지원됩니다.

2. Docker : Docker 컨테이너에서 작업을 실행합니다. Docker 이미지를 사용하여 격리된 환경에서 작업을 실행할 수 있습니다.

executor = "docker"
[runners.custom_build_dir]
[runners.docker]
  tls_verify = false
  image = "ubuntu:latest"
  privileged = true
  disable_entrypoint_overwrite = false


3. Docker-SSH
: Docker 컨테이너 내에서 SSH를 통해 명령을 실행합니다. SSH 접속이 가능하도록 설정된 Docker 컨테이너에서 작업을 실행합니다.

4. Kubernetes
: Kubernetes 클러스터에서 작업을 실행합니다. GitLab Runner는 Kubernetes API를 사용하여 파드(Pod)에서 작업을 실행합니다.

executor = "kubernetes"
[runners.kubernetes]
  namespace = "default"
  privileged = true

 

5. VirtualBox
설명: VirtualBox 가상 머신을 사용하여 작업을 실행합니다. 가상 머신을 통해 더 높은 수준의 격리가 필요한 경우에 사용됩니다.

 


 

CI / CD예제

1. nginx컨테이너에 vite프로젝트 배포하기 (executor - shell)

[[runners]]
  name = "react-runner"
  url = "http://woo06.ddns.net:18080"
  id = 7
  token = "t3_-ZkJT4vzyeSobnekBRvG"
  token_obtained_at = 2025-03-19T06:24:57Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "shell"
  [runners.cache]
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    privileged =true 
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0
    network_mtu = 0
stages:
  - build
  - deploy

variables:
  CONTAINER_NAME: "nginx-contianer"  # 실행 중인 Nginx 컨테이너 이름
  DEPLOY_DIR: "/usr/share/nginx/html"   # Nginx 서버의 정적 파일 경로

# 빌드 단계
build:
  stage: build
  artifacts:
    paths:
      - build
  script:
    - export PATH=$PATH:/usr/local/bin/pnpm
    - pnpm install
    - pnpm build
    - ls -al
  only:
    - master
  tags:
    - react-runner

# 배포 단계
deploy:
  stage: deploy
  script:
    - ls -al
    # Nginx 컨테이너 내에서 Vite 빌드 파일을 배포
    - docker ps -q --filter "name=$CONTAINER_NAME" | grep -q . || (echo "Nginx container not running" && exit 1)
    - docker cp build/. $CONTAINER_NAME:$DEPLOY_DIR
    # Nginx 컨테이너를 리로드하여 새로운 파일 적용
    - docker exec $CONTAINER_NAME nginx -s reload
  only:
    - master  # 배포는 main 브랜치에서만 실행
  tags:
    - react-runner

 

 

2. 스프링부트 컨테이너 띄우기  (executor - docker)

[[runners]]
  name = "boot-runner"
  url = "http://woo06.ddns.net:18080"
  id = 6
  token = "t3_Jh5Hii5FscJQgTmYotwZ"
  token_obtained_at = 2025-03-18T04:43:34Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:latest"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0
    network_mtu = 0
stages:
  - build
  - package
  - deploy

# Gradle 빌드 단계
build:
  stage: build
  image: gradle:8.12.1-jdk17
  script:
    - gradle clean build -x test
  artifacts:
    paths:
      - build/libs/*.jar
  only:
    - main
  tags:
    - boot-runner

# Docker 이미지 빌드 단계
package: 
  stage: package
  image: docker:latest
  script:
   - docker build -t springboot-demo .  
  only:
    - main
  tags:
    - boot-runner

deploy:
  stage: deploy
  script:
    - docker container rm -f springboot-demo-container
    - docker run -d -p 8081:8081 --name springboot-demo-container --restart always springboot-demo
  only:
    - main
  tags:
    - boot-runner