InfoGrab DocsInfoGrab Docs

GitLab CI/CD에서 SCP를 통한 배포와 함께 Composer 및 npm 스크립트 실행

요약

GitLab CI/CD를 사용해 PHP 프로젝트의 의존성을 빌드하면서 npm 스크립트로 에셋을 컴파일합니다. 사용자 정의 PHP 및 Node.js 버전으로 자체 이미지를 만들 수도 있습니다. 다음 단계는 zip/unzip 패키지와 Node.js를 설치하고 Composer를 사용할 수 있게 만드는 것입니다.

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 스크립트입니다.

  1. CSS 및 JS 컴파일
  2. 스프라이트 생성
  3. 다양한 에셋(이미지, 폰트)을 여러 위치로 복사
  4. 일부 문자열 치환

이 모든 작업은 모든 파일을 build 폴더에 넣으며, 이 폴더는 실제 서버에 배포할 준비가 됩니다.

실제 서버로 파일을 전송하는 방법#

rsync, SCP, SFTP 등 여러 옵션을 사용할 수 있습니다. 여기서는 SCP를 사용합니다.

이를 위해서는 GitLab CI/CD 변수(gitlab.example/your-project-name/variables에서 접근 가능)를 추가해야 합니다. 이 변수의 이름을 STAGING_PRIVATE_KEY로 지정하고 서버의 private 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'

이 스크립트는 다음 작업을 수행합니다.

  1. ssh-agent를 사용할 수 있는지 확인하고, 없으면 설치합니다.
  2. ~/.ssh 폴더를 생성합니다.
  3. 스크립트 실행 환경이 bash로 실행되고 있는지 확인합니다.
  4. 호스트 확인을 비활성화합니다. 모든 연결은 새로운 환경에서 이루어지므로, 호스트 확인을 비활성화하면 GitLab이 매번 연결 전에 사용자에게 서버의 신원을 확인하고 수락하도록 요청하지 않습니다.

이것이 before_script 섹션에 필요한 내용의 전부입니다.

배포 방법#

Docker 이미지에서 서버로 build 폴더를 배포하려면 새 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"

세부 내용은 다음과 같습니다.

  1. rules:if: $CI_COMMIT_BRANCH == "dev"는 이 빌드가 dev 브랜치에 푸시될 때만 실행됨을 의미합니다. 이 블록을 완전히 제거하고 모든 푸시에서 전부 실행되게 할 수도 있습니다(다만 이는 원하지 않는 동작일 가능성이 높습니다).
  2. ssh-add ...는 웹 UI에서 추가한 private 키를 Docker 컨테이너에 추가합니다.
  3. ssh를 사용해 연결하고 새 _tmp 폴더를 생성합니다.
  4. scp를 사용해 연결하고 (npm 스크립트로 생성된) build 폴더를 이전에 생성한 _tmp 폴더로 업로드합니다.
  5. 다시 ssh를 사용해 연결하고 live 폴더를 _old 폴더로 이동한 다음, _tmp를 live로 이동합니다.
  6. 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 프로젝트였기 때문에 실제 코드 스니펫을 포함하고 있습니다. 이어서 시도해 볼 수 있는 아이디어는 다음과 같습니다.

  • 기본 브랜치용 스크립트를 약간 다르게 구성하면 해당 브랜치에서는 프로덕션 서버로 배포하고, 다른 브랜치에서는 스테이징 서버로 배포할 수 있습니다.
  • 실제 서버로 바로 푸시하는 대신 WordPress 공식 리포지터리로 푸시할 수 있습니다.
  • 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"

GitLab CI/CD에서 SCP를 통한 배포와 함께 Composer 및 npm 스크립트 실행

GitLab v19.5
Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기

요약

GitLab CI/CD를 사용해 PHP 프로젝트의 의존성을 빌드하면서 npm 스크립트로 에셋을 컴파일합니다. 사용자 정의 PHP 및 Node.js 버전으로 자체 이미지를 만들 수도 있습니다. 다음 단계는 zip/unzip 패키지와 Node.js를 설치하고 Composer를 사용할 수 있게 만드는 것입니다.

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 스크립트입니다.

  1. CSS 및 JS 컴파일
  2. 스프라이트 생성
  3. 다양한 에셋(이미지, 폰트)을 여러 위치로 복사
  4. 일부 문자열 치환

이 모든 작업은 모든 파일을 build 폴더에 넣으며, 이 폴더는 실제 서버에 배포할 준비가 됩니다.

실제 서버로 파일을 전송하는 방법#

rsync, SCP, SFTP 등 여러 옵션을 사용할 수 있습니다. 여기서는 SCP를 사용합니다.

이를 위해서는 GitLab CI/CD 변수(gitlab.example/your-project-name/variables에서 접근 가능)를 추가해야 합니다. 이 변수의 이름을 STAGING_PRIVATE_KEY로 지정하고 서버의 private 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'

이 스크립트는 다음 작업을 수행합니다.

  1. ssh-agent를 사용할 수 있는지 확인하고, 없으면 설치합니다.
  2. ~/.ssh 폴더를 생성합니다.
  3. 스크립트 실행 환경이 bash로 실행되고 있는지 확인합니다.
  4. 호스트 확인을 비활성화합니다. 모든 연결은 새로운 환경에서 이루어지므로, 호스트 확인을 비활성화하면 GitLab이 매번 연결 전에 사용자에게 서버의 신원을 확인하고 수락하도록 요청하지 않습니다.

이것이 before_script 섹션에 필요한 내용의 전부입니다.

배포 방법#

Docker 이미지에서 서버로 build 폴더를 배포하려면 새 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"

세부 내용은 다음과 같습니다.

  1. rules:if: $CI_COMMIT_BRANCH == "dev"는 이 빌드가 dev 브랜치에 푸시될 때만 실행됨을 의미합니다. 이 블록을 완전히 제거하고 모든 푸시에서 전부 실행되게 할 수도 있습니다(다만 이는 원하지 않는 동작일 가능성이 높습니다).
  2. ssh-add ...는 웹 UI에서 추가한 private 키를 Docker 컨테이너에 추가합니다.
  3. ssh를 사용해 연결하고 새 _tmp 폴더를 생성합니다.
  4. scp를 사용해 연결하고 (npm 스크립트로 생성된) build 폴더를 이전에 생성한 _tmp 폴더로 업로드합니다.
  5. 다시 ssh를 사용해 연결하고 live 폴더를 _old 폴더로 이동한 다음, _tmp를 live로 이동합니다.
  6. 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 프로젝트였기 때문에 실제 코드 스니펫을 포함하고 있습니다. 이어서 시도해 볼 수 있는 아이디어는 다음과 같습니다.

  • 기본 브랜치용 스크립트를 약간 다르게 구성하면 해당 브랜치에서는 프로덕션 서버로 배포하고, 다른 브랜치에서는 스테이징 서버로 배포할 수 있습니다.
  • 실제 서버로 바로 푸시하는 대신 WordPress 공식 리포지터리로 푸시할 수 있습니다.
  • 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"