前言:在應用項目部署中,“環境不一致”往往是開發與運維的痛點——本地能跑的代碼到了服務器就報錯,依賴版本、系統配置差異都可能成為隱患。而Docker的容器化技術恰好能解決這一問題,通過“一次構建,到處運行”的特性,讓環境完全可控。
Node.js作為前端工程化(如Vite、Webpack)和服務端渲染(SSR)的核心運行環境,搭配pnpm(高效的包管理器,比npm/yarn更節省磁盤空間)和pm2(Node進程守護工具,確保服務穩定運行),能形成一套高效的前端部署鏈路。
本文將從0到1拆解手動操作流程:從Docker安裝開始,到Node.js 20.15.0環境部署,再到pnpm和pm2的配置,全程包含常見報錯處理(如網絡超時、命令找不到等)。步驟雖偏基礎,但每一步都有明確的邏輯說明,適合新手直觀理解容器化環境的搭建原理。
(注:本文為手動操作指南,旨在幫助大家理清底層邏輯;后續會推出基于Dockerfile的自動化部署版本,通過代碼固化流程,進一步提升部署效率。)
一、安裝Docker
(一)卸載舊版本(若有)
舊版本Docker可能與新版本沖突,執行以下命令卸載:
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
(二)安裝依賴包
Docker依賴yum-utils
等工具配置軟件源,安裝命令:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
(三)配置Docker官方軟件源
使用官方源保障版本穩定,執行:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
(四)安裝Docker Engine
安裝包含docker-ce
引擎、docker-ce-cli
等的最新版Docker:
sudo yum install -y docker-ce docker-ce-cli containerd.io
報錯處理:
從報錯信息 [Errno 14] curl#35 - "TCP connection reset by peer"
來看,這不正常,說明在執行 yum-config-manager --add-repo
命令拉取 Docker 官方 repo 文件時,網絡連接被對方(Docker 官方服務器)重置了,可能是網絡問題、Docker 官方源訪問限制等導致。
解決思路:
- 檢查網絡:確保服務器能正常訪問外網,可嘗試
ping download.docker.com
,或用curl https://download.docker.com
測試基本連通性。若網絡不通,排查服務器網絡配置(如防火墻、代理等 )。 - 更換源:如果訪問 Docker 官方源一直有問題,可改用國內鏡像源(比如阿里云的 Docker 鏡像源 ),步驟如下:
# 備份原 repo(若有) sudo mv /etc/yum.repos.d/docker-ce.repo /etc/yum.repos.d/docker-ce.repo.bak # 添加阿里云 Docker 源 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 清理緩存重試:更換源或確保網絡正常后,清理 yum 緩存再嘗試安裝相關操作:
sudo yum clean all sudo yum makecache # 重新嘗試 安裝 Docker 引擎、客戶端等 sudo yum install -y docker-ce docker-ce-cli containerd.io # 啟動 Docker 并設置開機自啟 sudo systemctl start docker sudo systemctl enable docker
報錯處理完成
(五)Docker版本驗證
安裝完成后,通過以下命令驗證版本:
- 查看完整版本信息(客戶端和服務端):
docker version
- 簡潔查看客戶端版本:
docker -v
(六)配置Docker鏡像加速
添加國內鏡像加速并優化配置,執行:
sudo mkdir -p /etc/docker && sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}
EOF
(七)重啟Docker服務使配置生效
sudo systemctl daemon-reload && sudo systemctl restart docker
(八)驗證Docker安裝成功
運行hello-world
容器測試:
sudo docker run hello-world
輸出Hello from Docker!
相關信息則安裝成功。
報錯處理:
若拉取鏡像報錯(如網絡超時),需重新確認鏡像加速配置:
1. 獲取專屬鏡像加速地址
登錄阿里云 容器鏡像服務控制臺 ,在“鏡像工具”下找到“鏡像加速器”,復制專屬的鏡像加速地址。這里就不展示我個人的鏡像站了。
2. 檢查并修改配置文件
檢查 /etc/docker/daemon.json
文件,確保配置正確。如果文件內容有誤或不完整,你可以按照以下內容修改:
sudo nano /etc/docker/daemon.json
將文件內容修改為(將 https://你的專屬加速地址.mirror.aliyuncs.com
替換為你從阿里云控制臺獲取的真實加速地址):
{"registry-mirrors": ["https://你的專屬加速地址.mirror.aliyuncs.com"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}
修改完成后,按下 Ctrl + X
,然后按 Y
保存修改,最后按 Enter
確認。
保存后重啟Docker:
sudo systemctl daemon-reload && sudo systemctl restart docker
如果啟動失敗:
這是在 Linux 系統中執行 jq . /etc/docker/daemon.json
命令時出現的報錯,實體信息是:系統提示 jq
命令未找到(-bash: jq: command not found
),說明當前系統沒有安裝 jq
工具 。
若要使用 jq
檢查 daemon.json
語法,需先安裝 jq
,以 CentOS/RHEL 系統為例,可執行 sudo yum install -y jq
;以 Debian/Ubuntu 系統為例,可執行 sudo apt install -y jq
進行安裝。
更換其他鏡像加速源
如果阿里云鏡像加速依然無法解決問題,可以嘗試使用其他鏡像源:
- 網易云鏡像源:
sudo nano /etc/docker/daemon.json
將文件內容修改為:
{"registry-mirrors": ["https://hub-mirror.c.163.com"]
}
修改完成后保存并退出,然后重新加載Docker配置并重啟Docker服務:
sudo systemctl daemon-reload
sudo systemctl restart docker
- 清華大學鏡像源:
sudo nano /etc/docker/daemon.json
將文件內容修改為:
{"registry-mirrors": ["https://docker.mirrors.tuna.tsinghua.edu.cn"]
}
同樣修改完成后保存并退出,執行以下命令重新加載配置和重啟服務:
sudo systemctl daemon-reload
sudo systemctl restart docker
報錯處理完成
驗證鏡像加速配置是否生效
配置完成后,再次嘗試拉取 hello-world
鏡像:
sudo docker run hello-world
如果配置生效,應該能夠正常從鏡像加速源拉取鏡像并運行,顯示類似 Hello from Docker!
的成功提示信息。
2. 驗證配置生效
重新執行hello-world
測試:
sudo docker run hello-world
若仍報錯,可能是網絡限制,建議檢查服務器網絡或更換鏡像源。
二、部署Node.js 20.15.0環境(含pnpm、pm2)
(一)選擇Node.js鏡像
Node.js官方提供alpine
版本(輕量級),適合容器化部署,無需依賴底層OS(如CentOS、Rocky、ubuntu),鏡像體積小且環境完整,完全滿足前端項目(靜態文件、Vite Server)需求。
(二)拉取Node.js 20.15.0官方鏡像
執行以下命令拉取輕量的alpine
版本:
sudo docker pull node:20.15.0-alpine
通過sudo docker images
查看,顯示node:20.15.0-alpine
即拉取成功。
(三)創建并進入Node.js容器
創建持久化容器并進入終端:
sudo docker run -itd --name node20-container node:20.15.0-alpine /bin/sh
sudo docker exec -it node20-container /bin/sh
進入后終端前綴顯示/#
,表示在容器內操作。
(四)在容器內安裝pnpm
pnpm是高效包管理工具,通過官方腳本安裝:
apk update
apk add curl
curl -fsSL https://get.pnpm.io/install.sh | sh -
報錯原因分析
WARN
提示:using --force I sure hope you know what you are doing
是因為安裝腳本檢測到使用了一些強制操作相關的參數(curl
里的--force
類似強制行為 ),不過這不是關鍵問題。ERR_PNPM_UNKNOWN_SHELL
錯誤:安裝腳本無法推斷當前使用的 Shell 類型,雖然報錯,但并不影響pnpm
二進制文件的拷貝安裝。pnpm: not found
:這是因為安裝腳本沒成功配置環境變量,使得系統無法在默認路徑找到pnpm
命令 。
安裝過程中出現了問題,但其實pnpm
已經安裝成功了 ,只是環境變量沒配置好,導致系統找不到pnpm
命令。
如果以上curl很慢,就執行以下命令:
curl -fsSL https://registry.npmmirror.com/-/binary/pnpm/install.sh | sh -
如果想更猛的話就修改為共用宿主機網絡:(生產環境上謹慎操作)
1. 如果容器已啟動,但未使用 --network=host
進入容器后直接執行原命令(無需添加 --network=host
):
docker exec -it <容器名> /bin/sh
# 在容器內執行:
curl -fsSL https://get.pnpm.io/install.sh | sh -
2. 如果需要使用 host
網絡模式
步驟 1:先停止并刪除當前容器(如果已存在):
docker stop <容器名> && docker rm <容器名>
步驟 2:使用 --network=host
參數重新創建容器:
docker run -itd --name <容器名> --network=host node:20.15.0-alpine /bin/sh
步驟 3:進入容器并執行安裝命令:
docker exec -it <容器名> /bin/sh
# 在容器內執行:
curl -fsSL https://get.pnpm.io/install.sh | sh -
- 網絡慢或超時:改用國內源腳本:
curl -fsSL https://registry.npmmirror.com/-/binary/pnpm/install.sh | sh -
pnpm: not found
:環境變量未配置,執行:echo 'export PATH="$HOME/.local/share/pnpm:$PATH"' >> ~/.profile && source ~/.profile
(五)配置pnpm環境變量(讓命令全局可用)
執行:
echo 'export PATH="$HOME/.local/share/pnpm:$PATH"' >> ~/.profile && source ~/.profile
(六)驗證pnpm安裝
pnpm -v
輸出版本號(如10.13.1
)即成功。
可選步驟(根據具體需求選擇執行不)
插個題外話,如果想降級到指定版本,需要先徹底卸載當前版本,再用指定版本安裝命令,如 pnpm8.15.0版本(此步驟謹慎操作)
要完全卸載 pnpm 并清理所有相關文件和配置,可以執行以下命令:
1. 刪除 pnpm 二進制文件
# 刪除 pnpm 和 pnpx 可執行文件
rm -f ~/.local/share/pnpm/pnpm
rm -f ~/.local/share/pnpm/pnpx# (可選)如果使用了全局安裝路徑,也刪除這些位置的文件
rm -f /usr/local/bin/pnpm
rm -f /usr/local/bin/pnpx
2. 清理環境變量配置
# 編輯 Shell 配置文件(根據你使用的 Shell 選擇)
nano ~/.profile # 或 .bashrc, .zshrc, .shrc 等# 在文件中找到并刪除以下類似的行(如果存在):
export PATH="$PATH:/root/.local/share/pnpm"
# 或
export PNPM_HOME="/root/.local/share/pnpm"
export PATH="$PNPM_HOME:$PATH"# 保存并退出編輯器(按 Ctrl+O 保存,Ctrl+X 退出)# 使配置立即生效
source ~/.profile # 或 source ~/.bashrc, ~/.zshrc 等
3. 刪除 pnpm 存儲的全局包和緩存
# 刪除 pnpm 全局包存儲目錄
rm -rf ~/.local/share/pnpm/store# 刪除 pnpm 緩存目錄
rm -rf ~/.pnpm-store
4. 驗證卸載結果
pnpm -v # 應顯示 "command not found"
額外說明
- 如果是通過
npm install -g pnpm
安裝的,先執行:npm uninstall -g pnpm
- 如果使用的是 Fish Shell,配置文件路徑為
~/.config/fish/config.fish
,需編輯該文件刪除相關環境變量。
完成上述步驟后,pnpm 會被徹底移除,可以重新開始干凈的安裝流程。
安裝指定版本:curl -fsSL https://get.pnpm.io/install.sh | sh -s -- --version 8.15.0
(七)在容器內安裝pm2
pm2用于守護Node.js應用進程,執行:
pnpm add -g pm2
報錯處理:
由于 pnpm setup
命令因無法推斷 Shell 類型報錯,導致不能自動創建全局二進制目錄,這種情況下使用方法二手動設置全局二進制目錄和環境變量是比較好的選擇。以下是具體的操作步驟:
1. 創建全局二進制目錄
在容器內執行以下命令,創建用于存放 pnpm 全局包二進制文件的目錄:
mkdir -p ~/.local/share/pnpm_global_bin
mkdir -p
命令會創建目錄,如果目錄已經存在則不會報錯。
2. 設置環境變量
將創建的全局二進制目錄添加到 PATH
環境變量中,同時設置 PNPM_HOME
環境變量:
export PNPM_HOME=~/.local/share/pnpm
export PATH="$PNPM_HOME/global_bin:$PATH"
上述命令設置了 PNPM_HOME
為 pnpm 的主目錄,并且將全局二進制目錄路徑添加到了 PATH
中,這樣系統就能找到全局安裝的包的可執行文件。
為了讓這些環境變量在每次進入容器時都生效,可以將它們追加到 Shell 配置文件中。在 Alpine Linux 中,默認的 Shell 是 /bin/sh
,通常可以編輯 ~/.profile
文件(如果是其他 Shell,如 bash
,則編輯對應的配置文件,如 ~/.bashrc
):
echo 'export PNPM_HOME=~/.local/share/pnpm' >> ~/.profile
echo 'export PATH="$PNPM_HOME/global_bin:$PATH"' >> ~/.profile
source ~/.profile
source ~/.profile
命令用于立即生效剛剛添加到配置文件中的環境變量,而不需要重新登錄或重啟容器。
3. 安裝 pm2
完成上述環境變量設置后,再次嘗試使用 pnpm 安裝 pm2:
pnpm add -g pm2
安裝完成后,可以使用 pm2 -v
命令來檢查 pm2 是否安裝成功,如果能輸出版本號,就說明安裝成功了。
(八)驗證pm2安裝
pm2 -v
輸出版本號(如5.3.0
)即成功。
三、驗證環境完整性
在容器內依次執行以下命令,驗證所有依賴:
# 驗證Node.js版本
node -v # 應輸出v20.15.0
# 驗證npm版本(Node自帶)
npm -v # 應輸出對應版本(如10.7.0 )
# 驗證pnpm版本
pnpm -v # 輸出安裝的版本
# 驗證pm2版本
pm2 -v # 輸出安裝的版本
所有命令正常輸出版本號,環境配置完成。
四、容器與項目管理
(一)容器持久化(掛載項目目錄)
為同步宿主機項目代碼到容器,啟動容器時添加掛載參數:
# 先停止并刪除現有容器(若需)
sudo docker stop node20-container && sudo docker rm node20-container# 啟動容器并掛載宿主機項目目錄
sudo docker run -itd \--name node20-container \-v /your/local/project:/container/project \node:20.15.0-alpine /bin/sh
/your/local/project
:宿主機項目目錄(需替換為實際路徑)/container/project
:容器內映射目錄
(二)應用部署流程
- 進入容器并切換到項目目錄:
sudo docker exec -it node20-container /bin/sh cd /container/project
- 安裝項目依賴:
pnpm install
- 用pm2啟動應用:
pm2 start server.js --name your-app-name
(三)容器管理常用命令
- 停止容器:
sudo docker stop <容器名>
- 重啟容器:
sudo docker restart <容器名>
- 刪除容器(需先停止):
sudo docker rm <容器名>
- 查看容器日志:
sudo docker logs <容器名>
五、環境持久化驗證
為確保容器重啟后環境可用,可按以下步驟驗證:
-
停止并刪除當前容器:
docker stop node20-container && docker rm node20-container
-
重新創建容器:
docker run -itd --name node20-container node:20.15.0-alpine /bin/sh
-
進入新容器,重新配置環境:
docker exec -it node20-container /bin/sh # 重新執行pnpm和pm2安裝步驟(容器重建后需重新配置)
說明:容器本身是“無狀態”的,重建后需重新安裝依賴。若需環境持久化,后續可通過Dockerfile固化環境(后續文章將詳細介紹)。
總結
本文詳細演示了通過手動操作完成 Docker 安裝、Node.js 20.15.0 環境部署的全過程,同步實現了 pnpm 包管理工具與 pm2 進程管理工具的配置,并針對性解決了網絡連接異常、環境變量配置錯誤等常見問題。盡管手動操作流程相對繁瑣,但能讓使用者更直觀地理解容器化環境的底層運行邏輯與核心配置原理,為后續靈活應對復雜場景打下基礎。