반응형

서론

 

이번에 개발을 진행하면서, 인트라넷에 있는 Laravel Project를 AWS EC2에 배포해야 되는 상황이 왔다.

AWS ECR을 사용하여, 도커 이미지를 빌드하고 EC2에서는 AWS ECR의 이미지를 당겨오는 방식으로 배포를 진행하였다.

 

EC2 내부에 nginx가 설치되어 있는 상태이며 비용 문제상 EC2 내부에 mysql 도 같이 설치 되어 있는 상태였다.

일단 가장 중요한건 Dockefile 구성화 gitrunner 혹은 gitaction 에서의 처리 방법.

 

.env 파일은 git repo에 등재가 되면 안되기 때문에 variables로 등록 된 후 배포시 파일을 생성하여 포함해 주도록 처리하였다.

 

전제로는, AWS ECR IAM 계정 및 정책이 있어야 한다. 또한, AWS CLI이 설치가 되어있어야 한다.

해당부분은 추후 포스팅을 진행해야겠다.

 

 

IAM ECR 관련 정책 추가 내용

bash
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:CompleteLayerUpload", "ecr:GetAuthorizationToken", "ecr:UploadLayerPart", "ecr:InitiateLayerUpload", "ecr:BatchCheckLayerAvailability", "ecr:PutImage", "ecr:DescribeRepositories" ], "Resource": "*" } ] }

 

 

Laravel Dockerfile

 

bash
FROM php:8.2-fpm WORKDIR /var/www/html RUN apt-get update && apt-get install -y \ git \ unzip \ libpng-dev \ libjpeg-dev \ libfreetype6-dev \ libzip-dev \ zip \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install gd pdo pdo_mysql zip RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer COPY . . RUN composer install RUN chown -R www-data:www-data /var/www/html/storage RUN chmod -R 755 /var/www/html/storage EXPOSE 9000 CMD ["php-fpm"]

기본 이미지를 php fpm을 사용하였고 php 의존성들을 설치하고 컴포저를 설치하였다.

해당 부분을 gitaction이나 gitrunner 등에서 docker file build 처리해주면 된다.

 

gitrunner gitlab-ci.yml 예제

 

bash
stages: - build - deploy build: stage: build image: docker:latest before_script: - apk add python3 - apk add py3-pip - pip3 install awscli script: - echo "$SERVER_ENV" >> .env - echo "$PUBLIC_OAUTH_KEY" >> storage/oauth-public.key - echo "$PRIVATE_OAUTH_KEY" >> storage/oauth-private.key - cat .env - docker build --tag [ECR PATH/image]:latest . - aws configure set aws_access_key_id "$AWS_ACCESS_KEY_ID" - aws configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY" - aws configure set region "$AWS_DEFAULT_REGION" - aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin [ECR PATH] - docker tag [ECR PATH/image]:latest [ECR PATH]:$CI_COMMIT_SHORT_SHA - docker push [ECR PATH/image]:$CI_COMMIT_SHORT_SHA - docker push [ECR PATH/image]:latest services: - docker:dind only: - master deploy: stage: deploy script: - mkdir -p ~/.ssh - echo "$AWS_SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H $AWS_SSH_HOST >> ~/.ssh/known_hosts - ssh $AWS_SSH_USER@$AWS_SSH_HOST "aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin [ECR PATH]" - ssh $AWS_SSH_USER@$AWS_SSH_HOST "[ECR PATH/image]:latest" - ssh $AWS_SSH_USER@$AWS_SSH_HOST "./deploy.sh" only: - master

 

 

deploy.sh

 

bash
docker stop api docker rm api docker run -d --name api [ECR path]:latest docker exec api php artisan migrate # 이미지 태그가 latest가 없는 이미지들의 이미지 ID 값을 가져오기 image_ids=$(docker images | grep -v "latest" | awk '{print $3}') # 이미지들을 순회하며 docker rmi 명령어로 이미지 삭제 for image_id in $image_ids; do if [ "$image_id" != "IMAGE" ] && docker images | grep -q "$image_id"; then echo "$image_id" docker rmi "$image_id" else echo "Image with ID $image_id not found. Skipping deletion." fi done

 

nginx conf

bash
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html/public; index index.html index.htm index.nginx-debian.html index.php; server_name sub-api.arkinfo.kr; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include fastcgi_params; fastcgi_pass [docker inspect [container] ip]:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }

 

 

 

반응형