Docker

Docker Compose로 PHP, Nginx, MySQL 개발환경 구성하기

helperwoo 2025. 3. 26. 16:49
반응형

목표

Docker compose를 사용하여 각각의 Nginx, PHP, MySQL 컨테이너를 실행하고, php 개발환경을 구성한다.

 

파일구성

docker-compose.yml

services:
  php:
    build: ./docker/php
    container_name: php
    ports:
      - "9000:9000"
    expose:
      - "9000"
    volumes:
      - {앱 경로}:/home/app

  mysql:
    image: mysql:8.0
    container_name: db
    restart: always
    environment:
      MYSQL_DATABASE: {DB}
      MYSQL_USER: {DB 유저}
      MYSQL_PASSWORD: {DB 유저 패스워드}
      MYSQL_ROOT_PASSWORD: {DB ROOT 패스워드}
    volumes:
      - ./docker/mysql/data:/var/lib/mysql:rw
      - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d
    ports:
      - "{DB 포트}:3306"

  nginx:
    build: ./docker/nginx
    container_name: nginx
    restart: always
    depends_on:
      - php
    volumes:
      - {앱 경로}:/home/app
      - ./docker/nginx/logs:/var/log/nginx
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "{HTTP 포트}:80"
      - "{HTTPS 포트}:443"

./docker/php/Dockerfile

FROM php:8.2.5-fpm

RUN apt-get update
RUN apt-get install -y curl

#install some base extensions
RUN apt-get install -y \
        zlib1g-dev \
        zip \
        libpng-dev \
        exiftool \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libicu-dev \
        libpq-dev \
        libxpm-dev \
        libvpx-dev \
        libzip-dev \
        mariadb-client \
        libxml2-dev \
        vim

RUN docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg
RUN docker-php-ext-install pdo_mysql exif gd bcmath zip

# Composer install
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer

WORKDIR /home/app

CMD ["php-fpm"]

./docker/nginx/default.conf

server {
    listen      80;
    server_name localhost;

    root "/home/app/public";
    index index.php index.html index.htm ;
    charset utf-8;

    location / {
        add_header 'Access-Control-Allow-Origin' "*";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header Access-Control-Allow-Headers "X-Requested-With, X-Prototype-Version, X-CSRF-Token, x-csrftoken, Origin, Accept, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization";
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log error;

    sendfile off;

    client_max_body_size 0;

    location ~ \.php$ {
        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;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }

    location ~ /\.ht {
        deny all;
    }
}
반응형