Gitlab CI/CD 기초

개발자, Bono·2025년 11월 7일

CI/CD

목록 보기
1/1
post-thumbnail

1. 배포대상(dev) 서버 key 생성.

# ex)
ssh-keygen -t ed25519 -C "gitlab-ci"

2. 생성된 public key를 authorized_keys에 추가.

cd ~/.ssh
cat id_ed25519.pub
# cat으로 나온 값을 아래 파일에 추가해준다.
vi authorized_keys

3. Gitlab Web에 Private Key 등록

# 1번에서 만들어진 키중 .pub가 없는 private key를 
# [GitlabWeb] 프로젝트 > Settings > CI/CD > Variables 에 추가.
# SSH_PRIVATE_KEY라는 이름으로 private key 내용 저장

4. 프로젝트 root에 .gitlab-ci.yml 파일작성

stages:
  - deploy

deploy_dev:
  stage: deploy
  only:
    - main        # main 브랜치에만 동작
  variables:
    GIT_STRATEGY: none  # GitLab Runner에서 코드를 clone하지 않음( 이부분을 추가하지 않으면 권한문제가 발생함 이 이후에 다루도록 함 )
  script:
    # 1. SSH 세팅
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    # 포트가 다를경우 ssh-keyscan 뒤에 -p [포트번호] 추가!
    - ssh-keyscan -H YOUR_SERVER_IP >> ~/.ssh/known_hosts

    # 2. 배포 서버에 접속해 pull/build/restart
	# 포트가 다를경우 ssh 뒤에 -p [포트번호] 추가!
    - ssh USER@YOUR_SERVER_IP "cd /srv/your-app && git pull && npm install && npm run build && pm2 restart all"

5. Gitlab Runner 설치

1) Ubuntu/Debian 기준

# 패키지 설치와 등록
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
# 서비스 등록
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start

6. Runner 등록

# 1. GitlabWeb 접속
# 2. 프로젝트 > Settings > CI/CD > Runners > “Set up a specific runner manually”에서 Registration Token을 복사
# 3. 배포 서버에서 등록 명령어 실행:
sudo gitlab-runner register

질문마다 아래처럼 입력합니다:

# GitLab instance URL( for example,https://gitlab.com/):
- 자신이 쓰는 GitLab 주소. 회사/자체 서버면 해당 주소
# Enter the registration token:
- 복사한 토큰 붙여넣기
# Enter a description for the runner:
- 자유롭게(예: dev-server)
# Enter tags for the runner(comma-separated):
- 필요할 경우만 입력(예: node, prod 등)
# Enter optional maintenance note for the runner:
- (예:개발서버 배포용)
# Enter an executor: docker+machine, kubernetes, instance, ssh, parallels, virtualbox, docker, docker-windows, docker-autoscaler, custom, shell:
- 보통은 shell 선택, (도커 쓰면 docker)

7. 설치확인

sudo gitlab-runner status

실행중이면 OK
프로젝트 > Settings > CI/CD에서 등록/활성 상태 확인 가능

파이프라인 실행 후 “pending”에서 “running”으로 변하면 정상입니다.

재시작

sudo gitlab-runner restart

설치후기

# 실제로 pending에서 running으로 바로 변경되었으면 좋겠지만 아래와 같은 오류가 발생함.
Running with gitlab-runner 18.5.0 (bda84871)
  on [토큰정보], system ID:
Preparing the "shell" executor
00:00
Using Shell (bash) executor...
Preparing environment
00:01
Running on [서버명]...
ERROR: Job failed: prepare environment: exit status 1. Check https://docs.gitlab.com/runner/shells/#shell-profile-loading for more information

해결방법

sudo rm /home/gitlab-runner/.bash_logout

※ 참고용 세팅

❕기본적인 세팅이고, 어디까지나 참고용이며, 추후 테스트로직 등 보완해 나갈 예정이다.

  • nginx,php 는 docker 환경이고, node는 전역설치로 세팅된 환경

.gitlab-ci.yml

stages:
  - deploy

deploy_dev:
  stage: deploy
  only:
    - master
  variables:
    GIT_STRATEGY: none  # GitLab Runner에서 코드를 clone하지 않음
  script:
    # 1. SSH 세팅
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan -p [$SSH_PORT] -H [$SSH_IP] >> ~/.ssh/known_hosts

    # 2. 배포 스크립트를 서버에 생성하고 실행
    - |
      ssh -p [$SSH_PORT] [$SSH_ID]@[$SSH_IP] 'bash -s' << 'ENDSSH'
      cd /var/www/[PROJECT ROOT PATH]

      # 배포 스크립트 생성
      cat > /tmp/deploy_script.sh << 'DEPLOY_SCRIPT'
      #!/bin/bash
      echo "======================================"
      echo "🚀 배포 시작..."
      echo "======================================"
      cd /var/www/[PROJECT ROOT PATH]

      echo ""
      echo "[1/6] 📥 최신 코드 가져오기..."
      git pull origin master || { echo "❌ Git pull 실패"; exit 1; }
      echo "✅ Git pull 성공"

      echo ""
      echo "[2/6] 📦 Composer 의존성 설치..."
      docker compose exec -T php composer install --no-dev --optimize-autoloader --no-interaction 2>&1 | tail -20
      if [ ${PIPESTATUS[0]} -ne 0 ]; then
        echo "❌ Composer 설치 실패"
        exit 1
      fi
      echo "✅ Composer 설치 성공"

      echo ""
      echo "[3/6] 📦 NPM 의존성 설치..."
      npm install --production=false > /tmp/npm_install.log 2>&1
      if [ $? -ne 0 ]; then
        echo "❌ NPM 설치 실패"
        tail -20 /tmp/npm_install.log
        exit 1
      fi
      echo "✅ NPM 설치 성공"

      echo ""
      echo "[4/6] 🎨 프론트엔드 빌드..."
      npm run build > /tmp/npm_build.log 2>&1
      if [ $? -ne 0 ]; then
        echo "❌ 빌드 실패"
        tail -20 /tmp/npm_build.log
        exit 1
      fi
      echo "✅ 빌드 성공"

      echo ""
      echo "[5/6] ⚡ 캐시 초기화"
      docker compose exec -T php php artisan optimize:clear
      echo "✅ 캐시 초기화 완료"

      echo ""
      echo "[6/6] 🗄️ 데이터베이스 마이그레이션..."
      docker compose exec -T php php artisan migrate --force
      echo "✅ 마이그레이션 완료"

      echo ""
      echo "======================================"
      echo "🎉 배포 완료!"
      echo "======================================"
      DEPLOY_SCRIPT

      # 스크립트 실행
      chmod +x /tmp/deploy_script.sh
      /tmp/deploy_script.sh
      DEPLOY_EXIT=$?

      # 스크립트 삭제
      rm -f /tmp/deploy_script.sh /tmp/npm_install.log /tmp/npm_build.log

      exit $DEPLOY_EXIT
      ENDSSH

  # 배포 실패 시 알림 (선택사항)
  after_script:
    - echo "배포 프로세스가 완료되었습니다."

※참고로 브랜치가 보호되어 있지 않으면 변수에 값이 들어가지 않는다!!

0개의 댓글