본문 바로가기

InfoSec Log/Docker

[Docker] PHP, MySQL, phpMyAdmin Docker 배포 방법

Docker 실행 OS 환경: Kali Linux(Debian)

 

Docker 컨테이너 배포 순서

  1. 도커 설치
  2. docker-compose 설치
  3. docker-compose.yml & Dockerfile 작성
  4. docker-compose up --build  -d를 통해 컨테이너 설치 및 실행
  5. 애플리케이션 소스 코드를 호스트의 project_folder/html 디렉토리로 옮긴 후 8080포트를 통해 접속하여 정상적으로 실행이 되는지 확인

 

도커 설치

sudo apt update 

sudo apt install docker.io

 

docker-compose 설치

sudo apt install docker-compose

// 설치 확인
docker-compose --version 

 

docker-compose.yml & Dockerfile 작성

// 프로젝트 폴더 생성
mkdir ./project_folder

// 프로젝트 폴더로 이동
cd project_folder

// 애플리케이션 소스 코드와 바인드 마운트 시킬 폴더 생성
mkdir ./html

 


 

Docker를 통해 3개의 컨테이너를 배포하고 연결하기 위해, docker-compose.yml 파일을 통해 해당 설정들을 관리하고, Dockerfile을 통해 PHP에서 PDO 객체를 사용하여 MySQL과 통신이 가능하도록 확장 모듈을 설치한다. 

docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    container_name: php_web
    volumes:
      - ./html:/var/www/html
    ports:
      - "8080:80"
    environment:
      - DB_HOST=mysql_db
      - DB_NAME=community
      - DB_USER=user
      - DB_PASS=password
    networks:
      - app-network
    restart: always

  db:
    image: mysql:8.0
    container_name: mysql_db
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: community
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - app-network
    restart: always

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "8081:80"
    networks:
      - app-network
    restart: always

networks:
  app-network:
    driver: bridge

volumes:
  db_data:

 

설명

  • web 서비스는 PHP 컨테이너와 관련된 설정이다. 해당 컨테이너는 docker hub에서 바로 이미지를 가져오는 것이 아닌, build 옵션을 통해 같은 디렉토리 내에 존재하는 Dockerfile에 정의된 내용을 바탕으로 이미지를 다운로드 하도록 한다.
  • 호스트의 ./html 디렉토리와 해당 컨테이너의 /var/www/html 디렉토리를 바인드 마운트하여 호스트의 ./html 디렉토리 내 에서 수정한 내용이 즉시 반영되도록 한다. 따라서 웹앱의 소스코드의 경우 호스트의 ./html/ 경로에 위치 시키도록 한다. 만약 프로덕션 환경일 경우 db 서비스와 같이 직접 호스트의 특정 디렉토리와 바인드 마운트를 하는 것이 아닌, Docker에서 관리하는 volume을 사용하도록 한다. 
  • web 서비스는 호스트의 8080번 포트를 통해 Docker의 80번 포트(web)에 접속할 수 있도록 한다(포트포워딩).
  • MySQL과의 연결 설정에서 해당 정보를 하드 코딩하는 것이 아닌, 환경변수로 설정하기 위해 environment 옵션을 설정한다.
  • 만약 시스템이 재부팅 될 때 자동으로 실행하고 싶은 컨테이너에 대해 restart: always 옵션을 설정한다.
  • networks 옵션을 통해 3개의 컨테이너가 같은 네트워크 대역에 존재하도록 만들고 driver: bridge 를 통해 각 컨테이너가 격리된 환경에 존재하지만 같은 네트워크 대역에 존재하는 컨테이너끼리는 서로 통신할 수 있도록 만든다.
  • db 서비스의 경우 mysql 이미지가 빌드된 컨테이너이다.
  • db 서비스의 경우 바인드 마운트가 아닌 Docker에서 관리하는 Volume을 사용하여 데이터를 유지하도록 한다.
  • phpmyadmin은 GUI를 통해 DB를 관리할 수 있는 서비스로, PMA_HOST: db를 통해 db 서비스와 연결하도록 한다.
  • phpmyadmin의 경우 호스트의 8081 포트를 통해 Docker의 phpmyadmin 서비스에 접속할 수 있도록 만든다.
Dockerfile
FROM php:7.4-apache

RUN docker-php-ext-install pdo pdo_mysql

 


컨테이너 설치 및 실행

sudo docker-compose up --build -d

 

애플리케이션 배포 확인

 

http://localhost:8080을 브라우저 URL 주소 창에 입력하여 애플리케이션이 정상적으로 배포가 되었는지 확인한다.

만약 소스코드가 아직 project_folder/html/ 경로에 옮겨지지 못하였다면, echo “<?php phpinfo(); ?>” >  project_folder/html/index.php 을 통해 테스트 페이지 생성 후 정상적으로 해당 페이지가 출력이 되는지 확인한다.

 




번외

 

도커 컨테이너 내부에 접속 및 bash 쉘을 통해 명령어 제어

docker exec -it <container-name> /bin/bash

 

도커에서 현재 사용 중인 볼륨 목록

docker volume ls

 

특정 볼륨의 마운트 포인트 확인

docker volume inspect <volume-name>

 

도커 이미지 목록

docker images

 

도커 컨테이너 목록

// 실행 중인 컨테이너 목록
docker ps

// 모든 컨테이너 목록
docker ps -a