# 建立自訂 Docker 映像

[[目錄]]

::: 警告 本教學使用 core:java (opens new window) docker 映像中的範例, 可以在 GitHub 上找到。本教學也假設您了解 Docker (opens new window) 的一些知識,我們建議 如果這一切對你來說很陌生,請閱讀。 :::

# 建立 Dockerfile

此過程最重要的部分是建立 Dockerfile (opens new window) 將由守護程式使用。由於伺服器容器受到嚴格限制,您必須以特定方式設定此檔案。

我們嘗試在圖像中盡可能使用 Alpine Linux (opens new window) 以減少圖像的大小。

# ----------------------------------
# Pterodactyl Core Dockerfile
# Environment: Java
# Minimum Panel Version: 0.6.0
# ----------------------------------
FROM openjdk:8-jdk-alpine

MAINTAINER Pterodactyl Software, <support@pterodactyl.io>

RUN apk add --no-cache --update curl ca-certificates openssl git tar bash sqlite fontconfig \
    && adduser --disabled-password --home /home/container container

USER container
ENV  USER=container HOME=/home/container

WORKDIR /home/container

COPY ./entrypoint.sh /entrypoint.sh

CMD ["/bin/bash", "/entrypoint.sh"]

讓我們來瀏覽一下上面的 Dockerfile 。您會注意到的第一件事是 FROM (opens new window) 宣告。

FROM openjdk:8-jdk-alpine

在本例中,我們使用 openjdk:8-jdk-alpine (opens new window) ,它為我們提供了 Java 8。

# 安裝依賴項

接下來我們要做的就是使用 Alpine 的套件管理器來安裝我們需要的依賴項: apk 。你會注意到一些 保持容器較小的特定標誌,包括 --no-cache ,以及包含在 單一 RUN (opens new window) 區塊。

# 建立容器用戶

在這個 RUN 區塊中,您會注意到 useradd 指令。

adduser -D -h /home/container container

::: 警告 所有 Pterodactyl 容器都必須有一個名為 container 的用戶,用戶主目錄 必須/home/container 。 :::

建立該使用者後,我們定義預設容器 USER (opens new window) 以及一些應用於正在運行的事物的 ENV (opens new window) 設置 容器內。

# 工作目錄和入口點

我們做的最後一件事是定義一個 WORKDIR (opens new window) ,它 是執行其他所有操作的地方。 WORKDIR 必須設定為 /home/container

最後,我們需要將 ENTRYPOINT (opens new window) 腳本複製到 docker 映像根目錄。這是使用 COPY (opens new window) 完成的,之後 我們使用 CMD (opens new window) 定義容器啟動時要使用的命令。 CMD 行應始終指向 entrypoint.sh 檔案。

COPY ./entrypoint.sh /entrypoint.sh
CMD ["/bin/bash", "/entrypoint.sh"]

# 入口點腳本

為了完成這個 Dockerfile ,我們需要一個 entrypoint.sh 檔案來告訴 Docker 如何運作它 特定伺服器類型。

這些入口點檔案其實是相當抽象的,Daemon 會將啟動指令當作環境傳入 變量,然後處理它,然後執行命令。

#!/bin/bash
cd /home/container

# Output Current Java Version
java -version ## only really needed to show what version is being used. Should be changed for different applications

# Replace Startup Variables
MODIFIED_STARTUP=`eval echo $(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')`
echo ":/home/container$ ${MODIFIED_STARTUP}"

# Run the Server
${MODIFIED_STARTUP}

第二個命令 cd /home/container 只是確保我們在運行其餘部分時位於正確的目錄中 命令。然後,我們使用 java -version 將此資訊輸出給最終用戶,但這不是必需的。

# 修改啟動命令

該文件最重要的部分是 MODIFIED_STARTUP 環境變數。在這種情況下我們正在做什麼 正在解析由守護程式傳遞到容器中的環境 STARTUP 。大多數情況下,這個變數 看起來類似下面的範例:

STARTUP="java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}"

您會注意到那裡有一些佔位符,特別是 {{SERVER_MEMORY}}{{SERVER_JARFILE}} 。這兩個都指的是 傳入的其他環境變量,它們看起來類似於下面的範例。

SERVER_MEMORY=1024
SERVER_JARFILE=server.jar

有許多不同的環境變量,它們根據特定的服務選項而變化 配置。然而,這不一定是值得擔心的事。

MODIFIED_STARTUP=`eval echo $(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')`

上面的命令只是評估 STARTUP 環境變量,然後替換 大括號 {{EXAMPLE}} 與符合的環境變數(例如 EXAMPLE )。因此,我們的 STARTUP 指令:

java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}

變成:

java -Xms128M -Xmx1024M -jar server.jar

# 運行命令

最後一步是執行這個修改後的啟動指令,這是透過 ${MODIFIED_STARTUP} 行完成的。

### 筆記

有時您可能需要變更 entrypoint.sh 檔案的權限,在 Linux 上您可以透過在檔案所在目錄中執行 chmod +x entrypoint.sh 來完成此操作。