Thursday, October 22, 2026

Docker php-apache 8.5.12

#create container 

docker compose up -d --build

or

docker compose build --no-cache

docker compose up -d

#remove container 

docker compose down -v

---------------------------------------

# start container 

docker compose start

#shutdown container 

docker compose stop

#Bash

docker exec -it php_web bash

>>>>NOTE

debug use                                         -d

update docker-compose.yml  need    up --build

show log on terminal                         up -d

remove image                                   use down -v

remove container                              use down

-----------------------------------------------------------------------------

#file1 Dockerfile

FROM php:8.5-apache


# system libs สำหรับ gd, zip, mbstring

RUN apt-get update && apt-get install -y --no-install-recommends \

        git \

        unzip \

        libzip-dev \

        libpng-dev \

        libjpeg-dev \

        libfreetype6-dev \

        libwebp-dev \

        libonig-dev \

        zlib1g-dev \

        freetds-dev \

    && rm -rf /var/lib/apt/lists/*


# PHP extensions (mbstring, zlib ต้องใช้ตาม composer.json)

# pdo_dblib => SQL Server ผ่าน FreeTDS (db_config.php ใช้ dbtype 'dblib')

RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \

    && docker-php-ext-install -j"$(nproc)" gd mbstring zip mysqli pdo pdo_mysql pdo_dblib


# SQL Server 2005 ตอบ PRELOGIN ว่า encryption=ON แต่ทำ TLS handshake ไม่ได้

# (FreeTDS/GnuTLS ต่อ TLS 1.2 ไม่สำเร็จ) จึงปิด encryption ไว้ที่ระดับ client

RUN printf '[global]\n    tds version = auto\n    encryption = off\n    connect timeout = 10\n    timeout = 10\n' > /etc/freetds/freetds.conf


RUN a2enmod rewrite


# Composer (copy จาก official image)

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer


ENV COMPOSER_ALLOW_SUPERUSER=1


WORKDIR /var/www/html


# ติดตั้ง dependencies ก่อน เพื่อใช้ cache ของ Docker layer

COPY composer.json composer.lock* /var/www/html/

RUN composer install --no-dev --optimize-autoloader --no-interaction --no-scripts


# ถ้าใช้ volume mount ./src ทับ /var/www/html vendor จะหาย

# จึงย้าย vendor ไปไว้นอก document root แล้วชี้ผ่าน autoload ใน index.php

RUN mkdir -p /opt/app && mv /var/www/html/vendor /opt/app/vendor \

    && mv /var/www/html/composer.json /opt/app/composer.json \

    && (mv /var/www/html/composer.lock /opt/app/composer.lock 2>/dev/null || true)

---------------------------------------------------------------------------------------------------

#file2 docker-compose.yml


services:

  web:

    build: .

    container_name: php_apache_web

    ports:

      - "${WEB_PORT}:80"

    volumes:

      - ./src:/var/www/html

      - ./composer.json:/opt/app/composer.json   # แก้ไขจากเครื่อง host ได้

    env_file:

      - .env

    depends_on:

      db:

        condition: service_healthy


  db:

    image: mysql:latest

    container_name: mysql

    restart: unless-stopped

    ports:

      - "${DB_PORT}:3306"

    environment:

      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}

      MYSQL_DATABASE: ${MYSQL_DATABASE}

      MYSQL_USER: ${MYSQL_USER}

      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

    volumes:

      - db_data:/var/lib/mysql

    healthcheck:

      test: ["CMD-SHELL", "mysqladmin ping -h localhost -p$$MYSQL_ROOT_PASSWORD"]

      interval: 5s

      timeout: 5s

      retries: 10


  phpmyadmin:

    image: phpmyadmin:latest

    container_name: phpmyadmin

    restart: unless-stopped

    ports:

      - "${PMA_PORT}:80"

    environment:

      PMA_HOST: db

      PMA_PORT: 3306

    depends_on:

      - db


volumes:

  db_data:


-------------------------------------------------------------------------
#file3 .env

# Web

WEB_PORT=80


# MySQL

MYSQL_ROOT_PASSWORD=rootpass

MYSQL_DATABASE=app_db

MYSQL_USER=app_user

MYSQL_PASSWORD=app_secret

DB_HOST=db

DB_PORT=3306


# phpMyAdmin

PMA_PORT=8080

---------------------------------------------------------------------------