관리 메뉴

코딩하는 락커

섹션 8: 더 복잡한 설정: Laravel & PHP 도커화 프로젝트 본문

🐳 도커와 쿠버네티스

섹션 8: 더 복잡한 설정: Laravel & PHP 도커화 프로젝트

락꿈사 2022. 8. 15. 18:45

Target 설정

  • 3개의 애플리케이션 컨테이너로 구성됨
    1. 첫번째 컨테이너 - PHP 인터프리터 컨테이너
      • Laravel PHP 애플리케이션의 소스 코드가 포함된 폴더가 호스트 컴퓨터에 존재함
      • 소스 코드 폴더는 PHP 인터프리터 컨테이너라는 하나의 컨테이너에 노출됨
      • 이 컨테이너는 소스 코드에 접근할 수 있으며 내부에는 PHP가 설치되어 있음 (즉, 소스 코드를 해석하고 들어오는 요청에 대한 응답을 생성할 수 있음)
    2. 두번째 컨테이너 - Nginx 웹서버 컨테이너
      • Nginx 웹 서버가 들어가 있음
      • 이 컨테이너와 웹 서버는 들어오는 요청을 받은 다음 PHP 인터프리터로 이동해서 PHP 인터프리터가 생성한 응답을 요청을 전송한 클라이언트에게 돌려줌
    3. 세번째 컨테이너 - MySQL 데이터베이스
      • MySQL 데이터베이스가 들어가 있음
      • PHP 인터프리터와 통신하여 데이터를 저장함 (즉, PHP 코드 묶음인 Laravel 프레임워크와 통신함)
  • 유틸리티 컨테이너
    1. 첫번째 유틸리티 컨테이너 - Composer
      • Node의 npm 과 같은 것
      • 써드파티 패키지를 설치하는데 사용하는 패키지 관리자
      • Composer를 사용하여 Laravel 애플리케이션을 만들고 필요한 종속성을 설치함
    2. 두번째 유틸리티 컨테이너 Laravel Artisan
      • 데이터베이스에 대해 마이그레이션을 실행하고 초기 시작 데이터를 데이터베이스에 씀
    3. 세번째 유틸리티 컨테이너 - npm
      • 프론트엔드 로직의 일부에서 사용 (Laravel이 반환하는 뷰에서 JavaScript 코드가 필요한 경우)

 

 

Nginx(웹 서버) 컨테이너 추가

  • 서로 상호작용하는 다중 컨테이너를 만들기 위하여 도커 컴포즈 사용
  • docker-compose.yml 작성
    • Nginx 부분 작성
# 도커 컴포즈 버전 설정
version: '3.8'

# 컨테이너 작성
services:
  # nginx 서버 컨테이너
  # 들어오는 요청을 받아들여 php 인터프리터를 트리거함
  # nginx 공식 이미지 사용(stable-alpine: 슬림한 Linus 운영 체제 레이어를 기반으로 하는 이미지)
  # 이미지의 80 포트를 노출하여 호스트 컴퓨터의 8000 포트에 바인딩
  # 로컬 컴퓨터에 있는 nignx/nignx.conf 파일과 
  # 컨테이너의 /etc/nginx/nginx.conf 파일과 바인드 마운드
  # ro 설정을 하여 컨테이너의 권한을 read only로 지정
  server:
    image: 'nginx:stable-alpine'
    ports:
      - '8000:80'
    volumes:
      - ./nginx/nignx.conf:/etc/nginx/nginx.conf:ro


  # php 컨테이너
  # php 코드와 Laravel 코드를 실행함
  php:

  # mysql 컨테이너
  # mysql 서버를 실행함
  mysql:

  # 유틸리티 컨테이너들
  composer:
  artisan:
  npm:
  • nginx/nginx.conf 생성
    • liten 80: nginx가 포트 80에서 수신대기
    • index index.php index.html: index 파일에 대한 요청 처리
    • root /var/www/html/public: 들어오는 요청에 응답하는데 사용할 수 있는 파일을 /var/www/html/public 디렉토리에서 찾음
    • location / { try_files $uri $uri/ /index.php?$query_string; }: 모든 수신 요청을 기본적으로 index.php 파일로 리디렉션하거나
    • location ~ \.php$ { ~ } : php 파일을 대상으로 하는 요청이 php 인터프리터로 전달되도록 함
server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/html/public;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:3000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

 

 

PHP 컨테이너 추가

  • docker-compose.yml 작성
    • PHP 부분 작성
    • 커스텀 Dockefile을 사용
version: '3.8'

services:
  server:
    image: 'nginx:stable-alpine'
    ports:
      - '8000:80'
    volumes:
      - ./nginx/nignx.conf:/etc/nginx/nginx.conf:ro


  # php 인터프리터 컨테이너
  # php 코드와 Laravel 코드를 실행함
  # php.dockefile을 사용하여 빌드 구성 설정
  # 로컬 컴퓨터의 프로젝트 폴더에 있는 소스 코드 폴더 src 파일과
  # 컨테이너의 /var/www/html 폴더와 바인드 마운트
  # delegated 설정을 하여 결과를 호스트 컴퓨터에 즉시 반영하지 않고 batch를 기본으로 설정하여 성능을 향상시킴
  php:
    build:
      # 해당하는 도커 파일을 찾을 수 있는 경로 작성
      context: ./dockerfiles 
      # php 도커 파일명 작성
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html:delegated

  # mysql 컨테이너
  # mysql 서버를 실행함
  mysql:

  # 유틸리티 컨테이너들
  composer:
  artisan:
  npm:
  • php.dockerfile 작성
    • 도커허브의 php 공식 이미지를 기반으로 한 커스텀 이미지 생성
# CMD, ENTRYPOINT 명령어가 없으므로 
# 베이스 이미지인 PHP 베이스 이미지의 디폴트 명령어 실행됨
# PHP 베이스 이미지의 디폴트 명령어는 PHP 인터프리터를 호출하는 명령임
# 즉, 해석되어야 하는 PHP 파일이 들어오면 아래 명령어가 자동으로 처리됨

# 사용중인 Nginx 구성을 위해서 php-fpm 이미지가 필요함
FPOM php:7-4-fpm-alpine

# 작업 디렉토리 설정
# /var/www/html: 웹 사이트를 제공하는 웹 서버의 표준적인 폴더
# 모든 컨테이너에서 최종 애플리케이션을 보관해야 하는 폴더로 이 폴더를 사용함
# Laravel PHP 애플리케이션을 보관해야 하는 컨테이너의 내부 폴더가 됨
WORKDIR /var/www/html

# 필요한 부가 종속성을 설치함
# pdo와 pdo_mysql 확장 프로그램 설치
RUN docker-php-ext-install pdo pdo_mysql
  • nginx.conf 파일 수정
server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/html/public;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # 기존 코드
        # fastcgi_pass php:3000;
        # Nginx 컨테이너와 php 컨테이너가 바로 통신을 하게 하기 위해 포트 번호 수정
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

 

 

MySQL 컨테이너 추가

  • docker-compose.yml 작성
    • MySQL 부분 작성
    • .env 파일을 사용
version: '3.8'

services:
  server:
    image: 'nginx:stable-alpine'
    ports:
      - '8000:80'
    volumes:
      - ./nginx/nignx.conf:/etc/nginx/nginx.conf:ro

  php:
    build:
      context: ./dockerfiles 
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html:delegated

  # mysql 컨테이너
  # mysql 서버를 실행함
  # mysql 공식 이미지 사용
  mysql: 
    image: mysql:5.7
    # 사용자, 비밀번호 등 설정 정보
    # env/.env파일에서 읽어옴
    env_file:
      - ./env/mysql.env

  # 유틸리티 컨테이너들
  composer:
  artisan:
  npm:
  • env/.env 파일 작성
MYSQL_DATABASE=homestead
MYSQL_USER=homestead
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=secret

 

 

Composer 유틸리티 컨테이너 추가

  • docker-compose.yml 작성
    • composer 유틸리티 컨테이너 부분 작성
version: '3.8'

services:
  server:
    image: 'nginx:stable-alpine'
    ports:
      - '8000:80'
    volumes:
      - ./nginx/nignx.conf:/etc/nginx/nginx.conf:ro

  php:
    build:
      context: ./dockerfiles 
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html:delegated

  mysql: 
    image: mysql:5.7
    env_file:
      - ./env/mysql.env

  # 유틸리티 컨테이너들

  # composer 컨테이너
  # Laravel에 의해 내부적으로 사용됨
  # 처음 Laravel 애플리케이션을 설정하는데 사용할 수 있음
  # 커스텀 dockerfile 사용
  composer:
    build:
      # 해당하는 도커 파일을 찾을 수 있는 경로 작성
      context: ./dockerfiles
      # composer 도커 파일명 작성
      dockerfile: composer.dockerfile 
    # Laravel을 설치하고 Laravel 프로젝트를 설장한 뒤
    # 그것을 사용할 때 소스 폴더에서 수행하게 함
    # 즉, '/var/www/html' 폴더에서 사용할 수 있도록 설정
    # 따라서 소스 폴더를 src를 컨테이너 내부의 '/var/www/html' 폴더로 바인딩 함
    volumes:
    - ./src:/var/www/html

  artisan:
  npm:

 

Composer 유틸리티 컨테이너로 Laravel 앱 만들기

  • composer 컨테이너 실행
    • composer create-project --prefer-dist laravel/laravel: Laravel 인스톨러 실행 명령어
      • composer.dockerfile에 ENTRYPOINT에 이미 composer 실행파일이 있으므로 composer 명령어 제거
      • 따라서 composer create-project --prefer-dist laravel/laravel으로 composer가 한번만 들어감 (첫번째는 서비스명, 두번째는 실행파일명)
    • create-project: 실행파일에서 create-project 호출
    • . : 프로젝트가 생성될 폴더를 명령어 끝에 특정해줌
      • composer.dockefile 때문에 컨테이너 내부 폴더인 /var/www/html에서 모든 작업이 실행됨 
      • 또한 이 폴더는 Laravel 프로젝트가 생성되는 루트 폴더가 됨
$ docker-compose run --rm composer create-project --prefer-dist laravel/
laravel .

 

일부 Docker Compose 서비스만 구동하기

  • src/.env 코드 수정
    • Laravel에 의해 생성되어 Laravel에 대한 구성을 갖고 있음
    • MySQL DB에 연결하기 위한 연결 정보를 위에서 작성한 대로 수정
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

  • 실행
Comments