PHP 7.2 기반 서비스가 6종류 이상 있다. WordPress, Laravel, CodeIgniter, 쇼핑몰, 암호화폐 거래소, AI 연동 서비스. 서비스마다 Docker 이미지를 따로 만들면 관리가 불가능해지므로, 하나의 범용 이미지로 모든 서비스를 커버하기로 했다.
Table of contents
Open Table of contents
제약 조건
- PHP 7.2 고정: 레거시 서비스 호환. 업그레이드 불가한 의존성 존재
- 하나의 이미지: 서비스별 이미지 분리 금지. 빌드/배포 복잡도 제한
- 프로덕션 사용: 개발 전용 확장(xdebug 등)은 별도 이미지로 분리
확장 선정 기준
- 2개 이상 서비스에서 사용 → 무조건 포함
- 1개 서비스에서만 사용하지만 런타임 필수 → 포함
- 개발/디버깅 전용 → dev 이미지로 분리
- 이미지 크기 영향 → 100MB 이상 증가 시 재검토
최종 확장 목록
코어 빌트인 확장 (docker-php-ext-install)
RUN docker-php-ext-install \
bcmath exif gd gettext gmp intl \
mysqli pcntl pdo_mysql soap sockets xsl zip
| 확장 | 사용 서비스 |
|---|---|
| bcmath | 거래소 (정밀 연산), 쇼핑몰 (가격 계산) |
| gd | WordPress (이미지 처리), 쇼핑몰 (썸네일) |
| intl | Laravel (다국어), 거래소 (통화 포맷) |
| mysqli/pdo_mysql | 전체 (MariaDB 연동) |
| soap | 쇼핑몰 (PG결제, 배송 API) |
| zip | WordPress (플러그인), Laravel (파일 처리) |
PECL 확장
RUN pecl install \
igbinary msgpack lzf zstd \
redis amqp rdkafka stomp \
imagick mongodb apcu uuid ds yaml xlswriter \
decimal xdebug
직렬화/압축 (igbinary, msgpack, lzf, zstd)
Redis 세션 직렬화에 igbinary를 사용하면 PHP serialize 대비 메모리 30% 절약. msgpack은 API 통신용. lzf/zstd는 대용량 캐시 압축.
; Redis 세션 설정
session.save_handler = redis
session.serialize_handler = igbinary
redis.session.serializer = igbinary
redis.session.compression = zstd
메시징 (amqp, rdkafka, stomp)
| 확장 | 프로토콜 | 사용처 |
|---|---|---|
| amqp | AMQP 0-9-1 | 메시지 브로커 (큐 처리) |
| rdkafka | Kafka | 로그 수집 (일부 서비스) |
| stomp | STOMP | 메시지 브로커 (간단한 메시지) |
3개 다 넣는 것이 과하다고 생각할 수 있지만, 범용 이미지이므로 서비스별로 사용하는 프로토콜이 다르다.
데이터 처리 (ds, yaml, xlswriter, decimal)
- ds: PHP 배열 대체 자료구조. 거래소의 주문장(OrderBook) 처리에서 SplPriorityQueue 대비 성능 이점
- yaml: 설정 파일 파싱 (Docker 환경에서 YAML 설정 많음)
- xlswriter: 쇼핑몰 주문 내역 Excel 다운로드 (PhpSpreadsheet 대비 메모리 효율)
- decimal: 거래소 가격 계산. bcmath보다 직관적인 API
추가 DB 드라이버 (pdo_pgsql, sqlsrv)
RUN docker-php-ext-install pdo_pgsql pgsql
RUN pecl install sqlsrv pdo_sqlsrv
일부 레거시 서비스가 PostgreSQL과 MSSQL에 연결한다. MariaDB가 메인이지만 범용 이미지이므로 포함.
dev 이미지 분리
프로덕션 이미지에서 xdebug를 제외하고, 개발 전용 이미지에서만 활성화한다.
; php-development.ini (dev 이미지 전용)
opcache.enable = 0
display_errors = On
error_reporting = E_ALL
max_execution_time = 0
; xdebug
xdebug.mode = off ; 환경변수로 debug/trace/profile 전환
xdebug.client_host = host.docker.internal
xdebug.client_port = 9003
XDEBUG_MODE 환경변수로 런타임에 모드를 전환한다. 기본값 off로 성능 영향 없이 이미지에 포함 가능.
이미지 크기
| 단계 | 크기 |
|---|---|
| php:7.2-fpm (베이스) | ~400MB |
| + 코어 확장 | ~500MB |
| + PECL 확장 | ~650MB |
| + DB 드라이버 | ~700MB |
700MB는 큰 편이지만, 서비스별 이미지 6개(각 500MB)를 관리하는 것보다 효율적이다.
핵심 정리
범용 PHP Docker 이미지의 핵심은 “넣을 것을 고르는 것”이 아니라 “뺄 것을 고르는 것”이다. 기본적으로 모든 서비스가 필요로 하는 확장을 넣되, 개발 전용 도구(xdebug)와 프로덕션 이미지를 분리하는 것이 핵심이다. 레거시 PHP 7.2를 유지해야 하는 상황에서, 잘 구성된 범용 이미지 하나가 파편화된 이미지 여러 개보다 낫다.
참고 자료
- Docker Hub PHP Official Image — PHP 공식 Docker 이미지 문서
- docker-php-extension-installer — Docker PHP 확장 간편 설치 도구