docker
ความหมาย
Software container
คือ แนวคิดสร้างสภาพแวดล้อมเฉพาะให้ซอฟต์แวร์ทำงาน โดยไม่กระทบกับซอฟต์แวร์บนระบบปฏิบัติการ นักพัฒนาสามารถนำ container ไปประมวลผลบนเครื่องอื่น และซอฟต์แวร์ใน container ก็ยังทำงานได้ผลเหมือนเดิม ปัจจุบันมี Container registry หลายรายที่ให้บริการ อาทิ Amazon, Gitlab, Docker, JFrog, Google, Azure, Oracle, Redhat, UrbanCode, IBM, Quay, Alibaba, Harbar, Portus
Docker container
คือ การจำลองสภาพแวดล้อม ที่อาจใช้ image หลายตัวทำงานร่วมกัน เช่น container ที่มี apache และ php บน ubuntu
Docker registry
คือ แหล่งเก็บ image ของผลิตภัณฑ์ หรือที่ตัวเรา หรือที่สมาชิก docker เป็นผู้สร้าง โดย public registry ของ docker คือ hub.docker.com เมื่อสร้าง image ได้แล้ว ก็จะส่งไปเก็บไว้ใน registry ซึ่งในนั้นก็จะมี repositories ในแต่ละ repository ก็จะมี image ตัวเดียวกัน แต่ต่างรุ่น ที่แยกด้วย tag เช่น repository ชื่อ apache, php หรือ ubuntu (repository = กรุ/ที่เก็บ) ซึ่ง container ที่เราสั่ง commit จะถูกบันทึกไปเป็น image ให้พร้อมที่จะถูก push ขึ้นไปไว้ใน docker registry และแยกตาม repository เหมือนกับที่ github.com บริการเก็บ source code ในที่นี้สนใจ public registry ที่บริการโดย docker.com ที่มี repository เก็บ image ให้พร้อมถูก pull ไปใช้
Docker repository
คือ แหล่งรวบรวม images เดียวกัน แต่ต่างรุ่น แยกตาม tag การอ้างถึง repository อาจกำหนด [user name] หากเป็นของสมาชิกใน docker เช่น thaiall/helloapp:v1 โดย thaiall คือ user name ส่วน helloapp คือ image name และ v1 คือ tag
Commit
คือ การบันทึกการปรับปรุงใน container layers ไปเป็น image ตัวใหม่ เมื่อสั่ง commit แล้วก็จะได้ image ที่พร้อมสำหรับถูก push ขึ้นไปยัง Docker registry
Pull
คือ ดึง image จาก Docker registry มาไว้ในเครื่อง หรือ Download image นั่นเอง
Push
คือ ส่ง image จากในเครื่องของเรา ขึ้นเก็บใน Docker registry หรือ Upload image นั่นเอง
Virtual Machine คือ การจำลอง Environment ทั้ง OS มาเป็นเครื่องคอมพิวเตอร์เครื่องหนึ่งที่เรียกว่าเครื่อง Guest และพร้อมทำหน้าที่เครื่องคอมพิวเตอร์อีกเครื่องหนึ่ง โดยแบ่งทรัพยากรจาก Host มาให้กับ Guest ได้ทำงานเต็มที่
Prune คือ การชำระล้าง หากใช้ docker system prune ก็จะเป็นการชำระล้างสิ่งที่ไม่ใช้ในระบบ เช่น container ที่ exited ไปแล้ว
+ https://cloud.docker.com/u/thaiall/repository/list
+ medium.com ทำความรู้จัก Docker ของ Pattanapong Cherthong
+ linuxize.com/../how-to-remove-docker-images
+ mysql.com/../docker-mysql-getting-started.html
+ hostpacific.com/using-docker-on-centos7/
+ ascendcorp.com/docker-starter-342b61a1c915
+ aws.amazon.com/th/docker/
+ docker-containers-images-registries
+ https://medium.com/@somprasongd/
+ https://www.g2crowd.com/categories/container-registry
พาไปรู้จัก Hyper-V ก่อน Docker
+ บทความใน mindphp.com
1. Windows Hyper-V (ชื่อเดิม Windows Server Virtualization)
คือ ซอฟต์แวร์ประเภท VMware ทำหน้าที่สร้างเครื่องเสมือน หรือจำลองการทำงานของระบบปฏิบัติการขึ้น (Guest OS) บนระบบปฏิบัติการ (Host OS) จึงเรียก OS ตัวฐานว่า Host OS และตัวมาใหม่ที่ติดตั้งเพิ่มว่า Guest OS ทำให้มีได้หลาย OS บนเครื่องคอมพิวเตอร์ 1 เครื่อง ปัจจุบัน Windows Home ไม่มี Hyper-V มากับผลิตภัณฑ์นี้ ต้องเป็น Windows 10 Pro หรือ Ent จึงจะมี ดังนั้น Physical Hyper-V ของ Windows 10 Pro หรือ Ent จะทำหน้าที่ควบคุม CPU, RAM, Disk, VGA ของ Guest OS จึงทำงานร่วมกันได้ดีกับ Docker Desktop ที่ใช้บริการ Hyper-V
2. Virtual Box เป็นซอฟต์แวร์ประเภท VMware หรือ Virtualization เช่นกัน
แต่ไม่สามารถทำงานบน Windows 10 หาก Hyper-V mode is enabled หรือเปิดอยู่ จึงต้องสั่ง Disable Hyper-v ก่อนเปิดใช้งาน Virtual box เพราะจำเป็นต้องมี Hyper-V เพียง 1 เดียว ต้องเลือกว่าจะให้ Hyper-V ทำงานบน Windows หรือ Virtual box
+ เงื่อนไขการใช้ Virtualbox บน Windows 10
3. Docker คือ ซอฟต์แวร์ที่สามารถรองรับได้หลาย OS/Container บนโปรแกรม
แต่โปรแกรม Docker ไม่มี Hyper-V ในตัวเอง ดังนั้น Docker จึงไม่สามารถใช้งานบน Windows 10 Home เพราะไม่มี Physical Hyper-v ให้บริการ แต่ใช้งานได้บน Windows 10 Pro หรือ Ent และต้องเปิดบริการ Hyper-V ผ่าน Turn Windows features on or off หากเปิดบริการ Hyper-V จะมีผลให้ใช้งาน Virtual Box ไม่ได้ สภาพแวดล้อมของ Windows 10 Pro หรือ Ent จะบริการ Docker ได้สมบูรณ์ คือ สั่ง Docker ให้ทำงานได้ทั้งบน CMD และ Powershell
4. โปรแกรม Docker Toolbox เป็นซอฟต์แวร์ที่ใช้แทน Docker Desktop
หากพบปัญหาว่า do not meet minimal system requirements for the Docker Desktop โปรแกรม Docker Toolbox จะมี Virtualbox ติดตั้งมาพร้อมกัน จึงมีบริการ Hyper-V ไว้ใช้ ทำให้สามารถใช้งาน Docker toobox บน Windows 10 Home ได้ โดยจะเปิดบริการ Virtualbox โดยอัตโนมัติขณะที่โปรแกรม Docker Toolbox ทำงานอยู่ ดังนั้นบน Windows 10 Home จึงสามารถใช้ Virtualbox และ Docker Toolbox พร้อมกันได้
5. บน Host : Windows 10 Pro หรือ Ent ที่เปิดบริการ Hyper-V ทิ้งไว้
จะไม่สามารถเปิด Guest OS ใด ๆ ที่เคยเปิดได้บน Virtual Box ได้ ซึ่งสามารถตรวจสอบใน [Turn Windows features on or off] ว่า Hyper-V ถูก Enabled ไว้หรือไม่
Powershell in Admin mode (can not use DOS on CMD)
- Disable Hyper-V : bcdedit /set hypervisorlaunchtype off
- Enable Hyper-V : bcdedit /set hypervisorlaunchtype auto
ข้อความปัญหาที่พบ เมื่อเปิด Guest OS บน Virtual Box
คือ "ไม่สามารถเปิดเซสชันสำหรับเวอร์ชวลแมชชีน [android/macOS/Ubuntu]"
1. เปิด android พบ Raw-mode is unavailable courtesy of Hyper-V. (VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT).
2. เปิด Ubuntu พบ Raw-mode is unavailable courtesy of Hyper-V. Raw-mode is unavailable courtesy of Hyper-V. (VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT).
3. เปิด macOS Sierra พบ WHvCapabilityCodeHypervisorPresent is FALSE! Make sure you have enabled the 'Windows Hypervisor Platform' feature. (VERR_NEM_NOT_AVAILABLE). VT-x is not available (VERR_VMX_NO_VMX).
Docker toolbox บน windows 10 home
เล่าเรื่องการใช้งาน Docker toolbox บน windows 10 home ผ่าน command line ใน 4 บริการ
1. mingw64 ของ Docker toolbox
2. CMD ของ Win 10 home
3. Power shell ของ Win 10 home
4. WSL on ubuntu
เข้าผ่าน /mnt/c/program files/docker toolbox
แต่ต้องใช้ ./docker.exe ps หรือ images
การจัดการ image Docker image คือ ต้นแบบของ container ที่มีการติดตั้ง application และ configuration ให้พร้อมเริ่มทำงาน ซึ่งแฟ้มเหล่านี้อาจเกิดจากการ build Dockerfile จนได้ image แล้ว push image ขึ้นไปเก็บบน Docker registry ดังนั้น Docker registry คือ ที่จัดเก็บ image และแยกกันไปตาม repository และ tag หากเปรียบเทียบว่า image เป็น class ก็จะเทียบได้ว่า container เป็น instance ของ class
ตัวอย่างคำสั่งหน้าที่
$ docker images แสดงรายการ image ที่พร้อมให้เรียกใช้ พบ image id ที่จะนำไปใช้งานต่อได้ เช่น ใช้อ้างอิง เพื่อสั่งลบออกไปจาก docker
$ docker pull hello-world ดึง image จาก hub.docker.com ไปไว้ในเครื่อง
$ docker run hello-world สั่ง hello-world ทำงาน หากไม่เคย pull ก็จะ pull ก่อน
$ docker rmi [image id] ลบ image ตาม id ออกจาก docker
docker rmi $(docker images -q)
$ docker pull thaiall/helloapp:v1 ดึง image เมื่อทราบ [user name] / [image] : tag เมื่อ repository คือ [user name] / [image]
$ docker ps -a แสดงรายการ container / image ที่กำลังประมวลผลอยู่
docker rm $(docker ps -aq)
$ docker inspect [object] แสดง information ของ [object : image/container]
install
ตัวอย่างดีมากที่ https://coderwall.com/p/2es5jw/docker-cheat-sheet-with-examples

Docker for Windows Installer.exe
Docker Desktop 2.0.0.2
1. Install & Configuration
[/] Add shortcut to desktop
[/] Use Windows containers instead of Linux containers (this can be change after installation)
2. Finish & Logout & Login & Docker Desktop starting
3. Open Docker Desktop
Need to enable Hyper-V and Virtualbox will no longer work
4. Power shell (PS C:\Windows\system32>) หรือ CMD (C:\Users\ACER>)
DOS> docker help
DOS> docker -v
Docker version 18.09.1, build 4c52b90
DOS> docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
DOS> docker images 
ถ้าเคยสั่ง run และ pull hello-world มาแล้ว ก็จะแสดงรายการใน repository ไว้
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        3 weeks ago         1.84kB
DOS> docker info
5. เข้าไปดูใน https://hub.docker.com/
พบ https://hub.docker.com/_/hello-world
อ่าน https://docs.docker.com/get-started/
อ่าน https://examples.javacodegeeks.com/devops/docker/docker-hello-world-example/
6. DOS> docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
xxxxxx: Pull complete
Status: Downloaded newer image for hello-world:latest
7. work with hello-world
DOS> docker ps -a
DOS> docker images แสดงรายการ image ใน docker
DOS> docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
DOS> docker images hello-world แสดงรายการ image ที่มีใน docker 
8. แสดงรายการ container ที่เคยถูกสร้าง 
เช่น docker run hello-world หลายครั้ง ก็จะได้ Container ID ทุกครั้ง
docker จะไม่ remove container ให้อัตโนมัติ แม้จะ stop ไปแล้วก็ตาม
DOS> docker container ls --all
9. การลบ container ตาม id
DOS> docker container rm 1979c765c3b9
10. การแสดง process 
DOS> docker ps ที่กำลังทำงาน 
DOS> docker ps -a  ที่กำลังทำงานอยู่ และที่หยุดทำงานไปแล้ว
11. แสดงเฉพาะ container id
DOS> docker ps -aq
DOS> docker rm -f $(docker ps -aq) สั่งลบ container ใน docker ทั้งหมด ทำงานได้ใน PS-Admin แต่ไม่ทำงานใน CMD
12. จัดการ image
DOS> docker image rmi hello-world สั่งลบ image ออก
DOS> docker pull hello-world เปลี่ยน pull เป็น run ก็จะทำการ pull เช่นกัน

13. mysql
https://dev.mysql.com/doc/mysql-installation-excerpt/5.5/en/docker-mysql-getting-started.html
DOS> docker pull mysql/mysql-server หรือ  docker pull mysql/mysql-server ดาวน์โหลด
DOS> docker pull mysql
DOS> docker images แสดงรายการ image ที่ติดตั้งในระบบ
mysql                latest              477MB
mysql/mysql-server   latest              288MB
DOS> docker container ls -all จะยังไม่พบว่ามี container 
Starting a MySQL Server Instance
DOS> docker run --name mysql1 mysql/mysql-server
DOS> docker logs mysql1 พบ GENERATED ROOT PASSWORD:
DOS> docker logs mysql1 | findstr GENERATED
LINUX> docker logs mysql1 | grep GENERATED
DOS> docker exec -it mysql1 mysql -uroot -p
MYSQL> ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpassword';
MYSQL> show databases;
MYSQL> exit;
DOS> docker stop mysql1;
DOS> docker start mysql1;
DOS> docker container ls 
DOS> docker inspect test-mysql | findstr IPAddress
Linux> docker inspect test-mysql | grep IPAddress
"IPAddress": "172.17.0.4"
MySQL instance running in a container. 
https://severalnines.com/blog/mysql-docker-containers-understanding-basics
DOS> docker run --name mysql2 --publish 6603:3306 mysql/mysql-server
DOS> docker logs mysql1 | findstr GENERATED
DOS> docker exec -it mysql2 mysql -uroot -p
MYSQL> ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpassword';
DOS> docker exec -it mysql2 mysql -uroot -pnewpassword
DOS> docker inspect mysql2
DOS> ipconfig

14. busybox
DOS> docker pull busybox
DOS> docker run -itd --name=container1 busybox
cd8..c83
DOS> docker attach container1
# cd /bin
# ls -al
# ping 172.17.0.4 ok
# ping 172.17.0.14 no
# exit;
DOS> docker start/stop container1
DOS> docker run busybox:latest echo "hello world"
DOS> docker run busybox echo "hello world" ทำให้เกิด container id ขึ้นใหม่ แต่ exited ทันที
# docker run repository:tag command [arguments]
-i = interactive mode 
-t = pseudo-TTY
-d = detached mode หรือ background mode
foreground (default mode) 
DOS> docker run busybox sleep 60 (ctrl-c ได้)
DOS> docker run -d busybox sleep 60 
DOS> docker ps พ้น 60 วินาที process ก็จะหายไป
DOS> docker ps -a หรื อ docker container ls --all เห็น container id ทั้งหมด

15. Docker Image Layers
- debian
- git
- commit เก็บ container เป็น repository 
- docker commit container_id repository:tag เพื่อบันทึกเป็น repository ใหม่
- docker commit container_id burin/debian_git:1.0
- docker run --it burin/debian_git:1.0

16. ส่ง repository เข้า docker hub
DOS> docker login --username=thaiall
Login Succeeded
DOS> docker push burin/debian_git:1.0

17. my first repository
docker ps -a
docker container ls -a
docker rm -f $(docker ps -aq)
docker images
docker pull busybox
docker run -itd --name=busybox1 busybox
docker attach busybox1
http://www.thaiall.com/isinthai/index.php?q=shell_if
#vi one
read x
echo $x
if [ "$x" == "1" ]
then
echo "one"
elif [ "$x" == "2" ]
then
echo "two"
else
echo "-"
fi
#chmod 544 one เดิม 644
# ./one
#exit
MY_DOCKERHUB_NAME = thaiall
docker commit 3bc08df2e259 thaiall/busybox_one:1.0
docker login --username=thaiall
docker push thaiall/busybox_one:1.0
https://cloud.docker.com/u/thaiall/repository/list

18. docker system prune
WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all dangling images
        - all build cache
Are you sure you want to continue? [y/N]

19. เรียกใช้ script ที่สร้างขึ้น
docker run -itd --name=b1 thaiall/busybox_one:1.0
docker attach b1
/ # ./one
docker run -it --rm thaiall/busybox_one:1.0
docker run busybox:latest echo "hello world"
docker run thaiall/busybox_one:1.0 ls /bin
docker run -it --rm busybox
--rm คือ สร้าง container และลบทิ้งหลังใช้งานเสร็จ

docker run -it --rm thaiall/busybox_one:1.0
docker run -itd --name=btwo thaiall/busybox_one:1.0

docker exec -it 387fc116e058 ls

20. my fifth repository
ย้ายเข้า /bin และ #!/bin/sh
docker system prune
docker rm -f $(docker ps -aq)
docker run -itd --name=busybox1 thaiall/busybox_two:1.3
docker attach busybox1
http://www.thaiall.com/isinthai/index.php?q=shell_if
#mv one /bin
#mv two /bin
#mv three /bin
#exit
MY_DOCKERHUB_NAME = thaiall
docker container ls -a
docker commit 93c3bebe0f1b thaiall/busybox_two:1.4
docker login --username=thaiall
docker push thaiall/busybox_two:1.4
https://cloud.docker.com/u/thaiall/repository/list
https://devopscube.com/getting-started-with-docker-contianers/
docker run -itd --name=busybox3 thaiall/busybox_two:1.4
docker exec -it busybox3 three
https://github.com/moby/moby/issues/10668

22. สร้าง Docker Image ด้วยแฟ้ม Dockerfile
docker build . -t myname:mytag
DOS> docker build -t "burin/debian_git:1.0"
FROM debian:lastest
RUN apt-get update
RUN apt-get install -y git
RUN apt-get install -y vim

21. Docker file
[1]. hello
[2]. Dockerfile
mkdir myproject && cd myproject

echo #!/bin/sh> hello
echo df>> hello
DOS 21 bytes
PS 32 bytes

DOS + PS  : no
echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > Dockerfile

FROM busybox
COPY /hello /
RUN cat /hello

docker build -t helloapp:v6 .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM busybox
 ---> 3a093384ac30
Step 2/3 : COPY /hello /
 ---> 4243b0660961
Step 3/3 : RUN cat /hello
 ---> Running in 5f342c1558ba
h e l l o
 Removing intermediate container 5f342c1558ba
 ---> be52bcabb858
Successfully built be52bcabb858
Successfully tagged helloapp:v6
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

DOS> docker run helloapp:v6
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

docker run -itd --name=container3 helloapp:v6
docker attach container3

เมื่อสั่ง docker images จะพบ
REPOSITORY            TAG                 IMAGE ID            CREATED              SIZE
helloapp              v1                  be52bcabb858        About a minute ago   1.2MB

docker build -t foo -<<EOF
FROM busybox
RUN echo "hello world"
EOF
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
Docker Quickstart Terminal
$ pwd
/c/Program Files/Docker Toolbox
$ ls
boot2docker.iso  docker-compose.exe*  docker-quickstart-terminal.ico  kitematic/  unins000.dat
docker.exe*      docker-machine.exe*  installers/                     start.sh*   unins000.exe*
$ cd
$ pwd
/c/Users/ACER

1. Docker file
[1]. hello
[2]. Dockerfile

$ mkdir myproject && cd myproject
ใน linux mingw64 จะลบ ' ออกให้ แต่ใน dos จะมี ' ไปด้วย
echo '#!/bin/sh'>hello
echo 'df'>>hello
mingw64 13 bytes
DOS 19 bytes มี ' เพิ่มมา
PS 32 bytes ไม่มี ' แต่เป็น unicode

DOS + PS  : no
echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello">Dockerfile

Mingw64 : ok
echo -e 'FROM busybox\nCOPY /hello /\nRUN cat /hello'>Dockerfile
echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello">Dockerfile

FROM busybox
COPY /hello /
RUN cat /hello

docker build -t helloapp:v1 .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM busybox
latest: Pulling from library/busybox
 ---> 3a093384ac30: Pull complete
Step 2/3 : COPY /hello /
 ---> 4243b0660961
Step 3/3 : RUN cat /hello
 ---> Running in 5f342c1558ba
#!/bin/sh
df
 Removing intermediate container 5f342c1558ba
 ---> be52bcabb858
Successfully built be52bcabb858
Successfully tagged helloapp:v6
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. 
All files and directories added to build context will have '-rwxr-xr-x' permissions. 
It is recommended to double check and reset permissions for sensitive files and directories.

$ docker run -itd --name=container1 helloapp:v1
$ docker attach container1
/ # /hello หรือ ./hello ก็ได้
$ docker run helloapp:v1 /hello
ถ้าย้าย hello เข้าห้อง /bin ก็ไม่ต้องมี / เรียกใช้ hello ได้เลย
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

docker system prune
docker rm -f $(docker ps -aq)
$ docker run -itd --name=container1 helloapp:v1
$ docker attach container1 (ย้าย hello เข้า /bin)
docker ps -a 
docker commit 9a26931e8d37 thaiall/helloapp:v1 (1.2MB)
docker run thaiall/helloapp:v1 hello
docker login --username=thaiall
docker push thaiall/helloapp:v1
The push refers to repository [docker.io/thaiall/helloapp]
https://cloud.docker.com/u/thaiall/repository/list

docker system prune
docker rmi thaiall/helloapp:v1
docker pull thaiall/helloapp:v1
docker run thaiall/helloapp:v1 hello
Docker บน Ubuntu ใน Virtualbox
ubuntu-18.04.1-desktop-amd64
https://www.linux.com/blog/learn/intro-to-linux/how-install-docker-ce-your-desktop
$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
$ sudo apt-get update
$ apt-cache policy docker-ce
$ sudo apt install docker-ce
$ sudo systemctl status docker
$ sudo su
#docker run hello-world
#docker pull thaiall/helloapp:v1
#docker run thaiall/helloapp:v1 hello
Blog
เปิด Docker Quickstart Terminal ครั้งแรก
พอต่อ net ก็ดาวน์โหลด boot2docker.iso ขนาด 45 MB
จาก github.com/boot2docker รอนานมาก และไม่มี progress bar
แฟ้ม .iso จะถูกใช้กับ VirtualBox และ Mingw64
ด้วยความใจร้อนปิดหน้า download ไป 2 รอบ
รอบสามอดทนรอไปเรื่อย ๆ จึงดาวน์โหลดได้สำเร็จ
C:\Users\[computer name]\.docker\machine\cache
#เล่าสู่กันฟัง 62-023
https://web.facebook.com/search/str/62-023/keywords_search
php mysql apache บน Docker Toolbox in Win10Home
name$ pwd
/c/Program Files/Docker Toolbox
$ cd
$ pwd
/c/Users/ACER
$ mkdir website1 & cd website1
$ vi docker-compose.yml (or notepad)
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: myrootpassword
      MYSQL_DATABASE: mydb
      MYSQL_USER: myuser
      MYSQL_PASSWORD: myuserpassword
    ports:
      - "6603:3306"
  web:
    image: php:7.2.2-apache
    container_name: php_web
    depends_on:
      - db
    volumes:
      - ./php/:/var/www/html/
    ports:
      - "8080:80"
    stdin_open: true
    tty: true
$ mkdir php
$ cd php
$ echo "<?php phpinfo(); ?>">index.php
$ cat index.php
$ cd ..
$ docker-compose up -d (download images นานมาก)
$ docker-machine ip default
192.168.99.100
$ start http://$(docker-machine ip default):8080/index.php
$ start mysql://myuser:myuserpassword@$(docker-machine ip default):6603/mydb
$ cd php
$ echo $(date +"%m_%d_%Y")>>index.php
$ echo $(date +"%m_%d_%Y")>>test.php
$ start http://$(docker-machine ip default):8080/test.php
$ docker container ls -all |grep php
613c9d97bd93
$ docker exec -t -i 613c9d97bd93 /bin/bash
# ls index.php
$ docker images | grep mysql
$ docker ps -a |grep mysql
6aae0cda606e
$ docker exec -i 6aae0cda606e mysql -umyuser -pmyuserpassword  <<< "show databases;"
$ docker exec -i 6aae0cda606e mysql -uroot -pmyrootpassword  <<< "show databases;"

https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/docker-mysql-getting-started.html

docker exec -it 5f71c645b823 mysql -uroot -pmyrootpassword  
mysql>
create database mydb; 
use mydb;
create table a (a1 int, a2 char(20));
insert into a values (1, "abc");
insert into a values (2, "def");
select * from a;

$ cat my.php
echo "<?php" '$link' " = mysqli_connect('172.17.0.2', 'root', 'myrootpassword', 'myjoomla'); ?>" > x.php
echo "<?php" '$link' " = mysqli_connect('maria-db', 'root', 'myrootpassword', 'myjoomla'); ?>" > x.php
$link = mysqli_connect("172.18.0.2", "root", "myrootpassword", "myjoomla");
$link = mysqli_connect("172.17.0.2", "root", "myrootpassword", "myjoomla");

$conn = mysqli_connect("maria-db",  "root", "myrootpassword", "mydb");
$conn = mysqli_connect("192.168.99.100:6603",  "root", "myrootpassword", "mydb");
if (!$conn) { die(mysqli_connect_error()); } 
if ($result = mysqli_query($conn,"select * from a")) {
    while($row = mysqli_fetch_assoc($result)) {
        echo $row["a1"] . $row["a2"]. "<br/>";
    }
} 
mysqli_close($conn);

Fatal error: Uncaught Error: Class 'mysqli' not found in /var/www/html
$ docker container ls -all |grep php
613c9d97bd93
$ docker exec -t -i 613c9d97bd93 /bin/bash
# docker-php-ext-enable mysqli
# docker-php-ext-install mysqli
#exit
$ docker commit -p 613c9d97bd93 php:7.2.2-apache-mysqli
$ docker ps -a
$ docker stop [container-id]
$ docker rm -f $(docker ps -aq)
$ docker run --rm -p 8080:80 -d --name=php_web -v /c/Users/ACER/website1/php/:/var/www/html php:7.2.2-apache-mysqli
$ docker run -p 6603:3306 --name mysql573 -e MYSQL_ROOT_PASSWORD=myrootpassword -d mysql:5.7
https://alysivji.github.io/php-mysql-docker-containers.html
https://qiita.com/kazuma1989/items/e08e8475fc5126f2363f (Mingw64)
https://medium.com/@meeramarygeorge/create-php-mysql-.. (ติดตั้ง ubuntu ด้วย)
php mysql apache บน Docker in Win10 Pro
ติดตั้ง LAMP บน Docker
Docker บน Windows 10 pro
How to create a docker-based LAMP stack using docker-compose on Ubuntu 18.04 Bionic Beaver Linux
https://linuxconfig.org/how-to-create-a-docker-based-lamp-stack-using-docker-compose-on-ubuntu-18-04-bionic-beaver-linux
https://medium.com/@somprasongd/docker-compose-%E0%B8%84%E0%B8%B7%E0%B8%AD-fc8b35e0c8bc (ติดตั้ง wordpress)
1. สั่ง restart เพราะไม่ได้ run ทิ้งไว้
ต้องกระตุ้นให้ runing ขึ้นมา
2. เข้า Powershell ธรรมดาที่ไม่ใช่ admin บน Windows
สั่งผ่าน CMD DOS ด้วย powershell ก็ได้ จะพบ Home คือ c:\users\lab
3. mkdir -p website2/home

4. echo "<?php phpinfo(); ?>">website2/home/index.php
5. mkdir mariadb และ mkdir php-apache ใน website2
6. สร้างแฟ้มชื่อ Dockerfile ใน c:\users\lab\website2\php-apache ด้วย Notepad
FROM php:7.3.1-apache
MAINTAINER egidio docile
RUN docker-php-ext-install pdo pdo_mysql mysqli

7. สร้างแฟ้ม docker-compose.yml ใน website2 ด้วย notepad
ดูรุ่นที่ https://hub.docker.com/_/php/ หรือ https://hub.docker.com/_/mariadb/
version: '3'
services:
    php-apache:
        image: php:7.3.1-apache
        build:
            context: .
        ports:
            - 8080:80
        volumes:
            - /c/Users/acer/joomla:/var/www/htmltmp
        networks:
            - default
        links:
            - 'maria-db'
            
    maria-db:
        image: mariadb:10.4.1
        ports:
            - "6603:3306"        
        volumes:
            - /c/Users/acer/joomla/myjoomlasql:/docker-entrypoint-initdb.d
        environment:
            TZ: "Asia/Bangkok"
            MYSQL_ALLOW_EMPTY_PASSWORD: "no"
            MYSQL_ROOT_PASSWORD: "myrootpassword"
            MYSQL_USER: "myuser"
            MYSQL_PASSWORD: "myuserpassword"
            MYSQL_DATABASE: "myjoomla"
        networks:
            - default
----			
https://stackoverflow.com/questions/30740828/commit-data-in-a-mysql-container			
FROM mysql:latest
RUN cp -r /var/lib/mysql /var/lib/mysql-no-volume
CMD ["--datadir", "/var/lib/mysql-no-volume"]			
# But when you commit a container, each directory marked as VOLUME in the Dockerfile, is replaced with its original content.
# For instance, run date>/mydate inside the container and then commit it. When you then run a new container from that image, the file /mydate will still be there.
---
8. # docker-compose up
9. docker-machine ip default
192.168.99.100
10. docker run --rm -p 80:80 -d --name=php_web -v /c/Users/lab/website2/home/:/var/www/html php:7.3.1-apache
11. docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d mariadb:10.4.1
12. docker container ls -a พบว่า run อยู่
13. http://192.168.99.100 พบ phpinfo และ mysqli run อยู่
14. docker exec -it 0b00d5bb5a84 mysql  -uroot -p  ไม่ต้องใส่รหัสผ่าน หรือ myrootpassword
15. ใส่ข้อมูล และสร้างแฟ้ม my.php 
$conn = mysqli_connect("192.168.99.100:6603",  "root", "myrootpassword", "mydb");
if (!$conn) { die(mysqli_connect_error()); } 
if ($result = mysqli_query($conn,"select * from a")) {
    while($row = mysqli_fetch_assoc($result)) { echo $row["a1"]; }
} 
mysqli_close($conn);
16. docker system prune จะไม่ stop container ทั้ง 2
17. docker stop 0b00d5bb5a84  ทำให้หยุดได้ จึงเข้าจัดการฐานข้อมูลไม่ได้
18. จะใช้ก็สั่ง docker start 0b00d5bb5a84 แล้ว web ก็กลับมาทำงานได้เหมือนเดิม
นำ joomla เข้า docker ***
https://github.com/mybb/docker-compose/blob/master/docker-compose.yml.mariadb.example
https://docs.docker.com/network/links/
เคยลง image ทำ webserver บริการ php + mysql ไว้
d:/thaiall.com/joomla
[Dockerfile]
[docker-compose.yml]
--link [name or id]:alias
docker run -d -p 127.0.0.1:80:5000/udp training/webapp python app.py

[Hyper-v Manager]
docker-machine ip default (ไม่พบใน win 10 pro)
docker-machine ls (ไม่พบ default)
docker-machine create --driver hyperv vm (win 10 pro)
สร้าง virtual switch ตาม https://docs.docker.com/machine/drivers/hyper-v/
เปิด Hyper-v Manager
1. MAKE SURE HYPER-V IS ENABLED
2. SET UP A NEW EXTERNAL NETWORK SWITCH (OPTIONAL)
3. REBOOT
4. CREATE THE NODES WITH DOCKER MACHINE AND THE MICROSOFT HYPER-V DRIVER
PS admin> docker-machine create -d hyperv --hyperv-virtual-switch "Primary Virtual Switch" worker1
172.50.1.90
PS admin> docker-machine create -d hyperv --hyperv-virtual-switch "Primary Virtual Switch" default
PS admin> docker-machine ls (พบ worker1)
PS admin> docker-machine stop worker1
PS admin> docker-machine start default
===
0. clear
docker rm -f $(docker ps -aq)
docker rmi $(docker images -q) -f
===

1. สร้างแฟ้ม Dockerfile  ใน d:\thaiall.com\joomla
FROM php:7.3.1-apache
RUN apt-get update
RUN apt-get install -y vim
RUN docker-php-ext-install pdo pdo_mysql mysqli

#FROM mariadb:10.4.1
#COPY myjoomla.sql /docker-entrypoint-initdb.d/
#RUN cp -r /var/lib/mysql /var/lib/mysql-no-volume
#CMD ["--datadir", "/var/lib/mysql-no-volume"]

2. สร้างแฟ้ม docker-compose.yml ใน d:\thaiall.com\joomla
https://docs.docker.com/storage/volumes/
version: '3'
services:
    php-apache:
        image: php:7.3.1-apache
        build:
            context: .
        ports:
            - 8080:80
        volumes:
            - /c/Users/acer/joomla:/var/www/htmltmp
        networks:
            - default
        links:
            - 'maria-db'
            
    maria-db:
        image: mariadb:10.4.1
        ports:
            - "6603:3306"        
        volumes:
            - /c/Users/acer/joomla/myjoomlasql:/docker-entrypoint-initdb.d
        environment:
            TZ: "Asia/Bangkok"
            MYSQL_ALLOW_EMPTY_PASSWORD: "no"
            MYSQL_ROOT_PASSWORD: "myrootpassword"
            MYSQL_USER: "myuser"
            MYSQL_PASSWORD: "myuserpassword"
            MYSQL_DATABASE: "myjoomla"
        networks:
            - default
            

3. สร้าง container
3.1 docker pull hello-world
3.2 docker build . (ใน d:\thaiall.com\joomla)
--- รอ php
--- Dockerfile
3.3 docker-compose up (ถ้ามี container อยู่ ก็เพียงแต่ start container ถ้าไม่มีก็เพียงแต่สร้าง container)
--- รอ mariadb
--- docker-compose.yml
--- Dockerfile
3.4 docker ps

4. mariadb
docker inspect bbbc537a55df
docker exec -it bbbc537a55df  /bin/bash
ls /docker-entrypoint-initdb.d/dump.sql 

บน win 10 home
	docker exec -it bbbc537a55df  /usr/bin/mysql  -uroot -p (กำลังประมวลผล sql)
	docker exec -it bbbc537a55df  /usr/bin/mysql  -uroot -pmyrootpassword
	use myjoomla; show tables;

บน win 10 pro
	docker exec -it bbbc537a55df  /usr/bin/mysql  -uroot -pmyrootpassword
		show databases;		
		ไม่ต้องใช้คำสั่งนี้เลย source /docker-entrypoint-initdb.d/dump.sql;

5. stop & start		
Ctrl-C : docker-compose up
docker start bbbc537a55df (mariadb:10.4.1)
docker start 07c7fc66e429 (php:7.3.1-apache)
docker inspect 07c7fc66e429

6. backup dump.sql
docker exec -it bbbc537a55df /bin/bash
ls -al /docker-entrypoint-initdb.d/dump.sql 
cp /docker-entrypoint-initdb.d/dump.sql /home/dump.sql
 
7. php
docker start 07c7fc66e429
docker exec -it 07c7fc66e429 /bin/bash
	cd ../htmltmp
	cp -r * ../html
	echo "<?php if(!""session_start()){ echo 0; } else { echo 1;} phpinfo(); ?>">x1.php
	echo "<?php phpinfo(); ?>">x2.php
	//session.save_path
	cd libraries/joomla/session/handler/
	
8. ทดสอบ
http://192.168.99.100:8080/
http://localhost:8080/
Warning: session_start(): Failed to read session data: user (path: ) 
in /var/www/html/libraries/joomla/session/handler/native.php on line 260
Error: Failed to start application: Failed to start the session

docker exec -it 07c7fc66e429 /bin/bash
		// Ok to try and start the session
		#if (!session_start())
		#{
		#	throw new RuntimeException('Failed to start the session');
		#}
		
		if (session_start()) {} else
		{
			throw new RuntimeException('Failed to start the session');
		}
		
cp /var/www/htmltmp/libraries/joomla/session/handler/native-remark-260.php /var/www/html/libraries/joomla/session/handler/native.php
cp /var/www/htmltmp/libraries/joomla/session/handler/native.php /var/www/html/libraries/joomla/session/handler/native.php
	public $host = '192.168.99.100:6603';
	public $user = 'root';
	public $password = '';
	
	public $host = 'maria-db';
	public $user = 'root';
	public $password = 'myrootpassword';

$link = mysqli_connect("maria-db", "root", "myrootpassword", "myjoomla");
if (!$link) {
    echo "Error: Unable to connect to Database" . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
} else { echo "connect : ok"; }

=============
phpMyAdmin
cp -r * ../../html/phpMyAdmin
config.inc.php
cp /var/www/htmltmp/phpMyAdmin/config.inc.php /var/www/html/phpMyAdmin/config.inc.php
cp config.inc.php ../../html/phpMyAdmin
mkdir ../../html/phpMyAdmin/tmp
chmod 777 ../../html/phpMyAdmin/tmp
The $cfg['TempDir'] (./tmp/) is not accessible. phpMyAdmin is not able to cache templates and will be slow because of this.

พบปัญหา ฐานข้อมูล
Error: Failed to start application: Could not connect to MySQL server.
ยกเลิก readonly configuration.php เพื่อแก้ไขก่อน

	public $host = 'localhost:6603';
	public $user = 'root';
	public $password = 'myrootpassword';
	public $db = 'myjoomla';	
	
cp /var/www/htmltmp/configuration.php /var/www/html/configuration.php
Warning: mysqli_connect(): (HY000/1130): Host '172.17.0.1' is not allowed to connect to this MariaDB server

echo gethostbyname("maria-db");
$link = mysqli_connect("maria-db", "root", "myrootpassword", "myjoomla");
if (!$link) {
    echo "Error: Unable to connect to Database" . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
} else { echo "connect : ok"; }
echo "phpMyAdmin";
phpinfo();

cp /var/www/htmltmp/phpinfo.php /var/www/html/phpinfo.php
	
7. Commit php
docker commit 07c7fc66e429 thaiall/php:7.3.1-apache-myjoomla.1
docker run -p 8080:80 -d --name php_web1 thaiall/php:7.3.1-apache-myjoomla.1

docker login --username=thaiall
docker push thaiall/php:7.3.1-apache-myjoomla.1
* The push refers to repository [docker.io/thaiall/php]
https://cloud.docker.com/repository/registry-1.docker.io/thaiall/php/tags (135MB)

8. Commit mariadb
docker commit bbbc537a55df thaiall/mariadb:10.4.1-myjoomla.1
docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d thaiall/mariadb:10.4.1-myjoomla.1

docker login --username=thaiall (tenten)
docker push thaiall/mariadb:10.4.1-myjoomla.1
https://cloud.docker.com/repository/registry-1.docker.io/thaiall/mariadb/tags (116MB)
* The push refers to repository [docker.io/thaiall/mariadb]

9. run อีกเครื่องหนึ่ง
docker inspect 36ed57667a95 (mariadb) 172.17.0.3
docker exec -i -t 36ed57667a95 /bin/bash
docker exec -it 36ed57667a95  /usr/bin/mysql  -uroot -pmyrootpassword
		use myjoomla;
		show tables;		
		source /home/dump.sql;

docker inspect 253b66ef3f39  (php)
docker exec -i -t 253b66ef3f39 /bin/bash
phpMyAdmin
config.inc.php
$cfg['Servers'][$i]['host'] = '172.17.0.3'; // 127.0.0.1
joomla
configuration.php
public $host = '172.17.0.3'; // maria-db
vim libraries/joomla/session/handler/native.php start & next


$ docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d thaiall/mariadb:10.4.1-myjoomla.1
C:\Program Files\Docker Toolbox\docker.exe: Error response from daemon: cannot mount volume over existing file, file exists /mnt/sda1/var/lib/docker/overlay2/83b740a4c844ed2a5cf104cdb96ac679a7279ff7a22b361819f7a0b8fba88f7f/merged/mnt/myjoomla.sql.
See 'C:\Program Files\Docker Toolbox\docker.exe run --help'.

docker run -p 8080:80 -d --name=php_web1 thaiall/php:7.3.1-apache-myjoomla.1
docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d thaiall/mariadb:10.4.1-myjoomla.1
docker run -it -e MYSQL_ROOT_PASSWORD=example mysql:5.7 --datadir=/var/lib/mydata

หากปรับใช้ docker-compose build 
Pulling maria-db (mariadb:10.4.1)
Pulling php (php:7.3.1-apache)
maria-db_1    | 2019-02-17 15:21:37 0 [Note] Added new Master_info '' to hash table
			
4. docker images
พบ Repository : php  และ Tag : 7.3.1-apache มี Image id : xxxxxxx ขนาด 378MB

5. คำสั่ง docker run
https://rominirani.com/docker-on-windows-mounting-host-directories-d96f3f056a2c
c:\users\acer\joomla
docker run -v /c/Users/my-account:container-path
https://docs.docker.com/docker-for-windows/#/shared-drives

การ mount ไม่ใช่การ copy แต่เป็นการอ้างอิงไปแบบ soft link
docker run --rm -p 8080:80 -d --name=php_web php:7.3.1-apache
docker run --rm -p 8080:80 -d --name=php_web -v /c/Users/acer/joomla:/var/www/html php:7.3.1-apache
docker run --rm -p 8080:80 -d --name=php_web -v "./varwwwhtml":/var/www/html php:7.3.1-apache
docker run --rm -p 8080:80 -d --name=php_web -v "$PWD":/var/www/html php:7.3.1-apache
docker run -d -p 8080:80 --mount type=bind,source="$(pwd)",target=/var/www/html php:7.3.1-apache
docker run php:7.3.1-apache env
--rm คือ ลบ container ทิ้ง เมื่อทำงานเสร็จ

ทดสอบ 
ไม่ ok บน win 10 home เมื่อใช้ docker run --rm -v "/c/users":/data alpine ls
ไม่ ok บน win 10 home เมื่อใช้ docker run --rm -v "/c/Windows":/data alpine ls
ok บน win 10 home เมื่อใช้ docker run --rm -v "/c/Users":/data alpine ls
ok บน win 10 home เมื่อใช้ docker run --rm -v /c/Users:/data alpine ls
ok บน win 10 home เมื่อใช้ docker run --rm -v /c/Users/acer/joomla:/data alpine ls

6. docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d mariadb:10.4.1

7. docker rm -f $(docker ps -aq) สั่ง stop และ remove container ทั้งหมด

8. docker container list --all แสดงรายการทั้งหมดทั้งที่ exited และ running

9. chrome : http://192.168.99.100:8080 (Forbidden Apache/2.4.25 (Debian) Server at 192.168.99.100 Port 8080)
10. docker exec -it [container id] /bin/bash
docker exec -it 56afa68c75fc  /bin/bash
# cd /var/www/html
# ls
# ls >index.html

 docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d mariadb:10.4.1
 docker ps
 docker exec -it c137efe362a0 mysql  -uroot -pmyrootpassword (just enter)
show databases;
create database myjoomla;
use myjoomla;
SELECT host, user FROM mysql.user;
ALTER USER 'root'@'%' IDENTIFIED BY 'myrootpassword';
ALTER USER 'root'@'localhost' IDENTIFIED BY 'myrootpassword';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'  WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost'  WITH GRANT OPTION;

Warning: mysqli_connect(): (HY000/2002): Connection refused in /var/www/html/x.php on line 1

error in toolbox : docker exec -it ada917d84f58 mysql  -uroot -pmyrootpassword myjoomla < /d/myjoomla.sql
error in toolbox : winpty docker exec -it ada917d84f58 mysql  -uroot -pmyrootpassword myjoomla < /d/myjoomla.sql
error in ps(admin) : docker exec -it ada917d84f58 mysql  -uroot -pmyrootpassword myjoomla < d:\myjoomla.sql
error in dos : docker exec -it ada917d84f58 mysql  -uroot -pmyrootpassword myjoomla < d:\myjoomla.sql
error in toolbox : cat myjoomla.sql | docker exec -it ada917d84f58 mysql  -uroot -pmyrootpassword myjoomla 
ok : toolbox :  docker exec -i 2ae5c722d3ec /usr/bin/mysql  -uroot -pmyrootpassword myjoomla  < myjoomla.sql

c:\xampp\mysql\bin\mysql -u root -p testj < mydata.sql

SELECT 
sum(((data_length + index_length) / 1024 / 1024)) `Size in MB` 
FROM information_schema.TABLES 
ORDER BY (data_length + index_length);

SELECT 
     table_schema as `Database`, 
     table_name AS `Table`, 
     round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` 
FROM information_schema.TABLES 
ORDER BY (data_length + index_length) DESC;

11. Create docker image from container 
https://www.rapidtables.com/code/linux/mv.html
mkdir /var/www/myjoomla
cd /var/www/html
cp -Rf * /var/www/myjoomla
mv -f /var/www/myjoomla /var/www/html
----
16ff163f4ee2        php:7.3.1-apache-myjoomla.1 
6c22375e6541 		mariadb:10.4.1-myjoomla.1 
docker container ls -a
---
docker commit 16ff163f4ee2 thaiall/php:7.3.1-apache-myjoomla.2
docker login --username=thaiall
docker push thaiall/php:7.3.1-apache-myjoomla.2
* The push refers to repository [docker.io/thaiall/php]
https://cloud.docker.com/repository/registry-1.docker.io/thaiall/php/tags (135MB)
---
docker commit 6c22375e6541 thaiall/mariadb:10.4.1-myjoomla.2
docker login --username=thaiall
docker push thaiall/mariadb:10.4.1-myjoomla.2
https://cloud.docker.com/repository/registry-1.docker.io/thaiall/mariadb/tags (116MB)
* The push refers to repository [docker.io/thaiall/mariadb]
---
https://cloud.docker.com/u/thaiall/repository/list
https://devopscube.com/getting-started-with-docker-contianers/
docker run -itd --name=busybox3 thaiall/busybox_two:1.4
docker exec -it busybox3 three
https://github.com/moby/moby/issues/10668
mysql แบบ commit แล้วข้อมูลไม่หาย
https://stackoverflow.com/questions/30740828/commit-data-in-a-mysql-container
Dockerfile
FROM mysql:latest
RUN cp -r /var/lib/mysql /var/lib/mysql-no-volume
CMD ["--datadir", "/var/lib/mysql-no-volume"]

Build & run:
docker build . -t my-mysql
docker run -e MYSQL_ROOT_PASSWORD=root -it my-mysql

sudo docker run --name mysql-psat1 -e MYSQL_ROOT_PASSWORD=secret -d mysql:latest
docker run --rm -i -t -v /opt/Projets/P1/sqldumps:/mnt --link mysql-psat1:mysqlserver mysql:latest /bin/bash
> mysql --host $MYSQLSERVER_PORT_80_TCP_ADDR --port $MYSQLSERVER_PORT_80_TCP_PORT -uroot -psecret -e 'create database liferay_psat1;'
> mysql --host $MYSQLSERVER_PORT_80_TCP_ADDR --port $MYSQLSERVER_PORT_80_TCP_PORT -uroot -psecret liferay_psat1 < /mnt/liferay_sql_dump.sql

winpty docker run --volumes-from docker-mariadb-data -e MYSQL_ROOT_PASSWORD=user -p 3306:3306 -d mariadb

docker logs 34f8e5e53db5

docker-compose up --force-recreate

mysql>select @@datadir;
/var/lib/mysql

$sudo rsync -av /var/lib/mysql /mnt/volume-nyc1-01

$vi /etc/mysql/my.cnf
$vi /etc/mysql/mysql.conf.d/mysqld.cnf
datadir=/mnt/volume-nyc1-01/mysql

docker run -d \
  --volume /my/custom/conf.d:/etc/mysql/conf.d \
  mysql/mysql-server:5.7 \
    sh -c "
      echo '!includedir /etc/mysql/conf.d/' >> /etc/my.cnf

      mysqld
    "
Win 10 Home : thaiall/mariadb:10.4.1-myjoomla.1 และ thaiall/php:7.3.1-apache-myjoomla.1 เกือบสัปดาห์ ที่สร้าง image แล้ว push ขึ้น docker 2 ตัว คือ php กับ mariadb โดยมี database และ script เป็นของ joomla สลับกันทดสอบโดยใช้ docker toolbox บน Win 10 Home และ docker บน Win 10 Pro เป็น version 1 จึงยังมีหลายประเด็นที่ต้องปรับแบบ manual ก่อนที่ server จะทำงานได้ตามเป้าหมาย เห็นหน้าตาของ joomla ทำงานได้ปกติ พร้อม extension 2 ตัว คือ SP Easy Image Gallery และ SP Page Builder สิ่งสำคัญที่ต้องแก้ไข คือ การระบุ ip ของ database-container ให้ script-container รู้จัก
step 1 : pull & run Container ใน Win 10 home
	docker pull thaiall/mariadb:10.4.1-myjoomla.1
	docker pull thaiall/php:7.3.1-apache-myjoomla.1
	docker run -p 8080:80 -d  --link 6c22375e6541:maria-db --name phpx1 thaiall/php:7.3.1-apache-myjoomla.1
	docker run -p 192.168.99.100:8080:80 -d  --link 6c22375e6541:maria-db --name phpx1 thaiall/php:7.3.1-apache-myjoomla.1
	https://docs.docker.com/engine/reference/run/
	docker run -p 6603:3306 --name mariadb1 -e MYSQL_ROOT_PASSWORD=myrootpassword -d thaiall/mariadb:10.4.1-myjoomla.1
	สั่ง run ซ้ำได้ แต่ต้องเปลี่ยน --name
Step 2 : ตรวจ IP Address ของ Mariadb บน Docker			 
	docker ps
	docker inspect be0359e13029 |findstr IPAddress		
	docker inspect mariadb1 |findstr IPAddress
	พบ "IPAddress": "172.17.0.3"	
Step 3 : เปลี่ยน IP ของ Mariadb ที่ทำหน้าที่เป็น database
	docker exec -it 6c22375e6541 /bin/bash	
	chmod 777 /var/www/html/configuration.php
	vi /var/www/html/configuration.php
	เดิม public $host = 'maria-db' ;
	ใหม่ public $host = '172.17.0.3' ;
Step 4 : แก้ปัญหาใน Mariadb	
	docker ps
	รอเข้า mariadb จนกว่าระบบ จะสร้างรหัสผ่าน และฐานข้อมูลให้ อย่ารีบเข้าไป แบบไม่ใช้รหัสผ่าน
	รอรอบนี้ 12 นาที
	docker exec -it be0359e13029  /usr/bin/mysql  -uroot -pmyrootpassword
		SELECT host, user FROM mysql.user;			
		use myjoomla;
		show tables;
		source /home/dump.sql;
	รอไปอีก 15 นาที	
	RAM 4 GB , CPU Intel Core i3 , Win 10 Home + Vbox Ram : 1 GB
Step 5 : เริ่มต้นใช้งาน Container ที่เชื่อมกัน
	http://192.168.99.100:8080
Step 6 : แก้ URL Rewriting ใน administrator
	ok : http://192.168.99.100:8080/ (user:admin password:admin)
	ok : http://192.168.99.100:8080/index.php/9-toyota/4-car-toyota-3
	problem : http://192.168.99.100:8080/9-toyota/4-car-toyota-3	
	open : http://192.168.99.100:8080/administrator (user:admin password:admin)
		Menu bar , System, Global Configuration , Use URL Rewriting (Yes => No), Save & Close
		มีผลให้ link ต่าง ๆ มี index.php แทรกเพิ่มเข้าไป ไม่ต้องเพิ่มเอง
	ทำให้ลิงค์ใน website ต่าง ๆ ใช้งานได้
Step 7 : ปรับ config เพื่อใช้จัดการ Database
	vi /var/www/html/phpMyAdmin/config.inc.php
	กำหนด ip ให้กับ host
	$cfg['Servers'][$i]['host'] = '172.17.0.3';
	http://192.168.99.100:8080/phpMyAdmin
Step 8 :
	Host = maria-db	
=========
เก็บไว้เล่า	
ถ้า stop แล้ว start ใหม่
	ปัญหาอยู่ที่ session ของ Joomla ทำงานกับ Database
		ต้องแก้ไข 620 ใหม่ เพิ่ม #
		Mariadb เมื่อ restart ccontainer ตัวเดิมอาจได้ IP ใหม่ คือ 172.17.0.3 ก็ต้องตามไปแก้ไข Host
		ต้องแก้ไข 620 ใหม่ ลบ #
		แก้ไขด้วยการ
		เพิ่ม if (session_status() == PHP_SESSION_NONE) { session_start(); }
		ก่อนตรวจสอบด้วย if (!session_start())
	
		# Warning: session_start(): Failed to read session data: user (path: ) 
		# in /var/www/html/libraries/joomla/session/handler/native.php on line 260
		# Error: Failed to start application: Failed to start the session
		vim /var/www/html/libraries/joomla/session/handler/native.php
		ใส่ # ให้ทุกบรรทัดตั้งแต่บรรทัดที่ 260
		#if (!session_start())
		#{
		#	throw new RuntimeException('Failed to start the session');
		#}
		
	Check ip in container 
		awk 'END{print $1}' /etc/hosts
		awk 'END{print $2}' /etc/hosts (Container ID)
		hostname -i
		hostname (Container ID)

	ps> notepad c:\Windows\System32\Drivers\etc\hosts
	172.17.0.3 maria-db
	
	IP of Maria-DB
		docker inspect -f '{{ .NetworkSettings.IPAddress }}' 6c22375e6541
		docker exec 6c22375e6541 cat /etc/hosts
		
================================================	
	
thaiall/mariadb:10.4.1-myjoomla.beta
	docker run -p 6603:3306 --name mariadb -e MYSQL_ROOT_PASSWORD=myrootpassword -d thaiall/mariadb:10.4.1-myjoomla.beta
		Error response from daemon: cannot mount volume over existing file, 
		file exists /mnt/sda1/var/lib/docker/overlay2/.../merged/docker-entrypoint-initdb.d/dump.sql.

phpMyAdmin
	The $cfg['TempDir'] (./tmp/) is not accessible. phpMyAdmin is not able to cache templates and will be slow because of this.
	phpmyadmin/libraries/vendor_config.php
	define('TEMP_DIR', './tmp/');
	ls /var/www/html/phpmyadmin/tmp/ -al
	chmod 777 phpMyAdmin/tmp

[appendix]
มีภาพ สวยมาก --- https://severalnines.com/blog/mysql-docker-containers-understanding-basics
มี stack --- https://severalnines.com/blog/mysql-docker-composing-stack
mysql -uroot -pmypassword -h127.0.0.1 -P6603 -e 'show global variables like "max_connections"';
#docker exec 001f3028c351 sh -c 'exec mysqldump --all-databases -uroot -p"myrootpassword"' > /some/path/on/your/host/all-databases.sql

[Docker Port Mapping]
https://medium.com/@rachatatongpagdee/docker-%E0%B8%84%E0%B8%B7%E0%B8%AD%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3-%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%87%E0%B8%B2%E0%B8%99%E0%B8%AD%E0%B8%A2%E0%B9%88%E0%B8%B2%E0%B8%87%E0%B9%84%E0%B8%A3-7e77145967b6
192.168.99.100 is default ip on Docker toolbox or Docker machine which run docker on a linux vm
echo $(docker-machine ip) จะได้ 192.168.99.100 บน Docker toolbox
route /P add 172.16.0.0 MASK 255.240.0.0 10.0.75.2
docker logs 68c8
docker network create -d bridge --subnet 192.168.43.0/16 --gateway=192.168.43.1  mywifi
--network mywifi --ip 192.168.43.108
docker network ls
docker network inspect bridge
Win 10 Pro : thaiall/mariadb:10.4.1-myjoomla.1 และ thaiall/php:7.3.1-apache-myjoomla.1
step 1 : Survey
	docker container list --all
	// docker stop [container name]
	// docker rm [container name]
step 2 : Pull & run Container : Win 10 pro
	docker pull thaiall/mariadb:10.4.1-myjoomla.1
	docker pull thaiall/php:7.3.1-apache-myjoomla.1
	docker run -p 6603:3306 --name mariadb2 -e MYSQL_ROOT_PASSWORD=myrootpassword -d thaiall/mariadb:10.4.1-myjoomla.1
	docker run -p 8081:80 -d --link mariadb2:maria-db --name phpx1 thaiall/php:7.3.1-apache-myjoomla.1
	docker run -p 8082:80 -d --link mariadb2:maria-db --name phpx2 thaiall/php:7.3.1-apache-myjoomla.2
Step 3 : Dump database in Mariadb
	wait 3 minutes
	docker exec -it mariadb2  /usr/bin/mysql  -uroot -pmyrootpassword
		SELECT host, user FROM mysql.user;
		// % | root		
		// % | myuser (p : myuserpassword)
		use myjoomla;
		show tables;
		source /home/dump.sql;		
Step 4 : Start browser
	4.1 http://172.50.1.176:8081
	4.2 http://localhost:8081
	4.3 http://localhost:8081/phpMyAdmin
	4.4 http://127.0.0.1:8081/phpMyAdmin
	4.5 http://127.0.0.1:8082/index.php/9-toyota/4-car-toyota-3
Step 5 : Error testing for [Use URL Rewriting = Yes] in version 1
	http://172.50.1.176:8081/9-toyota/4-car-toyota-3	
Screen