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

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


Wednesday, October 14, 2026

tinycore wsl

 https://github.com/zkedem/wsl-tcl-setup
follow this guide line

use usbipd attach --wsl tinycore -b 3-1


and addition

NEW wsl-tcl-setup

#!/bin/busybox ash


echo This script prepares Tiny Core to run on WSL.

. /etc/init.d/tc-functions

checkroot


echo Creating /etc/sysconfig/tcuser...

if [ ! -f /etc/sysconfig/tcuser ]; then

> /etc/sysconfig/tcuser

fi


echo Preparing home directory for default user...

if [ ! -d /home/tc ]; then

        mkdir -p /home/tc

fi


echo Preparing TCE directory...

if [ ! -d /etc/sysconfig/tcedir/optional ]; then

mkdir -p /etc/sysconfig/tcedir/optional

fi



# ย้ายของเดิมไปไว้ที่ถาวร

sudo rm /etc/sysconfig/tcedir/tce

sudo mkdir -p /home/tc/tce

sudo mv /etc/sysconfig/tcedir/optional /home/tc/tce/

sudo chown -R tc:staff /home/tc/tce

sudo rmdir /etc/sysconfig/tcedir


# สร้าง symlink สองชั้น

sudo mkdir -p /mnt/nfs

sudo ln -sfn /home/tc/tce /mnt/nfs/tce

sudo ln -s /mnt/nfs/tce /etc/sysconfig/tcedir

sudo rm -f /tmp/md5.db /tmp/md5.db.gz /tmp/upgrade_errors.lst


echo Patching tce-load for root privileges...

sed -i.bak -e "s.checknotroot.checkroot." /usr/bin/tce-load

sed -i.bak -e "s.checknotroot.checkroot." /usr/bin/tce-update


echo Done!


Bootlocal.sh

#!/bin/sh

# put other system startup commands here


DIR=/mnt/nfs/tce/optional

sudo rm -f /usr/local/tce.installed/*

for pkg in "$DIR"/*.tcz; do

    [ -e "$pkg" ] || { echo "No .tcz files in $DIR"; exit 1; }

    echo "Installing $pkg"

    tce-load -i "$pkg"

done


sudo modprobe ax88179_178a


sudo /opt/eth1.sh &


sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE &


sudo iptables -A FORWARD -i eth1 -j ACCEPT &


sudo dnsmasq &


sudo sysctl -w net.ipv4.ip_forward=1


Thursday, October 8, 2026

Alpine wsl

usbipd -b 2-1

usbipd attach -b 2-1 -w alpine


su-d

modprobe ax88179_178a

ip addr flush dev eth1

ip addr add 192.168.137.1/24 dev eth1

ip link set eth1 up


echo 1 > /proc/sys/net/ipv4/ip_forward


echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-forward.conf


apk add iptables

iptables -t nat -A POSTROUTING -s 192.168.137.0/24 -o eth0 -j MASQUERADE

iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT


apk add dnsmasq

cat > /etc/dnsmasq.conf <<'EOF'

interface=eth1

bind-interfaces

dhcp-range=192.168.137.10,192.168.137.100,255.255.255.0,12h

dhcp-option=option:router,192.168.137.1

dhcp-option=option:dns-server,192.168.137.1

server=1.1.1.1

EOF


rc-service dnsmasq start

rc-update add dnsmasq


dnsmasq --conf-file=/etc/dnsmasq.conf

Wednesday, October 7, 2026

Tunnel SSL connect vm to host

apk add openssh-client (openwrt linux)

ssh-keygen -t rsa -b 2048 -f id_rsa (windows , host)
upload to vm (openwrt) /roots/.ssh/id_rsa
paste id_rsa.pub in--> /.ssh/authorized_keys

ssh -i /root/.ssh/id_rsa -N -R 8080:localhost:80 prapop@192.168.0.86 (openwrt)

http://localhost:8080 (windows)

Cross compile busybox for openwrt from windows10 (wsl)

how to cross compile busybox 1.38.0 for openwrt 25.12.5 x86_64 from windows10
use toolchain x86_64-openwrt-linux-musl-

Setting up a cross-compile of BusyBox for OpenWrt from Windows.

Cross-compiling BusyBox 1.38.0 for OpenWrt x86_64 from Windows 10

The OpenWrt toolchain is a Linux (ELF) toolchain, so it can't run natively on Windows. The usual approach is to use WSL2 as the build host.

1. Install WSL2

In PowerShell (admin):

powershell
wsl --install -d Ubuntu

Reboot if asked, then open the Ubuntu shell. Work inside the Linux filesystem (~), not /mnt/c/.... Building on the Windows drive is slow and causes case-sensitivity and symlink problems.

2. Install build dependencies

bash
sudo apt update
sudo apt install -y build-essential libncurses-dev wget bzip2 zstd xz-utils file

3. Get the OpenWrt SDK (contains the x86_64-openwrt-linux-musl- toolchain)

Browse https://downloads.openwrt.org/releases/25.12.5/targets/x86/64/ and download the file named openwrt-sdk-25.12.5-x86-64_gcc-*_musl.Linux-x86_64.tar.zst. The gcc version in the name will vary, so check the directory listing.

bash
cd ~
wget https://downloads.openwrt.org/releases/25.12.5/targets/x86/64/<SDK-FILENAME>.tar.zst
tar --zstd -xf <SDK-FILENAME>.tar.zst   # or: zstd -d file | tar x

Find the toolchain and set up the environment:

bash
SDK=$(ls -d ~/openwrt-sdk-*/)
TC=$(ls -d $SDK/staging_dir/toolchain-*/)
export STAGING_DIR=$SDK/staging_dir
export PATH=$TC/bin:$PATH

x86_64-openwrt-linux-musl-gcc --version   # sanity check

The STAGING_DIR variable matters because the OpenWrt wrapper scripts need it, otherwise you'll see warnings or failures.

4. Get BusyBox 1.38.0

bash
cd ~
wget https://busybox.net/downloads/busybox-1.38.0.tar.bz2
tar xf busybox-1.38.0.tar.bz2
cd busybox-1.38.0

5. Configure

bash
make defconfig
make menuconfig

In menuconfig:

  • Settings → Build Options → Build static binary (no shared libs): enable (recommended; musl static builds work well and run anywhere).
  • Settings → Build Options → Cross compiler prefix: set to x86_64-openwrt-linux-musl- (optional, since you can also pass it on the command line).

6. Build

bash
make ARCH=x86_64 CROSS_COMPILE=x86_64-openwrt-linux-musl- -j$(nproc)

Verify the result:

bash
file busybox
# expect: ELF 64-bit LSB executable, x86-64, statically linked

If you want an install tree:

bash
make ARCH=x86_64 CROSS_COMPILE=x86_64-openwrt-linux-musl- CONFIG_PREFIX=$HOME/bb-install install

7. Copy it to Windows / the router

bash
cp busybox /mnt/c/Users/<you>/Desktop/

You can also browse to \\wsl$\Ubuntu\home\<you>\busybox-1.38.0 in Explorer. Then transfer to the device with scp, and run it with chmod +x busybox && ./busybox ls.

Troubleshooting

  • tc.c errors (CBQ undeclared): a known issue with newer kernel headers. Disable it with make menuconfig → Networking Utilities → uncheck tc.
  • Other failures on a specific applet: disable that applet in menuconfig. Newer musl and gcc are stricter than what BusyBox's defconfig was tested against.
  • command not found for the compiler: PATH or STAGING_DIR isn't exported in the current shell. Re-run the step 3 exports.
  • Mismatched filenames: I can't verify the exact SDK and gcc filenames for 25.12.5, so use the directory listing.

Note

OpenWrt already ships its own BusyBox, built from its package system. Don't overwrite /bin/busybox on a running router with yours, as that can break the system. Put it somewhere like /tmp or /opt, or use it as an additional binary. If you instead want a fully integrated build, use the OpenWrt buildroot (make menuconfig → Base system → busybox) rather than a standalone build.

chmod before use

Right, the executable bit matters here. Two places it comes up:

On the router (after copying)

Files copied from Windows, or through WSL's /mnt/c/... paths, don't keep a reliable execute permission, so set it on the target:

sh
chmod +x /tmp/busybox
/tmp/busybox ls

My earlier line chmod +x busybox && ./busybox ls covered this, but it's easy to miss. If you transfer with scp from WSL, run chmod on the device afterward, not before.

Inside WSL (before copying)

The built binary already has the execute bit in the Linux filesystem, so you can test it right there if you're on an x86_64 machine:

bash
chmod +x busybox
./busybox --help

Cr. Claude