我们在官网找到二进制安装docker文档Binaries | Docker Docs
先决条件:
64位主机 查看命令 uname -p
Linux >=3.10 查看命令 uname -r
iptables >=1.4 查看命令 iptables -V
git >=1.7 查看命令 git version
xz >=4.9 查看命令 xz -V
ps可执行文件 查看命令ps -V
cgroupfs正确挂载 查看cgroupfs挂载
启用 SELinux 或 AppArmor
启用
seccomp安全配置文件启用用户命名空间
环境版本
安装docker 二进制文件
转到 https://download.docker.com/linux/static/stable/,选择您的硬件平台,然后下载与要安装的 Docker Engine 版本相关的
.tgz文件。
wget https://download.docker.com/linux/static/stable/x86_64/docker-28.0.4.tgz使用tar提取docker和dockerd二进制文件
tar xzvf /path/to/<FILE>.tar.gz将二进制文件移动到可执行路径上的目录,例如
/usr/bin/。如果跳过此步骤,则必须在调用docker或dockerd命令时提供可执行文件的路径。
sudo cp docker/* /usr/bin/启动docker守护程序
sudo dockerd &如果您需要使用其他选项启动守护进程,请相应地修改上述命令或创建并编辑文件 /etc/docker/daemon.json 以添加自定义配置选项。
要编写
docker.service文件加入Linux服务当中并开启守护进程
# vim /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service time-set.target
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3
# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
# TasksMax=infinity
# Older systemd versions default to a LimitNOFILE of 1024:1024, which is insufficient for many
# applications including dockerd itself and will be inherited. Raise the hard limit, while
# preserving the soft limit for select(2).
#LimitNOFILE=1024:524288
LimitNOFILE=524288
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target# 添加可执行权限
chmod +x /etc/systemd/system/docker.service
# 配置文件生效,加载daemon-reload
systemctl daemon-reload
# 设置开机自启动
systemctl enable --now docker.service拓展: 查看docker.service的启动路径
systemctl show -p FragmentPath docker
注意:docker 用户组存在,但不包含任何用户,因此需要使用 sudo 来运行 Docker 命令。继续 Linux 安装后 以允许非特权用户运行 Docker 命令和其他可选配置步骤
# 创建一个docker组
sudo groupadd docker
# 将当前用户加入到组中
sudo usermod -aG docker $USER
# 使组变化生效
newgrp docker安装Docker Compose CLI plugin
插件仓库地址:https://github.com/docker/compose/
mkdir -p /usr/local/lib/docker/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.36.2/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version安装docker buildx plugin
插件仓库地址:https://github.com/docker/buildx/
mkdir -p /usr/local/lib/docker/cli-plugins
curl -SL https://github.com/docker/buildx/releases/download/v0.24.0/buildx-v0.24.0.linux-amd64 -o /usr/local/lib/docker/cli-plugins/docker-buildx
chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
docker buildx version
docker buildx ls========================================================================
脚本化安装
将以上安装步骤脚本化,并安装最新的二进制包
#!/bin/bash
###############################################################################
# Docker CE 二进制部署脚本 - Kylin V10 V11 最终兼容版
# 适用: Kylin V10 V11 / CentOS / Ubuntu x86_64/aarch64
###############################################################################
set -euo pipefail
DOCKER_VERSION="${DOCKER_VERSION:-}"
COMPOSE_VERSION="${COMPOSE_VERSION:-}"
BUILDX_VERSION="${BUILDX_VERSION:-}"
TMP_DIR="/tmp/docker-install-$$"
INSTALL_DIR="/usr/local/bin"
CLI_PLUGIN_DIR="/usr/local/lib/docker/cli-plugins"
LOCK_FILE="/tmp/.docker-install.lock"
DOCKER_CE_MIRROR="https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/static/stable"
GH_API="https://api.github.com"
GH_RELEASES="https://github.com"
CURL_OPTS="-fsSL --connect-timeout 15 --retry 3 --retry-delay 2"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*" >&2; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*" >&2; }
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
acquire_lock() {
exec 200>"$LOCK_FILE"
if ! flock -n 200; then
error "另一个 Docker 安装任务正在运行 (lock: $LOCK_FILE)"
fi
info "✅ 已获取安装锁"
}
release_lock() {
flock -u 200 2>/dev/null || true
rm -f "$LOCK_FILE"
}
if [[ $EUID -ne 0 ]]; then
error "请使用 root 用户或 sudo 执行此脚本"
fi
acquire_lock
trap 'release_lock; rm -rf "$TMP_DIR"' EXIT
info "预检网络连通性..."
if ! curl -s -o /dev/null --connect-timeout 5 "$GH_API"; then
error "无法直连 api.github.com"
fi
if ! curl -s -o /dev/null --connect-timeout 5 "$DOCKER_CE_MIRROR/x86_64/"; then
error "无法访问清华 Docker CE 镜像"
fi
info "✅ 网络连通性检查通过"
ARCH=$(uname -m)
case "$ARCH" in
x86_64) DOCKER_ARCH="x86_64"; COMPOSE_ARCH="x86_64"; BUILDX_ARCH="amd64" ;;
aarch64) DOCKER_ARCH="aarch64"; COMPOSE_ARCH="aarch64"; BUILDX_ARCH="arm64" ;;
*) error "不支持的架构: $ARCH" ;;
esac
info "系统架构: $ARCH -> Docker: $DOCKER_ARCH, Buildx: $BUILDX_ARCH"
mkdir -p "$TMP_DIR" "$CLI_PLUGIN_DIR"
# ==================== 版本获取(彻底修复 stdout/stderr 污染)====================
get_latest_docker_version() {
info "查询 Docker Engine 最新稳定版本..."
local page_file="$TMP_DIR/docker_page.html"
local matched="" stripped="" version=""
# 【核心修复】curl 输出到文件,避免 $() 捕获任何非预期内容
if ! curl $CURL_OPTS "${DOCKER_CE_MIRROR}/${DOCKER_ARCH}/" -o "$page_file"; then
error "无法访问清华 Docker CE 镜像"
fi
# 【核心修复】grep 从文件读取 + 严格正则,只匹配纯版本文件名
matched=$(grep -oE '^docker-[0-9]+\.[0-9]+\.[0-9]+\.tgz$' "$page_file" 2>/dev/null || true)
if [[ -z "$matched" ]]; then
# 兜底:TUNA 目录页可能是 HTML <a> 标签格式
matched=$(grep -oE 'docker-[0-9]+\.[0-9]+\.[0-9]+\.tgz' "$page_file" 2>/dev/null || true)
fi
if [[ -z "$matched" ]]; then
error "未从镜像页面匹配到 Docker 版本文件,请手动指定 DOCKER_VERSION"
fi
stripped=$(echo "$matched" | sed 's/docker-//;s/\.tgz//')
version=$(echo "$stripped" | sort -V | tail -n1)
# 【核心修复】版本号格式校验,防止非法字符串进入 URL
if ! echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
error "解析出的版本号格式非法: '$version'"
fi
echo "$version"
}
# ==================== GitHub 镜像配置 ====================
# 优先使用 ghproxy,备选 kkgithub;可通过环境变量覆盖
GH_PROXY="${GH_PROXY:-https://ghfast.top/}"
# 注意:GH_PROXY 末尾必须带 /
if [[ "${GH_PROXY}" != */ ]]; then
GH_PROXY="${GH_PROXY}/"
fi
# ==================== 版本获取(API 也走镜像)====================
get_latest_gh_release() {
local repo="$1"
info "查询 $repo 最新版本..."
local resp_file="$TMP_DIR/gh_release.json"
local tag_line="" tag=""
# 【修复】GitHub API 同样走代理,避免 API 也被墙
if ! curl $CURL_OPTS "${GH_PROXY}${GH_API}/repos/${repo}/releases/latest" -o "$resp_file"; then
# 降级:尝试直连
warn "代理访问 GitHub API 失败,尝试直连..."
if ! curl $CURL_OPTS "${GH_API}/repos/${repo}/releases/latest" -o "$resp_file"; then
error "无法访问 GitHub API ($repo),请检查网络或更换 GH_PROXY"
fi
fi
tag_line=$(grep '"tag_name"' "$resp_file" | head -1 || true)
if [[ -z "$tag_line" ]]; then
error "API 返回中无 tag_name ($repo)"
fi
tag=$(echo "$tag_line" | sed -E 's/.*"v?([^"]+)".*/\1/')
if [[ -z "$tag" ]]; then
error "解析版本号失败 ($repo)"
fi
echo "$tag"
}
# ==================== 1. 获取版本号 ====================
if [[ -z "$DOCKER_VERSION" ]]; then DOCKER_VERSION=$(get_latest_docker_version); fi
if [[ -z "$DOCKER_VERSION" ]]; then error "Docker 版本号为空"; fi
info "Docker Engine: v${DOCKER_VERSION}"
if [[ -z "$COMPOSE_VERSION" ]]; then COMPOSE_VERSION=$(get_latest_gh_release "docker/compose"); fi
if [[ -z "$COMPOSE_VERSION" ]]; then error "Compose 版本号为空"; fi
info "Docker Compose: v${COMPOSE_VERSION}"
if [[ -z "$BUILDX_VERSION" ]]; then BUILDX_VERSION=$(get_latest_gh_release "docker/buildx"); fi
if [[ -z "$BUILDX_VERSION" ]]; then error "Buildx 版本号为空"; fi
info "Docker Buildx: v${BUILDX_VERSION}"
# ==================== 2. 安全停止旧组件 ====================
info "安全停止旧版 Docker..."
systemctl stop docker.socket 2>/dev/null || true
for i in $(seq 1 10); do
systemctl is-active docker.socket >/dev/null 2>&1 || break
sleep 1
done
systemctl stop docker.service 2>/dev/null || true
systemctl stop containerd.service 2>/dev/null || true
for i in $(seq 1 15); do
pgrep -x dockerd >/dev/null 2>&1 || break
sleep 1
done
if pgrep -x dockerd >/dev/null 2>&1; then
warn "dockerd 未退出,强制终止..."
pkill -9 -x dockerd 2>/dev/null || true
sleep 2
fi
systemctl disable docker.service 2>/dev/null || true
systemctl disable docker.socket 2>/dev/null || true
systemctl disable containerd.service 2>/dev/null || true
# 卸载所有冲突的 RPM 包 (兼容 yum/dnf)
PKGS_TO_REMOVE=$(rpm -qa | grep -iE '^docker|^podman|^containerd|^runc|^buildah|^skopeo' || true)
if [ -n "$PKGS_TO_REMOVE" ]; then
warn "发现以下冲突包,即将卸载:"
echo "$PKGS_TO_REMOVE"
if command -v dnf &> /dev/null; then
dnf remove -y $PKGS_TO_REMOVE
else
yum remove -y $PKGS_TO_REMOVE
fi
info "冲突 RPM 包卸载完成"
else
info "未发现冲突的 RPM 包,跳过卸载"
fi
# 清除残留的配置
rm -f /usr/local/bin/docker /usr/local/bin/dockerd /usr/local/bin/docker-init
rm -f /usr/local/bin/docker-proxy /usr/local/bin/containerd
rm -f /usr/local/bin/containerd-shim /usr/local/bin/containerd-shim-runc-v2
rm -f /usr/local/bin/ctr /usr/local/bin/runc
rm -f /etc/systemd/system/docker.service /etc/systemd/system/docker.socket
rm -rf "$CLI_PLUGIN_DIR"/*
systemctl daemon-reload
info "✅ 旧组件清理完成"
# ==================== 3. 下载安装 Docker Engine ====================
info "下载 Docker Engine v${DOCKER_VERSION}..."
DOWNLOAD_URL="${DOCKER_CE_MIRROR}/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz"
info "URL: $DOWNLOAD_URL"
if ! curl $CURL_OPTS "$DOWNLOAD_URL" -o "$TMP_DIR/docker.tgz"; then
error "Docker Engine 下载失败: $DOWNLOAD_URL"
fi
# 校验下载文件是否为有效 tar 包
if ! tar tzf "$TMP_DIR/docker.tgz" >/dev/null 2>&1; then
error "下载的文件不是有效的 tgz 包,可能版本号错误或镜像异常"
fi
info "解压安装..."
tar xzf "$TMP_DIR/docker.tgz" -C "$TMP_DIR"
cp "$TMP_DIR/docker/"* "$INSTALL_DIR/"
chmod +x "$INSTALL_DIR"/docker* "$INSTALL_DIR"/containerd* "$INSTALL_DIR"/runc 2>/dev/null || true
# ==================== 4. Systemd 服务 ====================
info "创建 Systemd 服务..."
cat > /etc/systemd/system/docker.service <<'UNIT'
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/local/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=5
Restart=always
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target
UNIT
cat > /etc/systemd/system/docker.socket <<'UNIT'
[Unit]
Description=Docker Socket for the API
[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
UNIT
systemctl daemon-reload
# ==================== 5. 用户组(零管道符)====================
if ! getent group docker >/dev/null 2>&1; then
info "创建 docker 用户组..."
groupadd docker
else
warn "docker 用户组已存在"
fi
CURRENT_USER="${SUDO_USER:-$USER}"
if [[ "$CURRENT_USER" != "root" ]]; then
DOCKER_GROUP_FOUND=false
for g in $(id -Gn "$CURRENT_USER"); do
if [[ "$g" == "docker" ]]; then
DOCKER_GROUP_FOUND=true
break
fi
done
if [[ "$DOCKER_GROUP_FOUND" != "true" ]]; then
info "将 $CURRENT_USER 加入 docker 组..."
usermod -aG docker "$CURRENT_USER"
warn "请重新登录使 docker 组权限生效"
fi
else
info "当前为 root,无需配置用户组"
fi
# ==================== 6. CLI 插件(原子写入)====================
install_plugin() {
local name="$1" url="$2"
local dest="$CLI_PLUGIN_DIR/$name"
local tmp_dest="$TMP_DIR/$name.tmp"
# 构造代理 URL
local proxy_url="${GH_PROXY}${url}"
info "下载 $name (via proxy)..."
if curl $CURL_OPTS -L "$proxy_url" -o "$tmp_dest"; then
if [[ -s "$tmp_dest" ]]; then
chmod +x "$tmp_dest"
mv -f "$tmp_dest" "$dest"
info "✅ $name 安装完成 (代理)"
return 0
fi
fi
# 降级1: 直连原始 URL
warn "代理下载失败,尝试直连..."
rm -f "$tmp_dest"
if curl $CURL_OPTS -L "$url" -o "$tmp_dest"; then
if [[ -s "$tmp_dest" ]]; then
chmod +x "$tmp_dest"
mv -f "$tmp_dest" "$dest"
info "✅ $name 安装完成 (直连)"
return 0
fi
fi
# 降级2: kkgithub 镜像
warn "直连失败,尝试 kkgithub 镜像..."
local kk_url="${url//github.com/kkgithub.com}"
rm -f "$tmp_dest"
if curl $CURL_OPTS -L "$kk_url" -o "$tmp_dest"; then
if [[ -s "$tmp_dest" ]]; then
chmod +x "$tmp_dest"
mv -f "$tmp_dest" "$dest"
info "✅ $name 安装完成 (kkgithub)"
return 0
fi
fi
warn "❌ $name 所有下载源均失败"
warn " 代理: $proxy_url"
warn " 直连: $url"
warn " KK: $kk_url"
warn " 请手动下载后放置到: $dest"
return 1
}
install_plugin "docker-compose" \
"${GH_RELEASES}/docker/compose/releases/download/v${COMPOSE_VERSION}/docker-compose-linux-${COMPOSE_ARCH}"
install_plugin "docker-buildx" \
"${GH_RELEASES}/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-${BUILDX_ARCH}" || warn "Buildx 安装失败,可手动放置到 $CLI_PLUGIN_DIR/docker-buildx"
# ==================== 7. 启动并等待就绪 ====================
info "启动 Docker..."
systemctl enable docker.socket
systemctl start docker.socket
systemctl enable docker.service
systemctl start docker.service
info "等待 Docker daemon 就绪..."
DOCKER_READY=false
for i in $(seq 1 30); do
if docker info >/dev/null 2>&1; then
DOCKER_READY=true
break
fi
sleep 1
done
if [[ "$DOCKER_READY" != "true" ]]; then
error "Docker daemon 30s 内未就绪: journalctl -xeu docker.service"
fi
info "✅ Docker daemon 已就绪"
# ==================== 8. 验证 ====================
info "========== 安装验证 =========="
echo "--- Docker ---"
docker version || error "docker 命令失败"
echo ""
echo "--- Compose ---"
docker compose version || warn "compose 不可用"
echo ""
echo "--- Buildx ---"
docker buildx version || warn "buildx 不可用"
echo ""
if systemctl is-active docker.service >/dev/null 2>&1; then
echo "✅ docker.service 运行中"
else
error "❌ docker.service 未运行"
fi
echo ""
if docker run --rm hello-world >/dev/null 2>&1; then
echo "✅ hello-world 测试通过"
else
warn "hello-world 拉取失败,建议配置镜像加速器"
fi
echo ""
info "=========================================="
info "🎉 Docker CE 部署完成!"
info " Engine: v${DOCKER_VERSION}"
info " Compose: v${COMPOSE_VERSION}"
info " Buildx: v${BUILDX_VERSION}"
info "=========================================="