GitLab CI/CD에서 Composer·npm 스크립트 실행 및 SCP 배포
GitLab CI/CD에서 Composer·npm 스크립트 실행 및 SCP 배포
PHP 프로젝트에서 npm 스크립트로 에셋을 컴파일하면서 의존성을 빌드하고, 완성된 파일을 SCP로 운영 서버에 배포하는 워크플로를 만들어 볼게요. GitLab CI/CD 하나로 PHP 의존성 설치부터 프런트엔드 빌드, 원격 서버 배포까지 전 과정을 자동화하는 방법을 단계별로 따라 해 볼 수 있습니다.
출처: 문서
본문
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
GitLab CI/CD를 사용해 PHP 프로젝트의 의존성을 빌드하면서 npm 스크립트로 에셋을 컴파일해 봅시다.
커스텀 PHP·Node.js 버전을 가진 자신만의 이미지를 만들 수도 있어요. 여기서는 간결함을 위해 공식 php Docker 이미지를 사용하고, before_script에서 Node.js를 설치하겠습니다.
image: php:8.3
다음 단계는 zip/unzip 패키지와 Node.js를 설치하고 Composer를 사용할 수 있게 하는 거예요. 이들을 before_script 섹션에 넣으세요.
before_script:
- apt-get update
- apt-get install -y git zip unzip nodejs npm
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
이렇게 하면 모든 요구 사항이 준비됩니다. 다음으로 composer install로 모든 PHP 의존성을 가져오고, npm install로 Node.js 패키지를 불러온 뒤 npm 스크립트를 실행하세요. before_script 섹션에 명령을 추가합니다.
before_script:
# ...
- php composer.phar install
- npm install
- npm run deploy
이 예제에서 npm deploy 스크립트는 다음과 같은 일을 하는 Gulp 스크립트예요.
- CSS & JS 컴파일
- 스프라이트 생성
- 다양한 에셋(이미지, 폰트) 복사
- 일부 문자열 교체
이 모든 작업은 파일을 build 폴더에 모아 두며, 이 폴더는 운영 서버에 배포할 준비가 된 상태입니다.
운영 서버에 파일을 전송하는 방법
rsync, SCP, SFTP 같은 여러 옵션이 있어요. 여기서는 SCP를 사용하겠습니다.
이를 동작시키려면 GitLab CI/CD 변수를 하나 추가해야 해요 (gitlab.example/your-project-name/variables에서 접근 가능). 변수 이름은 STAGING_PRIVATE_KEY로 하고, 서버의 프라이빗 SSH 키 값으로 설정하세요.
보안 팁
업데이트가 필요한 폴더에만 접근할 수 있는 사용자를 만들어 두세요.
그 변수를 만든 뒤, 실행 시 Docker 컨테이너에 그 키가 추가되도록 하세요.
before_script:
# - ....
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
이 스크립트는 다음 작업을 수행해요.
- ssh-agent가 있는지 확인하고 없으면 설치
~/.ssh폴더 생성- 스크립트 실행 환경이 bash로 동작하는지 확인
- 호스트 검사 비활성화 — 모든 연결이 새 환경에서 일어나므로, 호스트 검사를 끄면 GitLab이 매번 연결 전에 서버 신원을 확인·수락하도록 요구하지 않아요.
before_script 섹션에는 기본적으로 이것만 있으면 됩니다.
배포 방법
빌드 폴더를 Docker 이미지에서 서버로 배포하려면 새 job을 만드세요.
stage_deploy:
artifacts:
paths:
- build/
rules:
- if: $CI_COMMIT_BRANCH == "dev"
script:
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
- ssh -p22 server_user@server_host "mkdir htdocs/wp-content/themes/_tmp"
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/_tmp
- ssh -p22 server_user@server_host "mv htdocs/wp-content/themes/live htdocs/wp-content/themes/_old && mv htdocs/wp-content/themes/_tmp htdocs/wp-content/themes/live"
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/_old"
구성을 하나씩 살펴볼게요.
rules:if: $CI_COMMIT_BRANCH == "dev"는 dev 브랜치에 무언가를 push할 때만 이 빌드가 실행된다는 뜻이에요. 이 블록을 완전히 제거하면 모든 push마다 실행되도록 할 수 있지만, 아마 원하지 않을 거예요.ssh-add ...는 웹 UI에서 추가한 프라이빗 키를 Docker 컨테이너에 더해줘요.- ssh로 연결해 새
_tmp폴더를 만들어요. - scp로 연결해 npm 스크립트로 생성된
build폴더를 앞서 만든_tmp폴더에 업로드해요. - 다시 ssh로 연결해
live폴더를_old폴더로 옮기고,_tmp를live로 옮겨요. - SSH로 연결해
_old폴더를 제거해요.
artifacts 섹션은 GitLab CI/CD에게 build 디렉터리를 보관하도록 지시합니다(나중에 필요하면 다운로드할 수 있어요).
왜 이렇게 하는가
스테이징 서버에만 이걸 쓴다면 두 단계로 끝낼 수 있어요.
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/live/*"
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/live
문제는 서버에 앱이 없는 짧은 시간이 생긴다는 거예요.
그래서 프로덕션 환경에서는 추가 단계를 통해 언제든 기능하는 앱이 자리 잡고 있도록 보장합니다.
다음 단계
WordPress 프로젝트였기 때문에 실제 코드 조각이 포함돼 있어요. 이어서 시도해 볼 수 있는 아이디어는 다음과 같습니다.
- 기본 브랜치용 스크립트를 조금 다르게 만들면, 그 브랜치에서 프로덕션 서버로, 다른 브랜치에서는 스테이징 서버로 배포할 수 있어요.
- 라이브로 push하는 대신 WordPress 공식 저장소로 push할 수도 있어요.
- i18n 텍스트 도메인을 즉석에서 생성할 수도 있어요.
최종 .gitlab-ci.yml은 다음과 같아요.
stage_deploy:
image: php:8.3
artifacts:
paths:
- build/
rules:
- if: $CI_COMMIT_BRANCH == "dev"
before_script:
- apt-get update
- apt-get install -y git zip unzip nodejs npm
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
- php composer.phar install
- npm install
- npm run deploy
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
- ssh -p22 server_user@server_host "mkdir htdocs/wp-content/themes/_tmp"
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/_tmp
- ssh -p22 server_user@server_host "mv htdocs/wp-content/themes/live htdocs/wp-content/themes/_old && mv htdocs/wp-content/themes/_tmp htdocs/wp-content/themes/live"
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/_old"
더 알아보기 (Learn more)
SSH 키를 CI/CD job에서 안전하게 사용하는 방법은 SSH 키 문서를, CI/CD 변수 설정은 GitLab CI/CD 변수 문서를 참고하세요. 다른 배포 예제는 CI/CD 예제에서 확인할 수 있어요.