
최근 배포 자동화를 공부하면서 실습 환경이 필요했는데, 마침 안 쓰는 노트북이 있어서 직접 서버를 구성해보기로 했습니다.
이 글은 Ubuntu Server 설치부터 GitLab CI/CD를 통한 자동 배포까지의 실습 과정을 기록한 내용입니다.
Ubuntu Server 설치 (Ubuntu PC)
Ubuntu Server ISO 다운로드
- 공식 사이트에 접속
- Ubuntu Server 22.04.4 LTS 클릭
- Download 버튼 눌러 ISO 파일 저장
부팅 USB 만들기 (Windows 기준, Rufus 사용)
- rufus.ie에서 Rufus 다운로드
- USB 메모리 PC에 꽂기
- Rufus 실행 후:
- 장치: 본인의 USB 선택
- 부트 선택: 다운로드한 ISO 파일 선택
- 나머지는 기본 설정 그대로
- '시작' 클릭 → 경고 메시지 뜨면 확인 → USB에 부팅 이미지 작성됨
노트북 부팅 & BIOS 설정
- USB 꽂은 상태로 노트북 부팅
- 부팅 시 BIOS 진입 (보통 F2, F10, DEL, ESC 중 하나)
- Boot Order 설정에서 USB가 1순위로 오게 변경
- 설정 저장 후 재부팅
Ubuntu Server 설치
📋 설치 단계 요약
Language | 보통 영어 선택 (English) |
Keyboard | 기본값 English (US) 유지 |
Network | 자동으로 DHCP로 설정됨 (수동도 가능) |
Proxy | 특별히 없으면 빈칸 Enter |
Mirror | 기본 서버 추천, Enter |
Storage | 디스크 파티션 설정 → Use an entire disk 선택 후 Done |
Profile | 사용자 계정 생성 (사용자명/비번 입력) |
OpenSSH Server | ✅ 꼭 체크! (SSH 원격접속용) |
Snap 패키지 설치 | 기본값으로 두고 Enter |
Install 진행 | 잠시 기다리면 설치 완료 |
설치가 완료되면 Reboot Now 선택 → USB 빼고 재부팅
설치 후 로그인
# 업데이트
sudo apt update
sudo apt upgrade -y
# IP 주소 확인 (SSH 접속용)
ip a
# 윈도우 PC에서 ssh 원격 접속 확인
ssh ubuntu@192.xxx.xxx.xxx
Node.js 프로젝트 생성
my-node-app 프로젝트 생성, express.js 설치
mkdir my-node-app
cd my-node-app
npm init -y
npm install express
index.js. 파일 생성
// index.js
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => res.send('Hello CI/CD!'));
app.listen(port, () => console.log(`Server running on port ${port}`));
package.json에 start script 추가
"scripts": {
"start": "node index.js"
}
GitLab Repository 생성
GitLab Repository 생성
소스 Pull & Push
cd my-node-app
git init
git remote add origin https://gitlab.com/***/my-node-app.git
git pull origin main --allow-unrelated-histories
git add .
git commit -m "init"
git push origin main
Ubuntu Server 에 GitLab Runner 설치 및 등록 (Ubuntu PC)
GitLab Runner 설치
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner
GitLab Runner 등록
- GitLab 접속
- 프로젝트 > Settings > CI/CD > Runners > Expand
- "Registration token" 복사
Registration token 복사
sudo gitlab-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
> https://gitlab.com/
Please enter the registration token:
> <내 리포지토리에서 복사한 토큰>
Please enter a description for the runner:
> my-node-runner
Please enter tags for the runner (comma-separated):
> nodejs
Please enter the executor: shell, docker, etc.:
> shell
.gitlab-ci.yml 파일 생성
Node.js 프로젝트 루트 경로에 .gitlab-ci.yml 파일 생성
stages:
- deploy
deploy:
stage: deploy
script:
- echo "🚀 Deploying..."
- pm2 delete all || true
- pm2 start index.js
tags:
- nodejs # GitLab Runner 태그
only:
- main # 또는 master
.gitlab-ci.yml 파일 기본 구조
- stages: 파이프라인에서 수행할 작업의 순서를 정의합니다.
- jobs: 각 작업을 정의합니다. 각 job은 stage에 속합니다.
- script: 각 job에서 실행할 명령어를 작성합니다.
- tags: GitLab Runner 등록 시 작성했던 tags 를 적어야 해당 태그의 Runner가 실행됩니다.
pm2
- PM2(Process Manager2)는 Node.js 애플리케이션을 프로덕션 환경에서 실행/관리하는 툴
- Node.js 앱을 백그라운드에서 안정적으로 실행
build, test, deploy 구조의 .gitlab-ci.yml 예시
stages:
- build
- test
- deploy
# 빌드 단계
build:
stage: build
script:
- npm install # 의존성 설치
- npm run build # 애플리케이션 빌드
# 테스트 단계
test:
stage: test
script:
- npm test # 테스트 실행
# 배포 단계
deploy:
stage: deploy
script:
- pm2 restart app # pm2로 애플리케이션 재시작 (배포 후)
only:
- main # main 브랜치에서만 배포
GitLab에 프로젝트 푸시
cd my-node-app
git add .
git commit -m "runner test"
git push origin main
자동배포 확인
.gitlab-ci.yml 파일에서 작성한 script 코드가 실행된 것을 확인할 수 있습니다.
Build > Pipelines에서 파이프라인 목록을 볼 수 있습니다.
에러사항
- .gitlab-ci.yml 파일 생성을 ubuntu server에 생성하여 gitlab runner를 등록하고 소스를 푸시해도 gitlab runner가 동작을 하지 않았습니다.
- .gitlab-ci.yml 파일을 저장소(root 디렉토리)에 작성하고 커밋함
- GitLab에 코드가 푸시되면, GitLab이 .gitlab-ci.yml 파일을 감지함
- GitLab이 연결된 GitLab Runner에게 파이프라인 실행 요청을 보냄
- GitLab Runner는 .gitlab-ci.yml에 정의된 대로 작업을 수행함 (빌드, 테스트, 배포 등)
- 첫 push에서 에러가 발생했는데 .gitlab-ci.yml의 display script 에 따라 pm2 start app.js 명령을 수행할 때 app.js 파일이 없어서 에러가 발생했습니다. 저는 index.js 파일을 올렸기 때문에 pm2 start index.js 로 명령어를 변경하여 해결했습니다.
- Just Do It -