Docker 常見指令以及 run 一個容器

Docker

Image2Container.png

透過公開倉庫映像檔 run 容器

這種方式是直接使用他人已經建置好的映像檔來運行容器,不需要任何額外設定即可快速啟動環境。例如,如果你需要一個 Python 開發環境,可以直接拉取包含 Conda 的映像檔;若需要 PHP 環境,則可使用 php:8.3 的映像檔;想要資料庫服務,也可以使用 mariadb 映像檔。這樣我們就能立刻在這些現成的容器環境中開始開發所需的應用程式或功能。

透過 Dockerfile run 容器

這種方式是先撰寫 Dockerfile,基於現有映像檔加上自己需要的設定與套件,進一步客製化容器。這樣在容器生成前,就能確保相關依賴已預先安裝好,省去每次手動配置的麻煩。

此外,Dockerfile 可被整個團隊共用,讓所有成員建立出一致的開發環境。我們甚至可以在其中明確指定各項工具或套件的版本,進一步保證「我可以跑」的程式,在其他人的電腦上也能「一模一樣地跑」。

LAMP 環境

LAMP 是一組常見的 Web 開發環境組合,包含四個部分:

  • L - Linux:作業系統(我們使用 Ubuntu,其他 Linux 發行版也可以)
  • A - Apache:網頁伺服器,用來處理來自瀏覽器的請求
  • M - MariaDB / MySQL:資料庫,用來儲存與查詢資料(MariaDB 是 MySQL 的分支,通常狀況下我們會選擇 MariaDB,因爲比較不會翻車)
  • P - PHP:後端程式語言,處理網站的邏輯

當然也有其他的架構,比如:

  • LEMP:Nginx(讀作EngineX) + MariaDB+ PHP
  • MERN/MEAN:MongoDB + Express + React/Angular + Node.js
  • Docker-LAMP:使用 Docker 建立可攜式、隔離的 LAMP 環境

接下來我們分別試著在一個容器裏面一步步裝好以及透過一個 Dockerfile 完成建立LAMP 的環境

在接下來的章節中,筆者將將會帶領各位認識在 docker 以及 Debian 常用的指令(Ubuntu 是 Debian-based OS),首先需要安裝 docker,在接下來的操作中,我們需要保持 docker 是開啓的。

docker 基本指令

docker search [映像檔名稱]

docker hub 是其中一個公開的映像檔倉庫,今天如果我想確定我要找的 ubuntu 映像檔有沒有在 docker hub 上面讓我等一下可以拉取直接使用,我們就可以在終端機輸入以下指令去搜尋與 ubuntu 相關的映像檔。

docker search ubuntu

我們可以看到執行該指令後終端機會顯示如下: docker search 這裏都是名稱中有包含 Ubuntu 的所有映像檔,通常我們會看 STARS 的數量,如果你需要官方的映像檔,在 OFFICIAL 的欄位則會標記 [OK]。現在我麽需要找 ubunt 官方的映像檔,我們就選擇第一個有被標記 OFFICIAL 的搜尋結果。

docker pull [映像檔名稱]

這個指令我們可以把 ubuntu 從 docker hub 上 pull 下來。

docker pull ubuntu

我們可以看到執行該指令後終端機會顯示如下: docker pull 這樣表示我們已經成功將 Ubuntu 的映像檔 pull 下來了。

docker image [選項] [參數]

這個指令可以讓我們對 image 做一些行爲,但是我們不知道有什麽選項可以供我們選擇,可以輸入下面不完整的指令使得 docker 輸出指令使用方式的説明

docker image
# 或是
docker image COMMAND --help

我們可以看到執行該指令後終端機會顯示如下: docker image 因爲剛剛我們想要查看我們剛剛 pull 的 image,我們可以選擇 ls (List)作爲我們的選項。

docker image ls
# 或是
docker images # 加上 s 

我們可以看到執行該指令後終端機會顯示如下: docker image ls 筆者反白的部分則是我們剛剛 pull 下來的 Ubuntu image,接下來我們要用這個 image 去生成這個容器。

docker run [一堆選項參數 …]

在這個部分,我們先停一下,思考一下要開啓哪些 port。

port 通訊埠

在上一篇我們提到在開發網頁需要一個伺服器,我們可以透過 docker 生成一個 container 使其充當網頁伺服器,但是這個 port 號碼有什麽關係?

一般來説一個伺服器會有 65535 個 port,這些 port 都在運行一些服務,譬如説:

  • port 22:ssh 連線
  • port 25:郵箱的 SMTP 協定
  • port 20 與 21:FTP (檔案通訊協定)
  • port 80:http 超文本傳輸協定(網頁伺服器會用到的 port)
  • port 443:https 更加 secure 的 http (網頁伺服器會用到的 port)

我們需要將一些我們需要的 port 轉發/映射(mapping)到我們的主機,對於網頁伺服器來説我們需要 80 port。

docker run 指令

我先給大家一個指令,我們再分別解釋每個部分。

docker run -dit -p 8080:80 --name=ubuntu_container --privileged ubuntu  /bin/bash
部分上述指令 描述
run 生成並運行一個容器 docker run
-dit -d -i -t 組成
-d: detach 分離當前終端機,也就是背景執行的意思
-it: 分別是 interactive 與 terminal 即互動式終端機
-p 8080:80 像剛剛提到的,我們需要將容器網頁的 80 port 轉發到自己電腦的 8080 port,讓我們可以從自己的電腦 8080 port 去訪問容器中的網頁
--name=a_name 為該容器命名
--privileged 這個參數是讓容器又可以控制主機的權限,我們在上一篇講過容器可以隔離主機的環境在裏面測試一些危險的程式,如果今天加上了這個--privileged 容器就不安全了(因爲是示範,所以請大家省略這個參數)
ubuntu 你要用的映像檔名稱
/bin/bash 一連上終端機的會啓動的程式,很明顯我們選擇 bash,他讓我們一連上終端機就有命令列可以使用

我們可以看到執行該指令後終端機會顯示如下: docker run ….

這表示我們已經成功建立一個容器,若指令沒有問題但是容器建立失敗,可能是已經有另外一個容器也用了主機的 8080 port(或是其他的 port)或是主機本身在這個 port 有服務在運行,修改指令映射到其他的 port 便可以解決這個問題

docker ps

透過這個指令我們可以查看當前主機上容器的運行狀況。加上 -a(all) 可以連同停止的容器狀況一並顯示。

docker ps
# 或是
docker ps -a

我們可以看到執行該指令後終端機會顯示如下: docker ps -a

docker stop [容器ID/容器名稱]

當前 ubuntu_container 容器時開啓的狀態,他的容器 ID 是 47383a4698afb60e004762fcbdedd38f0e86cb0222118d778767b96d0e68cb53,我們可以透過

docker stop ubuntu_container # 容器名稱依據實際狀況替換
docker stop 4738 # 你的容器ID的前幾位

容器 ID 有 64 個字元那麽長,但是如果只有一個容器是 4 開頭的話,甚至可以簡化指令變成:

docker stop 4

我們可以看到執行該指令後終端機會顯示如下: docker stop 容器也確實成功關閉了。

docker start [容器ID/容器名稱]

docker stop 指令同理,把指令中 stop 的部分改成 start,就能夠開啓某個容器。

docker start ubuntu_container # 容器名稱依據實際狀況替換
# 或是
docker start 4738 # 你的容器ID的前幾位
# 或是
docker start 4  

我們可以看到執行該指令後終端機會顯示如下: docker start ubuntu_container 容器成功開啓了。

docker rm [容器ID/容器名稱]

docker stop 指令同理,把指令中 stop 的部分改成 rm,就能夠刪除某個容器。

指令替換

剛剛我們有提到 docker ps -a ,現在我們加上 -q ,是 quietly 的意思,也就是不會輸出容器 ID 以爲外的内容。

我們可以看到執行該指令後終端機會顯示如下: docker start

我們也知道要開關一個容器我們知道容器 ID 前幾位就能夠辦到,因此我們可以將 docker ps -aqdocker start 或是 docker stop 以及 docker stop 結合,讓我們能夠透過一個指令進行 開啓關閉以及刪除 所有容器

這裏示範開啓所有容器:

docker start $(docker ps -aq)

docker ps -aq 會先被執行,換成容器的 ID 之後再依據這些 ID 開啓容器,我們可以看到執行該指令後終端機會顯示如下: docker command sub 所有的容器都成功被打開了。

docker attach [容器ID/容器名稱]

我們在使用這個指令前需要先確保你要使用的容器是開啓的狀態,如果我們要用終端機“連線”到容器,我們可以用

docker attach ubuntu_container
# 或是
docker attach 14

我們可以看到執行該指令後終端機會顯示如下: docker attach 我們就成功連到容器裏面了,在這裏就是我們就可以使用 Ubuntu 的指令了。

你需要注意的是當你要離開這個容器的時候,在 Ubuntu 的命令列輸入 exit 或是 logout, 將會結束容器的連線,此時容器會被關閉,如果你不想要離開容器就被關閉的話,讓我們看看下一個指令

docker exec [一堆參數…]

很明顯這個指令就是跟上一個 docker attach 一樣的功能,但是你可以不用進入容器就可以執行指令,我們先連到這個容器的 shell 吧,也就是用終端機連到這個容器。

docker exec -it ubuntu_container /bin/bash
# 或是
docker exec -it 14 /bin/bash
# 可以簡化 /bin/bash 變成 bash
# bash 在 ubuntu 已經是指令,可以不需要透過絕對路徑執行了
docker exec -it ubuntu_container bash

我們可以看到執行該指令後終端機會顯示如下: docker exec binbash 在這裏我們離開容器時,容器不會被關掉了

同時你也可以試試看在容器外面執行指令,我們舉 ls -la ,條列顯示根目錄下所有内容。

docker exec -it ubuntu_container ls -la

我們可以看到執行該指令後終端機會顯示如下: docker exec ls -la 確實可以看到根目錄下所有東西,相對來説 docker execdocker attach 有用太多了


進入容器安裝相關工具

我們在開發的過程中,肯定不會在終端機不斷地打指令、開文字編輯器、切換視窗…… 我不是説終端機做不到,而是這樣太浪費時間了。因此我們的好朋友 VScode 就能夠幫我們大忙。下載 VScode

  1. 之後我們打開 VScode 安裝兩個插件:

  2. 接著透過 VScode 進入容器。 vscode attach

  3. 打開資料夾。 vscode open folder

  4. 切換到 / 目錄下,也就是 “根目錄”。 vscode root dir

  5. 接著我們打開終端機輸入更新套件包的指令(apt: advanced package tool)。

    apt update
    apt upgrade -y
    

    vscode open terminal and update

  6. 接著我們一口氣安裝所有 LAMP 中與 AMP 相關的工具

    apt install -y apache2 php php-mysql mariadb-server
    

    vscode install dependencies 記得選地區以及時區。 vscode location vscode time zone

  7. 接著我們啓動 apache2 以及 mariaDB 的服務

    service apache2 start
    service mariadb start
    # 或是 restart 也是可以
    service apache2 restart
    service mariadb restart
    

    打開瀏覽器輸入 localhost:8080(我們先前設定容器的 80 port 轉發到主機的 8080 port),我們可以看到 apache2 成功安裝的網頁。 apache2 successfully

  8. 下載 Phpmyadmin(簡稱 pma) 管理資料庫的工具

    apt install phpmyadmin -y
    

    vscode pma install 選擇 config database 輸入 yes 後,設定兩次密碼,這密碼可以隨便設定或是留白直接按 Enter,因爲這個密碼我們沒辦法使用 vscode pma password 選擇 apache2 vscode pma apache2

  9. 我們重新啓動 apache2 以及 mariaDB 的服務

    service apache2 restart
    service mariadb restart
    

    接著在瀏覽器的網址欄輸入

    http://localhost:8080/phpmyadmin/
    

    我們就會看到 phpmyadmin 的登入頁面了 pma login

  10. 接著我們再去改資料庫密碼

    # 以 root 的身分登入
    mariadb -u root
    

    並且在 mysql 的命令列中輸入以下指令,將最後面的 root 改成你自己的密碼,我打算將 root 作爲我的資料庫帳號與密碼

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
    

    mariadb change password 最後輸入 exit 離開 mariaDB 的命令列

  11. 重新啓動 apache2 以及 mariaDB 的服務(以後重新打開容器都要執行這兩個指令開啓服務,才會有網頁)

    service apache2 restart
    service mariadb restart
    

    vscode restart apache2

  12. 再次回到 phpmyadmin 接著在瀏覽器的網址欄輸入

    http://localhost:8080/phpmyadmin/
    

    使用

    帳號:root
    密碼:root
    

    登入 phpmyadmin pma login pma login 看到這個畫面表示登入成功,能夠登入表示資料庫沒有問題,應爲phpmyadmin 用資料庫的帳號密碼去登入,自己本身只是一個資料庫的工具沒有帳號密碼。到這裏我們的 LAMP 環境就已經透過自己輸入指令的方式完成了,接下來要進行網頁的開發可以將網頁放到 /var/www/html 的目錄下。