GitLab CI/CD 및 Envoy를 사용하여 Laravel 애플리케이션 테스트 및 배포
소개
GitLab은 지속적 통합으로 애플리케이션을 제공하며, 원할 때 새 코드 변경 사항을 손쉽게 프로덕션 서버에 배포할 수 있습니다.
이 튜토리얼에서는 Laravel 애플리케이션을 초기화하고 Envoy 작업을 설정한 다음 GitLab CI/CD 및 지속적 제공을 통해 테스트하고 배포하는 방법을 안내합니다.
Laravel, Linux 서버 및 GitLab 사용 방법에 대한 기본적인 경험이 있다고 가정합니다.
Laravel은 PHP로 작성된 고품질 웹 프레임워크입니다. 환상적인 문서와 함께 커뮤니티가 크고 있습니다. 라우팅, 컨트롤러, 요청, 응답, 뷰 및 (블레이드) 템플릿 외에도 Laravel은 캐시, 이벤트, 로컬라이제이션, 인증 등 다양한 추가 서비스를 기본 제공합니다.
우리는 Envoy를 PHP 기반의 SSH 작업 실행기로 사용할 것입니다. 이는 원격 서버에서 실행할 수 있는 작업을 설정하기 위해 깨끗하고 최소한의 Blade 구문을 사용합니다. 예를 들어, 귀하의 프로젝트를 리포지터리에서 복제하고, Composer 의존성을 설치하고 Artisan 명령을 실행하는 등의 작업을 수행할 수 있습니다.
GitLab에서 Laravel 앱 초기화
Laravel 프로젝트를 설치했다고 가정하고, 단위 테스트를 시작하고 프로젝트용으로 Git을 초기화합시다.
단위 테스트
Laravel의 새로운 설치(현재 버전 8.0)에는 ‘피처’ 및 ‘단위’ 두 종류의 테스트가 포함되어 있습니다. 이는 tests 디렉터리에 위치합니다. 다음은 test/Unit/ExampleTest.php
에서의 단위 테스트 예시입니다:
<?php
namespace Tests\Unit;
...
class ExampleTest extends TestCase
{
public function testBasicTest()
{
$this->assertTrue(true);
}
}
이 테스트는 주어진 값이 참인지 단순히 단언하는 것입니다.
Laravel은 기본적으로 PHPUnit
을 사용하여 테스트합니다. vendor/bin/phpunit
을 실행하면 녹색 출력이 표시됩니다:
vendor/bin/phpunit
OK (1 test, 1 assertion)
이 테스트는 나중에 GitLab CI/CD를 사용하여 앱을 지속적으로 테스트하는 데 사용될 것입니다.
GitLab에 푸시
로컬에서 앱을 실행 중이므로 코드베이스를 원격 리포지터리에 푸시할 시간입니다. GitLab에서 laravel-sample
이라는 새 프로젝트를 만듭시다. 그 후, 프로젝트 홈페이지에 표시된 명령 줄 지침을 따라 우리의 기계에서 리포지터리를 초기화하고 첫 번째 커밋을 푸시합시다.
cd laravel-sample
git init
git remote add origin git@gitlab.example.com:<USERNAME>/laravel-sample.git
git add .
git commit -m 'Initial Commit'
git push -u origin main
프로덕션 서버 구성
Envoy 및 GitLab CI/CD를 설정하기 전에 먼저 프로덕션 서버가 배포에 준비되어 있는지 확인합시다. Ubuntu 16.04에서 Linux, NGINX, MySQL 및 PHP를 사용하여 LEMP 스택을 설치했습니다.
새 사용자 생성
이제 웹사이트를 배포하는 데 사용할 새 사용자를 만들고 Linux ACL를 사용하여 필요한 권한을 부여합시다:
# 사용자 deployer 생성
sudo adduser deployer
# /var/www 디렉터리에 대해 deployer 사용자에게 읽기-쓰기-실행 권한 부여
sudo setfacl -R -m u:deployer:rwx /var/www
Ubuntu 서버에 ACL이 설치되어 있지 않다면, 다음 명령을 사용하여 설치할 수 있습니다:
sudo apt install acl
SSH 키 추가
GitLab의 개인 리포지터리에서 프로덕션 서버로 앱을 배포하려면 먼저 SSH 키 쌍을 비밀번호 없이 생성해야 합니다. 그런 다음 해당 개인 키를 복사하여 SSH를 통해 프로덕션 서버에 연결하도록 사용하여 배포 프로세스를 자동화할 수 있습니다:
# 서버의 deployer 사용자로 실행
#
# 공개 키 내용을 authorized_keys에 복사합니다
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# 비공개 키 텍스트 블록을 복사합니다
cat ~/.ssh/id_rsa
그런 다음 이를 .gitlab-ci.yml에서 사용하여 프로덕션 서버에 deployer 사용자로 쉽게 연결할 수 있도록 나중에 사용할 CI/CD 변수에 추가합니다. 프로젝트 CI/CD 변수는 .gitlab-ci.yml
의 외부에 저장되는 사용자 정의 변수로, 보안 목적으로 사용됩니다. 프로젝트의 Settings > CI/CD로 이동하여 추가할 수 있습니다.
KEY 필드에 SSH_PRIVATE_KEY
라는 이름을 추가하고 VALUE 필드에 이전에 복사한 비공개 키를 붙여넣습니다. 나중에 .gitlab-ci.yml
에서 이 변수를 사용하여 deployer 사용자의 암호를 입력하지 않고 원격 서버에 쉽게 연결할 것입니다.
또한 이 공개 키를 Project > Settings > Repository의 배포 키로 추가해야 합니다. 이렇게 하면 SSH 프로토콜을 통해 서버에서 리포지터리에 액세스할 수 있습니다.
# 서버의 deployer 사용자로 실행
#
# 공개 키를 복사합니다
cat ~/.ssh/id_rsa.pub
제목 필드에 원하는 이름을 추가하고 키 필드에 공개 키를 붙여넣으세요.
이제 서버에서 리포지터리를 복제하여 deployer
사용자가 리포지터리에 액세스할 수 있는지 확인합시다.
# 서버의 deployer 사용자로 실행
#
git clone git@gitlab.example.com:<USERNAME>/laravel-sample.git
“계속해서 연결하시겠습니까 (yes/no)?”를 묻는 메시지가 나오면 yes로 대답합니다. 이렇게 하면 GitLab.com이 알려진 호스트로 추가됩니다.
NGINX 구성
이제 웹 서버 구성이 public
이 아닌 current/public
을 가리키도록 보장해봅시다.
다음을 입력하여 기본 NGINX 서버 블록 구성 파일을 엽니다.
sudo nano /etc/nginx/sites-available/default
구성은 다음과 같아야 합니다.
server {
root /var/www/app/current/public;
server_name example.com;
# 나머지 구성
}
/var/www/app/current/public
에 있는 앱 이름을 귀하의 애플리케이션 폴더 이름으로 대체할 수 있습니다.
Envoy 설정
이제 우리의 라라벨 앱은 프로덕션을 위해 준비되었습니다. 다음으로 Envoy를 사용하여 배포를 수행해야 합니다.
Envoy를 사용하려면 먼저 라라벨에서 제공하는 지침을 사용하여 로컬 머신에 설치해야 합니다.
Envoy 작동 방식
Envoy의 장점은 Blade 엔진이 필요하지 않다는 것입니다. 단순히 작업을 정의하기 위해 Blade 구문을 사용하는 것뿐입니다.
먼저 루트에 있는 Envoy.blade.php
를 만들어 간단한 Envoy 테스트 작업을 정의합니다.
@servers(['web' => 'remote_username@remote_host'])
@task('list', ['on' => 'web'])
ls -l
@endtask
예상대로 파일 상단에 @servers
지시문 내에 web
이라는 이름으로 서버 주소 값을 가진 배열이 있습니다 (예: deployer@192.168.1.1
).
그런 다음 @task
지시문 내에서 작업이 실행될 때 서버에서 실행해야 하는 bash 명령을 정의합니다.
로컬 머신에서 run
명령어를 사용하여 Envoy 작업을 실행합니다.
envoy run list
이 명령은 앞서 정의한 list
작업을 실행하여 서버에 연결하고 디렉터리 내용을 나열해야 합니다.
Envoy는 Laravel의 의존성이 아니므로 PHP 애플리케이션에 대해 사용할 수 있습니다.
제로 다운타임 배포
프로덕션 서버로 배포할 때마다 Envoy는 GitLab 리포지터리에서 앱의 최신 릴리스를 다운로드하고 미리보기 릴리스로 대체합니다. Envoy는 이를 다운타임 없이 수행하므로 배포 중에 사이트를 검토하는 사람이 있을 때 걱정할 필요가 없습니다. 우리의 배포 계획은 GitLab 리포지터리에서 최신 릴리스를 복제하고, Composer 의존성을 설치한 후에 새 릴리스를 활성화하는 것입니다.
@setup 지시문
우리의 배포 프로세스의 첫 번째 단계는 @setup 지시문 내에서 일련의 변수를 정의하는 것입니다.
app
을 귀하의 애플리케이션 이름으로 변경할 수 있습니다.
...
@setup
$repository = 'git@gitlab.example.com:<USERNAME>/laravel-sample.git';
$releases_dir = '/var/www/app/releases';
$app_dir = '/var/www/app';
$release = date('YmdHis');
$new_release_dir = $releases_dir .'/'. $release;
@endsetup
...
-
$repository
는 우리 리포지터리의 주소입니다. -
$releases_dir
디렉터리는 앱을 배포하는 위치입니다. -
$app_dir
은 서버에서 라이브인 앱의 실제 위치입니다. -
$release
는 날짜를 포함하므로 앱의 새 릴리스를 배포할 때마다 현재 날짜를 이름으로 하는 새 폴더를 얻게 됩니다. -
$new_release_dir
는 작업을 더 깔끔하게 만들기 위해 사용되는 새 릴리스의 전체 경로입니다.
@story 지시문
@story 지시문을 사용하여 하나의 작업으로 실행할 수 있는 작업 디렉터리을 정의할 수 있습니다.
여기서 clone_repository
, run_composer
, update_symlinks
라는 세 가지 작업이 있습니다. 이러한 변수는 우리의 작업 코드를 더욱 깔끔하게 만드는 데 사용됩니다.
...
@story('deploy')
clone_repository
run_composer
update_symlinks
@endstory
...
이제 하나씩 이렇게 세 작업을 만들어 봅시다.
리포지터리 복제
첫 번째 작업은 releases
디렉터리 (없으면)를 만든 다음 리포지터리의 main
브랜치 (기본값)를 새 릴리스 디렉터리에 복제합니다. 이때 $new_release_dir
변수로 새 릴리스 디렉터리를 제공합니다.
releases
디렉터리에는 우리의 모든 배포가 유지됩니다.
...
@task('clone_repository')
echo 'Cloning repository'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
git clone --depth 1 {{ $repository }} {{ $new_release_dir }}
cd {{ $new_release_dir }}
git reset --hard {{ $commit }}
@endtask
...
프로젝트가 성장함에 따라 Git 히스토리가 시간이 지남에 따라 매우 길어질 것입니다.
릴리스마다 디렉터리를 만드는 것이기 때문에 각 릴리스에 프로젝트의 히스토리가 다운로드되어 있는 것이 절대로 필요하지 않을 수 있습니다.
--depth 1
옵션은 시스템 시간과 디스크 공간을 절약하는 훌륭한 해결책입니다.
Composer를 사용하여 의존성 설치
이 작업은 새 릴리스 디렉터리로 이동한 후 Composer를 사용하여 응용 프로그램 의존성을 설치합니다.
...
@task('run_composer')
echo "Starting deployment ({{ $release }})"
cd {{ $new_release_dir }}
composer install --prefer-dist --no-scripts -q -o
@endtask
...
새 릴리스 활성화
새 릴리스의 요구 사항을 준비한 후에 해야 할 다음 단계는 해당 디렉터리에서 스토리지 디렉터리를 제거하고 애플리케이션의 storage
디렉터리와 .env
파일을 새 릴리스로 가리키도록 두 개의 심볼릭 링크를 만드는 것입니다.
그런 다음, 애플리케이션 디렉터리에 current
라는 이름으로 새 릴리스에 대한 다른 심볼릭 링크를 만들어야 합니다.
current
심볼릭 링크는 항상 우리 앱의 최신 릴리스를 가리킵니다.
...
@task('update_symlinks')
echo "Linking storage directory"
rm -rf {{ $new_release_dir }}/storage
ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage
echo 'Linking .env file'
ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env
echo 'Linking current release'
ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask
보시다시피 ln
명령의 옵션으로 -nfs
를 사용하여 storage
, .env
및 current
가 이제는 미리보기 릴리스를 가리키지 않고 강제로 새 릴리스를 가리키도록 해야 합니다 (f
는 -nfs
의 f
가 강제를 의미합니다). 이는 여러 번 배포를 수행할 경우의 경우입니다.
전체 스크립트
스크립트는 준비되었지만, deployer@192.168.1.1
을 여러분의 서버로, 그리고 /var/www/app
은 앱을 배포하려는 디렉터리로 변경해야 합니다.
마지막으로, Envoy.blade.php
파일은 다음과 같이 보일 것입니다:
@servers(['web' => 'deployer@192.168.1.1'])
@setup
$repository = 'git@gitlab.example.com:<USERNAME>/laravel-sample.git';
$releases_dir = '/var/www/app/releases';
$app_dir = '/var/www/app';
$release = date('YmdHis');
$new_release_dir = $releases_dir .'/'. $release;
@endsetup
@story('deploy')
clone_repository
run_composer
update_symlinks
@endstory
@task('clone_repository')
echo '리포지터리 복제 중'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
git clone --depth 1 {{ $repository }} {{ $new_release_dir }}
cd {{ $new_release_dir }}
git reset --hard {{ $commit }}
@endtask
@task('run_composer')
echo "배포 시작 ({{ $release }})"
cd {{ $new_release_dir }}
composer install --prefer-dist --no-scripts -q -o
@endtask
@task('update_symlinks')
echo '리포지터리 디렉터리 링크 중'
rm -rf {{ $new_release_dir }}/storage
ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage
echo '.env 파일 링크 중'
ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env
echo '현재 릴리스 링크 중'
ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask
첫 배포 이전에 애플리케이션의 storage
폴더를 서버의 /var/www/app
디렉터리로 매뉴얼으로 복사해야 할 필요가 있습니다.
이를 위해 Envoy 작업을 생성할 수도 있습니다.
또한 Laravel의 프로덕션 환경 변수를 설정하기 위해 동일한 경로에 .env
파일을 생성합니다.
이러한 데이터는 영속적이며 모든 새 릴리스에 공유될 것입니다.
이제 envoy run deploy
를 실행하여 앱을 배포해야 할 것입니다. 그러나 GitLab이 환경으로 배포를 처리할 수 있기 때문에 이 튜토리얼의 이후에 설명될 것이기 때문에 필요하지 않을 것입니다.
이제 Envoy.blade.php를 커밋하고 main
브랜치로 푸시할 때입니다.
협업은 이 튜토리얼의 범위를 벗어나므로 기능 브랜치를 사용하지 않고 직접적으로 main
에 커밋합니다.
실제 프로젝트에서 팀은 코드를 브랜치 간에 이동하기 위해 Issue Tracker 및 Merge Request을 사용할 수 있습니다.
git add Envoy.blade.php
git commit -m 'Envoy 추가'
git push origin main
GitLab을 이용한 지속적 통합
우리는 GitLab에서 준비된 앱을 매뉴얼으로 배포할 수 있습니다. 그러나 지속적 전달 방법을 사용하여 자동으로 수행해보겠습니다. 가장 빨리 문제를 인식하기 위해 각 커밋을 일련의 자동화된 테스트로 확인해야 하며, 그 결과에 만족한다면 대상 환경에 배포할 수 있게 됩니다.
GitLab CI/CD를 사용하여 Docker 엔진을 사용하여 앱의 테스트 및 배포 프로세스를 처리할 수 있습니다. Docker에 익숙하지 않다면 자동 빌드 설정을 참조하세요.
GitLab CI/CD를 사용하여 앱을 테스트하고 배포하기 위해 작업 환경을 준비해야 합니다. Laravel 앱에서 실행되는 데 필요한 최소 요구 사항을 갖춘 Docker 이미지를 사용할 것입니다. 다른 방법도 있지만, 더 빠른 옵션을 사용할 수 있으므로 빌드가 느리게 실행되지 않도록 주의해야 합니다.
컨테이너 이미지 생성
우리 앱의 루트 디렉터리에 다음과 같은 내용으로 Dockerfile을 생성합니다:
# 다음 명령을 위한 기본 이미지 설정
FROM php:7.4
# 패키지 업데이트
RUN apt-get update
# PHP 및 컴포저 의존성 설치
RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev
# 로컬 리포지터리의 패키지 파일 정리
RUN apt-get clean
# 필요한 확장 기능 설치
# 여기에는 테스트 및 배포 프로세스 중에 필요한 다른 확장 기능을 설치할 수 있습니다
RUN docker-php-ext-install mcrypt pdo_mysql zip
# 컴포저 설치
RUN curl --silent --show-error "https://getcomposer.org/installer" | php -- --install-dir=/usr/local/bin --filename=composer
# Laravel Envoy 설치
RUN composer global require "laravel/envoy=~1.0"
우리는 공식 PHP 7.4 Docker 이미지를 추가했는데, 이 이미지는 Debian buster의 최소 설치와 PHP가 미리 설치된 것으로 우리의 사용 사례에 완벽히 적합합니다.
우리는 PHP 확장 기능을 설치하기 위해 docker-php-ext-install
을 사용했습니다(공식 PHP Docker 이미지에서 제공).
GitLab 컨테이너 레지스트리 설정
이제 Dockerfile
을 생성했으므로 이를 GitLab 컨테이너 레지스트리에 빌드하고 푸시합니다.
레지스트리는 이미지를 저장하고 나중에 사용할 태그를 지정하는 곳입니다. 개발자들은 개인 또는 회사 이미지, 또는 테스트에서만 사용되는 일회성 이미지를 위한 자체 레지스트리를 유지하길 원할 수 있습니다. GitLab 컨테이너 레지스트리를 사용하면 또 다른 서비스를 설정하고 관리할 필요가 없으며 공개 레지스트리를 사용할 필요가 없습니다.
GitLab 프로젝트 리포지터리에서 레지스트리 탭으로 이동합니다.
레지스트리를 사용하려면 프로젝트의 설정 > 일반 > 가시성, 프로젝트 기능, 권한에서 컨테이너 레지스트리를 활성화해야 합니다.
로컬 머신에서 컨테이너 레지스트리를 사용하기 위해서는 먼저 GitLab 사용자 이름과 암호로 GitLab 레지스트리에 로그인해야 합니다. 먼저 Docker가 로컬 머신에 설치되어 있는지 확인하신 후, 다음 명령을 실행합니다:
docker login registry.gitlab.com
그런 다음 이미지를 빌드하고 GitLab으로 푸시할 수 있습니다:
docker build -t registry.gitlab.com/<USERNAME>/laravel-sample .
docker push registry.gitlab.com/<USERNAME>/laravel-sample
축하합니다! 첫 번째 Docker 이미지를 GitLab 레지스트리에 푸시했습니다. 페이지를 새로 고치면 이미지를 확인할 수 있습니다:
또한 머신에서 직접적으로 하는 대신 GitLab CI/CD를 사용하여 Docker 이미지를 빌드하고 푸시할 수 있습니다.
이 이미지를 .gitlab-ci.yml 구성 파일에서 우리 앱의 테스트 및 배포 프로세스를 처리하기 위해 사용할 것입니다.
Dockerfile
파일을 커밋합시다.
git add Dockerfile
git commit -m 'Dockerfile 추가'
git push origin main
GitLab CI/CD 설정
GitLab CI/CD를 사용하여 앱을 빌드하고 테스트하려면 리포지터리 루트에 .gitlab-ci.yml
이라는 파일이 필요합니다. 이 파일은 Circle CI 및 Travis CI와 유사하지만 GitLab에 기본으로 제공됩니다.
우리의 .gitlab-ci.yml
파일은 다음과 같을 것입니다:
default:
image: registry.gitlab.com/<USERNAME>/laravel-sample:latest
services:
- mysql:5.7
variables:
MYSQL_DATABASE: homestead
MYSQL_ROOT_PASSWORD: secret
DB_HOST: mysql
DB_USERNAME: root
stages:
- test
- deploy
unit_test:
stage: test
script:
- cp .env.example .env
- composer install
- php artisan key:generate
- php artisan migrate
- vendor/bin/phpunit
deploy_production:
stage: deploy
script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- ~/.composer/vendor/bin/envoy run deploy --commit="$CI_COMMIT_SHA"
environment:
name: production
url: http://192.168.1.1
when: manual
rules:
- if: $CI_COMMIT_BRANCH == "main"
이것은 많은 정보를 담고 있네요. 이제 한 단계씩 짚어봅시다.
이미지 및 서비스
Runners는 .gitlab-ci.yml
에서 정의된 스크립트를 실행합니다. image
키워드는 러너에 사용할 이미지를 지정합니다. services
키워드는 주 이미지에 연결된 추가 이미지를 정의합니다. 여기서는 우리가 이전에 만든 컨테이너 이미지를 주 이미지로 사용하고 MySQL 5.7을 서비스로 사용합니다.
default:
image: registry.gitlab.com/<USERNAME>/laravel-sample:latest
services:
- mysql:5.7
...
만약 앱을 다른 PHP 버전 및 데이터베이스 관리 시스템으로 테스트하려면 각 테스트 작업에 대해 다른 image
및 services
키워드를 정의할 수 있습니다.
CI/CD 변수
GitLab CI/CD는 CI/CD 변수를 작업에서 사용할 수 있도록 합니다. 우리는 데이터베이스 관리 시스템으로 MySQL을 정의했으며, 기본적으로 superuser root가 생성됩니다.
따라서 MySQL 인스턴스의 구성을 조정하기 위해 MYSQL_DATABASE
변수를 데이터베이스 이름으로, MYSQL_ROOT_PASSWORD
변수를 root
의 비밀번호로 정의해야 합니다. MySQL 변수에 대해 더 알아보려면 공식 MySQL Docker 이미지에서 확인할 수 있습니다.
또한 Laravel 특정 변수인 DB_HOST
를 mysql
로, DB_USERNAME
을 root
로 설정했습니다. 우리는 데이터베이스 서비스로 MySQL Docker 이미지를 사용하고 있기 때문에 DB_HOST
를 127.0.0.1
대신 mysql
로 정의했습니다. (서비스가 작업에 연결되는 방법을 참조하세요)
variables:
MYSQL_DATABASE: homestead
MYSQL_ROOT_PASSWORD: secret
DB_HOST: mysql
DB_USERNAME: root
첫 번째 작업으로의 단위 테스트
unit_test
작업에서는 script
키워드의 배열로 필요한 쉘 스크립트를 정의했습니다. 이 스크립트는 Laravel을 준비하기 위한 몇 가지 Artisan 명령어들이며, 스크립트의 끝에서 PHPUnit
으로 테스트를 실행할 것입니다.
unit_test:
script:
# 앱 의존성 설치
- composer install
# .env 설정
- cp .env.example .env
# 환경 키 생성
- php artisan key:generate
# 마이그레이션 실행
- php artisan migrate
# 테스트 실행
- vendor/bin/phpunit
프로덕션 배포
deploy_production
작업은 앱을 프로덕션 서버에 배포할 것입니다. Envoy를 사용하여 앱을 배포하기 위해 SSH 개인 키인 $SSH_PRIVATE_KEY
변수를 설정해야 합니다. SSH 키가 성공적으로 추가되면 Envoy를 실행할 수 있습니다.
앞서 언급했듯이, GitLab은 Continuous Delivery 방법을 지원합니다. environment
키워드는 이 작업이 production
환경으로 배포되어야 함을 GitLab에 알려줍니다. url
키워드는 GitLab 환경 페이지에서 앱에 대한 링크를 생성하는 데 사용됩니다. rules:if
키워드는 작업이 main
브랜치를 빌드할 때에만 실행되어야 함을 GitLab CI/CD에 알려줍니다. 마지막으로 when: manual
은 작업을 자동으로 실행되는 것에서 매뉴얼 조치로 변경하기 위해 사용됩니다.
deploy_production:
script:
# 빌드 환경에 개인 SSH 키 추가
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
# Envoy 실행
- ~/.composer/vendor/bin/envoy run deploy
environment:
name: production
url: http://192.168.1.1
when: manual
rules:
- if: $CI_COMMIT_BRANCH == "main"
앱을 프로덕션 환경에 배포하기 전에 스테이징 환경에 대한 다른 작업을 추가하고 싶을 수도 있습니다. 이를 통해 프로덕션 배포에 앞서 앱을 최종적으로 테스트할 수 있습니다.
GitLab CI/CD 활성화
GitLab CI/CD로 앱을 테스트하고 배포할 준비가 되었습니다. 이제 .gitlab-ci.yml
을 main
브랜치에 커밋하고 푸시하면 파이프라인이 트리거됩니다. 이를 프로젝트의 Pipelines에서 실시간으로 확인할 수 있습니다.
여기에서 Test 및 Deploy 단계가 표시됩니다. Test 단계에 unit_test
빌드가 실행 중인 것을 볼 수 있습니다. 이를 선택하여 러너의 출력을 확인할 수 있습니다.
코드가 성공적으로 파이프라인을 통과한 후, 우리는 오른쪽에 있는 재생 버튼을 선택하여 우리의 프로덕션 서버에 배포할 수 있습니다.
배포 파이프라인이 성공적으로 통과하면 Pipelines > Environments로 이동하세요.
예상대로 작동하지 않는 경우, 앱의 최신 작동 버전으로 롤백할 수 있습니다.
우측에 지정된 외부 링크 아이콘을 선택하면 GitLab이 프로덕션 웹사이트를 엽니다. 우리의 배포가 성공적으로 이루어졌으며 애플리케이션이 활성화되었음을 확인할 수 있습니다.
배포 후 프로덕션 서버의 응용프로그램 디렉터리 구조에 관심이 있는 경우, current
, releases
, storage
라는 세 가지 디렉터리가 있습니다. current
디렉터리는 최신 릴리스를 가리키는 심볼릭 링크입니다. .env
파일은 우리의 Laravel 계열 변수입니다.
current
디렉터리로 이동하면 애플리케이션의 내용을 확인할 수 있습니다. .env
가 /var/www/app/.env
파일을 가리키고 storage
는 /var/www/app/storage/
디렉터리를 가리키고 있음을 확인할 수 있습니다.
결론
우리는 GitLab CI/CD를 구성하여 자동화된 테스트를 수행하고 Continuous Delivery 방법을 사용하여 Envoy를 통해 라라벨 애플리케이션을 코드베이스에서 직접 프로덕션 환경에 배포했습니다.
또한 Envoy는 우리가 사용자 정의 bash 스크립트를 작성하지 않고 Linux 마법을 사용하여 애플리케이션을 배포하는 데 크게 도움이 되었습니다.