# [Docker] Laravel&php 도커화 프로젝트

# 타켓 설정

이번에는 PHP, MYSQL, Nginx 컨테이너로 구성된 웹앱을 도커로 구축하면서 복잡한 설정에서 도커를 이용해 이들을 어떻게 간단히 할 수 있는지 설명한다,.

## Nginx 컨테이너

우선 `docker-compose.yaml`을 만들어 두고 Nginx 부분은

```yaml
version: "3.8"

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

와 같이 작성한다. 도커허브에 있는 이미지를 사용하고, conf 파일은 읽기 전용으로 해놨다.

Nginx 설정이 여기서 크게 중요치는 않으나

```plaintext
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 컨테이너

php에 대한 도커파일을 `dockerfiles` 디렉토리에 넣고, 이름을 `php.dockerfile`이라 하자. (즉, `dockerfiles/php.dockerfile`)

`php.dockerfile`는

```dockerfile
FROM php:7.4-fpm-alpine

WORKDIR /var/www/html

RUN docker-php-ext-install pdo pdo_mysql
```

아래와 같이 해주었고,

그래서 이제 `docker-compose.yaml`에서 php부분을 작성해볼 차례인데

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

`dockerfiles` 디렉토리 내부에 있는 `php.dockerfile`이므로 빌드 부분은 위와 같이 적어줄 수 있겠고, `src`디렉토리를 `/var/www/html`로 마운트하도록 지정해준다.

여기서 `delegated`라는 것이 나오는데, 이건 성능 향상을 위해 쓰일 수 있는 것이다.

이건 컨테이너가 일부 데이터를 기록해야 하는 경우에 그 결과를 호스트 머신에 즉시 반영하는 게 아니라 배치로 기본 처리한다. 일종의 최적화 옵션으로 볼 수 있다.

그런데 위의 `nginx.conf` 파일에서 php가 3000번 포트를 쓰기를 기대하고 있는데 실제 php 이미지를 검색해보면 9000번 포트를 노출하고 있음을 찾을 수 있다. 그래서 9000번 포트를 3000번으로 매핑해주어야한다.

그래서

```yaml
  php:
    build:
      context: ./dockerfiles
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html:delegated
    ports:
      - "3000:9000"
```

이렇게 써주면 될 것 같지만, 사실 로컬호스트를 통해 통신하는 게 아니라 컨테이너끼리의 통신을 이루고자 하는 것이므로 `docker-compose.yaml`에 포트를 저렇게 기입해 둘 것이 아니라

`nginx.conf`에서

```plaintext
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:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}
```

포트를 9000번으로 수정해주는 것이 옳다.

## MySQL 컨테이너

MySQL의 경우 간단하다.

`/env/mysql.env`를 만들어주고 필요한 정보를 넣은 후

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

로 해주면 그만이다.

## Composer 유틸리티 컨테이너

`Laravel`환경 구축을 위해 Composer 유틸리티 컨테이너도 만들어 볼 것이다.

이것도 간단하게 `/dockerfiles/composer.dockerfile`에

```dockerfile
FROM composer:latest

WORKDIR /var/www/html

ENTRYPOINT [ "composer", "--ignore-platform-reqs" ]
```

이것들을 적어준 후

```yaml
  composer:
    build:
      context: ./dockerfiles
      dockerfile: composer.dockerfile
    volumes:
      - ./src:/var/www/html
```

로 유틸리티 컨테이너를 만들어줄 수 있다.
