iT邦幫忙

2023 iThome 鐵人賽

DAY 30
0
DevOps

嘿,稍等一下!別急著開發功能,先來打造 Walking Skeleton 吧!系列 第 30

【Walking Skeleton】Day30 - 使用 Docker 建立開發環境

  • 分享至 

  • xImage
  •  


圖片來源:Haufe Docker Style Guide

Image 和 Container

與其說 Image(映像檔)是 ISO 系統安裝檔或虛擬機快照,不如說 Image 更像是還沒執行的程式碼,跟程式不同的點是它是一個唯獨的檔案,而 Container(容器)是正在執行的程式

Image 可以從雲端儲存庫 pull 下來,或是用 Dockerfile build 出來,也可以從檔案 load 到本地儲存庫

Docker Hub 是一個最受歡迎的雲端儲存庫,我們可以在上面找到要用到的 Image

我們來下載 Nginx 的 Image,這樣就不用再把伺服器軟體安裝在系統上了

https://hub.docker.com/_/nginx

docker pull nginx

如果出現這坨字,表示沒把 Docker 運行起來,Docker 其實是個 Client-Server 架構,平常打指令的 CLI 只是 Client,還會需要一個 Server,也就是 Docker Daemon 才能運作

error during connect: this error may indicate that the docker daemon is not running: Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/images/json": open //./pipe/docker_engine: The system cannot find the file specified.

查看現在本地儲存庫有哪些 images

docker images

接著是讓它跑起來,變成 Container,-p 表示的是將內部的 80 port 映射到外部的 8001 port,也就是可以從外部的 8001 port 訪問到內部的 80 port

docker run -p 8001:80 nginx

如果想讓容器跑起來時進到裡面可以加上 -it 參數,如果想讓容器在背景執行可以加上 -d 參數

現在打開瀏覽器應該就可以看到 Nginx 的預設頁面啦
http://localhost:8001/

Ctrl + C 可以終止容器運行,或是開另一個終端機用 docker stop {id or name} 來停止,要重新啟動的話就用 docker start {id or name}docker restart {id or name}

ps 可以查看運行中的容器,加上 -a 則是列出全部,包含運行結束的容器

docker ps -a

要從容器列表中移除容器的話,可以使用 docker rm {id or name}

要移除映像檔的話則是使用 docker rmi {id or name}

現在應該很了解容器怎麼用了吧


DockerFile

Image 有點太單調了我需要一點調味

DockerFile 就像是一個食譜一樣,使用基本的食材再加上一些調味料和擺盤,讓 Image 變得更豐盛美味

我們來把 Nginx 的預設首頁改掉,找個喜歡的資料夾建立以下檔案

html/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1 align="center">Hello, Docker!</h1>
</body>

</html>

在 nginx 這個基本映像檔上加上 COPY,將外部的 ./html 複製進去 /usr/share/nginx/html

Dockerfile

FROM nginx

COPY ./html /usr/share/nginx/html

在專案資料夾中使用 docker build,來把 Dockerfile(食譜)變成 Image(料理),加上 -t 可以為它取個名字

docker build -t mynginx .

現在 Image 列表中就能看到我們自己製作的 Image

docker images

把它運行起來看看

docker run -p 8002:80 mynginx

現在再打開瀏覽器應該就可以看到我們自己製作的首頁啦
http://localhost:8001/


Docker Compose

一道道料理分開點餐有點麻煩,有沒有超值套餐可以選擇

Docker Compose 就像是一個套餐一樣,點一份套餐就能包含前菜、主食、飲料、點心,只需要一個指令就能同時啟動好幾個容器

我們來做一個 Nginx + PHP-FPM 的套餐吧,找個喜歡的資料夾建立以下檔案

public/index.php

echo "<h1>Hello, Docker Compose!</h1>";

nginx-default.conf

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    root /srv/www/public;
    index index.php;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/sock/docker.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

php-fpm.conf

[global]
daemonize = no

[www]
listen = /sock/docker.sock
listen.mode = 0666

docker-compose.yml

services:
  php-fpm:
    image: php:8.2-fpm
    container_name: php-fpm
    volumes:
      - .:/srv/www
      - ./php-fpm.conf:/usr/local/etc/php-fpm.d/zz-docker.conf
      - sock:/sock

  nginx:
    image: nginx
    container_name: nginx
    depends_on:
      - php-fpm
    ports:
      - 80:80
    volumes:
      - .:/srv/www
      - ./nginx-default.conf:/etc/nginx/conf.d/default.conf
      - sock:/sock

volumes:
  sock:

接著就是用 Docker Composer 來把這個套餐做出來,加上 -d 可以在背景運行

docker composer up

現在再打開瀏覽器應該就可以看到我們自己製作的首頁啦
http://localhost/

設定 volumes(磁區)可以將容器外的目錄或檔案掛載進容器內,就好像是影分身一樣,改裡面的東西 外面的也會改變,改外面的東西 裡面的也會改變,它本質上就是同個東西嘛

因為上述原理,現在可以隨意修改 index.php,不用重新 composer up,Docker 真是個方便好用的工具

另外還有幾個常用的指令

暫停 compose

docker compose stop

繼續執行 compose

docker compose start

重啟 compose

docker compose restart

停止 compose

docker compose down

列出所有 compose

docker compose ls -a

不知不覺就來到最後一天了,看來我太低估了這個題目的複雜程度,本來是想說講完 Docker 就用它來把資料庫建起來,然後讓 Laravel 接上,完成完整版的 E2E Test

不過講不完就算啦,我相信走到這裡你也有能力自己把它完成了,最後大魔王(Docker + Laravel + Database + E2E Test + CI/CD)就交給你討伐啦,再不行的話就來 水球軟體學院 找答案吧,我把寶藏都放在那裡了


上一篇
【Walking Skeleton】Day29 - 安裝與介紹 Docker
下一篇
【Walking Skeleton】Day31 - WSL:在 Windows 中使用 Linux 系統
系列文
嘿,稍等一下!別急著開發功能,先來打造 Walking Skeleton 吧!34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言