본문 바로가기

프로그래밍/Docker

NginX 와 php 환경의 Docker 컨네이트 배포

728x90
반응형

개요

  • 기존 php + apache +svn 형태의 프로젝트를 php + nginx(php+fpm) + git 으로 전환
  • 배포 환경은 jenkins Build + rancher Deploy로 전환
  • php 로는 UI 를 구현한 부분은 그대로 유지하고, backend api 부분은 spring boot로 전환
  • nginx에서 php는 php-fpm(PHP FastCGI Process Manager)을 통해 실행

기본 Base Dockerfile 생성

  • https://hub.docker.com/_/php 에 php 오피션 이미지가 있지만 기존 코드가 최신 버전의 문법에 맞지 않는 부분이 일부 있어서 php를 하위 버전으로 설치하였습니다.
  • 컨테이너 실행 후 php5 라이브러리 설치 테스트를 진행하였습니다. 이는 Dockerfile 파일에 들어갈 php 라이브러리가 실제 존재하는지 테스트 해보는 것입니다.
docker run -i -t harbor.xxx.co.kr/java/openjdk-8-alpine
export http_proxy=http://maven.xxx.co.kr:80
apk update && apk upgrade
apk add nginx curl php5 php5-common php5-json php5-fpm php5-curl php5-mysql php5-cli php5-gd php5-openssl
  • cuckoo-admin-base 를 만들기 위한 Dockerfile

Dockerfile

FROM harbor.xxx.co.kr/java/openjdk-8-alpine:latest
LABEL maintainer=""
ENV http_proxy 'http://maven.xxxx.co.kr:80'
RUN apk update && apk upgrade
RUN apk add nginx curl php5 php5-common php5-json php5-fpm php5-curl php5-mysql php5-cli php5-gd php5-openssl
ENV http_proxy ''
RUN rm -rf /var/cache/apk/*
  • docker build -t cuckoo-admin-base .
  • docker tag cuckoo-admin-base harbor.xxx.co.kr/cuckoo/cuckoo-admin-base:0.0.2
  • docker login --username '유저네임' --password '패스워드' harbor.xxx.co.kr
  • docker push harbor.xxx.co.kr/xxx/xxx-admin-base:0.0.2
# docker 컨테이너 접속
docker ps
docker exec -it 컨테이너ID /bin/sh



# nginx 실행 테스트
mkdir -p /run/nginx
nginx

Git 소스 추가 작업

application.yml

application:
 name: xxx-web-cms
 mode: live
 version: 1.0.1


---
application:
 name: xxx-web-cms-dev
 mode: develop
 version: 1.0.1

Dockerfile-DEV

FROM harbor.xxx.co.kr/xxx/xxx-admin-base:0.0.2
LABEL maintainer=""


# cms
RUN mkdir -p /xxx/log/cms
RUN mkdir -p /xxx/service/cms/htdocs
COPY ./htdocs /xxx/service/cms/htdocs


# phplibs
COPY ./phplibs /xxx/service/phplibs
COPY ./phplibs/DBConfig.class.php.dev /xxx/service/phplibs/DBConfig.class.php


# nginx
RUN mkdir -p /run/nginx
RUN mkdir -p /log/nginx
COPY ./nginx/conf/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/conf/ssl/xxx.xxx.net.crt /etc/nginx/xxx.xxx.net.crt
COPY ./nginx/conf/ssl/xxx.xxx.net.key /etc/nginx/xxx.xxx.net.key
COPY ./nginx/conf/ssl/xxx.xxx.net.pw /etc/nginx/xxx.xxx.net.pw


#forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log


#php short_open_tag=On
COPY ./php/etc/php5/php.ini /etc/php5/php.ini


# php-fpm
RUN mkdir -p /xxx/php/var/run
RUN mkdir -p /usr/var/log
COPY ./php/etc/php-fpm.conf /etc/php5/php-fpm.conf


RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime


EXPOSE 80 443


COPY ./run.sh /home/run.sh
RUN ["chmod", "+x", "/home/run.sh"]
ENTRYPOINT sh /home/run.sh && tail -f /dev/null

run.sh

#!/bin/bash
/usr/bin/php-fpm5 -D; nginx

 

  • nginx.conf 및 ssl 인증서 파일 git에 복사
  • php 및 php-fpm 설정 git에 복사

Jenkins 설정

  • git 저장소에 ciadmin 계정 developer로 추가
  • Jenkins 어드민 계정으로 로그인
  • 새로운 Item : xxx-web-cms-dev 로 기존 프로젝트에서 복사로 셋팅 시작
    • Git > Repository URL 수정
    • Build > Invoke Gradle script 삭제
    • Build > Groovy script 수정
    • @Grab(group='org.yaml', module='snakeyaml', version='1.8')
      import org.yaml.snakeyaml.Yaml
      import org.codehaus.groovy.runtime.InvokerHelper


      public class Main extends Script {
       def argsValue(String defstr,String[] obj) {
       if(obj.length>0 && obj[0].length()==1)
       return obj.join();
       return defstr;
       }
       def run() {
       def mode=null;
       def version=null;
       def appname=null;
       def arg=argsValue("live",(String[])binding.getAt("args"));
       println "################################################################"
       println "# args: $arg"
       Yaml yaml = new Yaml();
       Object list=yaml.loadAll(new File("${build.workspace}/application.yml").newDataInputStream())
       for(Object obj : list) {
       def application= obj.application;
       if(application!=null)
       {
       if(application.version!=null)version=application.version;
       if(application.name!=null)appname=application.name;
       if(application.mode!=null)mode= application.mode;
       if(mode!=null && mode.equalsIgnoreCase(arg)) {
        
       File file = new File("${build.workspace}/docker_image_values");
       file.write "IMAGE_NAME=" +appname + "\n";
       file << "DOCKER_TAG=" +version;
       println "# application name: $appname"
       println "# application version: $version"
       println "# application mode: $mode"
       println "################################################################"
       break;
       }
       }
       }
       }
       public static void main(String [] args) {
       InvokerHelper.runScript(Main,args)
       }
      }

Rancher 설정

  • Add Stacks 에 Webs 추가
  • Add Service
    • Scheduling 탭에 Run all containers on a specific host 로 ck2-dev-xh1-api1 선택(backend 와 동일 서버이어야 하므로)
    • Networking 탭에 Network 를 Host로 수정

자동배포

  • Racher API Key 는 Racher API > Keys에서 확인 가능하며 운영자 계정 필요
  • Racher Enviroment Id는 http://rancher.skcomms.co.kr/env/1a2489539/apps/stacks 형태에서 env 뒤의 값
  • Auto Confirm 을 해주어야 Rancher에서 Finish Upgrade 까지 처리함

  • Jenkins > Execute Shell
    • 배포가 완료되면 팀룸을 통해 배포 알림
set +x
echo " > Sending commit message to TeamRoom.... "
CONTENT_STR="`git log --pretty=format:"■ Committer: %cn%n■ Note:%n%B%n" ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}..${GIT_COMMIT}`"
if [ "$CONTENT_STR" = "" ]
then
 echo " > Pass.(duplicated build)"
else
 curl -o /dev/null -X POST -H "Content-Type: application/x-www-form-urlencoded" --data-urlencode \
 "content=$CONTENT_STR" "https://teamroom.nate.com/api/webhook/6b2cd/fjdOEkmdHslMhQP6"
 echo " > Complete."
fi
set -x

참고

 

가장 빨리 만나는 Docker 3장 Docker 사용해보기

 

pyrasis.com

728x90
반응형

'프로그래밍 > Docker' 카테고리의 다른 글

Docker로 AWS ECR 배포  (0) 2022.03.10