2025年4月30日 星期三

Ubuntu 20.04 上 製作 Docker Image

這篇文章我們要把一個 shell script 放進 Docker image 裡面

廢話不多說

首先要開 terminal 然後 cd 到 .sh 的位置

就假設這個 .sh 的位置是 /home/aaa/bbb/ccc/xxx.sh

所以就 cd /home/aaa/bbb/ccc

1. 輸入 sudo vim Dockerfile

進入 vim 後先按 i

然後輸入或貼上以下內容

# Use a base image, such as Ubuntu
FROM ubuntu:20.04

# Set environment variables to avoid prompts during installation
ENV DEBIAN_FRONTEND=noninteractive

# Install necessary dependencies (adjust based on your script's needs)
RUN apt update && apt install -y \
    bash \
    libgl1-mesa-glx \
    && apt clean

# Copy your script into the container
COPY xxx.sh /home/aaa/bbb/ccc/xxx.sh
COPY folder /home/aaa/bbb/ccc/folder
# Make the script executable RUN chmod +x /home/aaa/bbb/ccc/xxx.sh # Set the working directory (optional, for context) WORKDIR /home/aaa/bbb/ccc/latest # Set the script to run when the container starts CMD ["./xxx.sh"]

註1: 在實際執行時我的 .sh 跳出 error 說缺少 libGL.so.1 

所以我必須另外安裝 libgl1-mesa-glx

註2: 如果要複製資料夾就按照黃色字的寫法就可以了

註3. COPY到 container 裡面時其實不必按照外面的路徑

我選用一樣的路徑是個人覺得這樣比較簡單明瞭


2. 建立 image

docker build -t your-image-name .

注意最後的那個 "." 不能省略,表示當前目錄的意思


3. 執行 image

docker run -d --name your-container-name your-image-name


4. 除錯

如果程式跑起來不如預期

我們可以使用以下指令看到 container 執行時的 ternimal output

sudo docker logs your-container-name


5. 網路 ip

通常我們的內網 ip 會是 192.168.0.xx 這樣的數字

但是 container 內部的 ip 是 172.17.0.2 

我的程式會先查看自己的 ip 多少,然後跟別台主機說 ip 是什麼

結果報出去的這個 172.17.0.2 是外面連不進來的

以下講幾種 chatgpt 提供的解決方法

(a) Pass the Host IP as an Environment Variable

a-1

docker run -d --name container-name -p host_ip:host_port:container_port -e HOST_IP=192.168.0.xx image-name

a-2

host_ip = os.getenv("HOST_IP", "127.0.0.1")  # Example in Python

但是我不想動到 python 那邊的 code

所以沒用這方法


(b) Fetch the Host IP Dynamically in the Container

import socket
import os

def get_host_ip():
    try:
        # Get the default gateway IP
        gateway_ip = os.popen("ip route | grep default | awk '{print $3}'").read().strip()
        return gateway_ip
    except Exception as e:
        return "127.0.0.1"

host_ip = get_host_ip()

這也是要改 python 所以跳過


(c) Use host Network Mode

docker run -d --name container-name --network=host image-name

用這方法啟動 container 就成功的解決我的問題


後面其實還提到了 Use a Reverse Proxy, Modify Client-Side Logic

然後還講到

  • If the host IP is static or known at runtime, use Solution 1 (Environment Variable).
  • If the IP changes dynamically, use Solution 2 (Fetch Gateway IP) or Solution 3 (Host Network Mode).

  • 總之,大概記錄一下遇到的問題,就講到這





    沒有留言:

    張貼留言