部署新的 Ubuntu Server 服务 时,常见的第一步初始化操作之一
系统更新与基础工具
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y ca-certificates curl gnupg git ufw
命令解释:
sudo:
调用 superuser do,让后面那条命令以 root 权限运行。APT 需要修改系统文件,因此必须加 sudo
apt-get :
Debian 系发行版的老牌包管理工具,负责下载、安装、升级、卸载软件包
update:
告诉 apt-get
只去 同步 本地软件包索引(/var/lib/apt/lists
)与远程仓库的最新信息,不会实际安装或升级任何包
&&:
两个 &
连用时表示 逻辑与 的条件控制:仅当前面的命令返回码为 0(成功)时才执行后面的命令
upgrade:
根据刚才 update
得到的最新软件包列表,升级 系统中已安装且存在更新版本的软件包
-y:
-
表示短选项前缀y
代表 “yes”,告诉apt-get
对所有交互式提示自动回答 “Yes”,实现无人值守升级
install:
指定子命令:告诉 apt-get,接下来的参数是要安装的软件包名
ca-certificates:
各大证书颁发机构的根证书,系统用它校验 HTTPS 等 TLS 连接
curl:
命令行下载工具,支持 HTTP(S)、FTP、SFTP 等多种协议
gnupg:
用于加密、签名、验证文件或软件包,常用于添加软件源的密钥
git:
分布式版本控制系统
ufw(Uncomplicated Firewall):
简化的 iptables 前端,用于配置 Linux 防火墙规则
查看当前 UFW 防火墙规则(已开放的端口/服务)
sudo ufw status numbered
status
:
告诉 ufw “列出当前防火墙状态及所有规则”
numbered
:
要求 ufw 在每条规则前加上 序号(如 [ 1]、[ 2]),方便后续用 sudo ufw delete <序号>
,精确删除或调整规则。
当前 Linux 系统处于哪个时区:
timedatectl
以 root 权限创建 /etc/apt/keyrings
目录,并设置权限为 0755
sudo install -m 0755 -d /etc/apt/keyrings
/etc/apt/keyrings
系统级目录,普通用户没有权限创建或修改,所以用sudo,这个目录用于存放 GPG 公钥文件,以便 apt
验证软件包签名
install
一个 GNU coreutils 命令,用于复制文件并设置属性,也可以用于创建目录
-m 0755
作用:设置 权限模式(mode)。
解释:
0755
是 八进制权限表示法。对应权限:
所有者(root):
rwx
(读、写、执行)组用户:
r-x
(读、执行)其他用户:
r-x
(读、执行)
目的:确保目录对所有用户可读、可执行,但只有 root 可修改
-d
告诉 install
创建目录,而不是复制文件。等价于:mkdir -p
,但 install
可以一次性设置权限
以静默且跟随重定向的方式下载 Docker 的 GPG 公钥,立即用 root 权限把它转换成二进制格式,保存到 apt 专用密钥目录,供后续验证 Docker 软件包签名使用
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
curl:
发起 HTTP/HTTPS 请求并把响应内容输出到标准输出的命令行工具。这里用来“下载”远端文件
-f
--fail
的缩写。
如果 HTTP 状态码 ≥ 400,curl 会静默地返回非零退出码,不把错误页面内容送进管道。避免把 404/503 的 HTML 当成 GPG 密钥
-s
--silent
的缩写。
关闭进度条与错误信息(仍会把数据输出到标准输出)。让脚本更干净。
-S
--show-error
。
与 -s
搭配使用:当发生错误时仍然把错误信息打印到 stderr,方便调试。既安静又不完全“哑巴”。
-L
--location
。
如果服务器返回 30x 重定向,curl 会自动跟随跳转到最终地址。Docker 的 CDN 常常重定向,必须有它。
https://download.docker.com/linux/ubuntu/gpg
远端 URL,Docker 官方为 Ubuntu 发行的 ASCII-armored GPG 公钥文件。
|
管道符,把 curl 的标准输出直接接到后面命令的标准输入,不在磁盘上留下临时文件。
gpg
GnuPG 工具,用来处理 OpenPGP 密钥。这里只做格式转换,并不做签名验证。
--dearmor
“de-armor” 的缩写。
把 ASCII-armor(纯文本)格式的公钥转换成 二进制 GPG 密钥环格式(.gpg
),体积更小、解析更快。
-o /etc/apt/keyrings/docker.gpg
--output
的缩写。指定输出文件路径。
文件最终权限由 sudo 的 umask 决定,通常 0644,所有者可写,其余只读。这个路径正是前面 install -m 0755 -d /etc/apt/keyrings
创建好的目录
umask :
是“权限反码”,它告诉系统“创建文件/目录时不要给哪些位”。
sudo
的 umask 就是 root 账户当前生效的那个 umask 值,它决定了刚生成的 /etc/apt/keyrings/docker.gpg
最终权限里“缺掉”哪些 1。
root 身份给 Docker 的 GPG 密钥文件添加‘所有人可读’权限,确保 APT 在验证签名时无论以什么身份都能读取该密钥。
sudo chmod a+r /etc/apt/keyrings/docker.gpg
chmod
change mode 的缩写,用来 更改文件或目录的权限位(mode bits)。
支持两种写法:数字法(如 644)和符号法(如 a+r)
a+r:
符号法权限表达式,拆成两段理解:
a
代表 all 所有身份:
u(user 所有者) g(group 组) o(others 其他人) a 就是 u+g+o 的并集。+r
表示 增加读(read)权限:
把 r 位设为 1,其它位保持不动。
综合效果:给“所有者、组、其他人”同时加上读权限,写与执行位原样不变
把一条带正确架构、指定验证密钥、指向当前 Ubuntu 版本代号、只取稳定版的 Docker 官方源,写入独立列表文件,供后续 apt update 使用。
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release; echo $VERSION_CODENAME) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
echo
把后面跟的字符串原样写到标准输出,供后续命令接收。
引号块整体
"deb [arch=...] https://... ... stable"
这是一整行 APT 源记录,将来会被写进 /etc/apt/sources.list.d/docker.list
。
双引号允许内部 $(...)
被 Bash 先展开。
deb
APT 源记录的开头关键字,表示“二进制软件包仓库”。(如果是源码,用 deb-src
。)
[arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]:
方括号选项段,APT 2.1.5 以后支持,用来给这条源加“修饰符”。
内部两项:
arch=$(dpkg --print-architecture)
只在这条源里下载当前系统硬件架构的包,防止混杂 i386/amd64/arm64 等。
dpkg --print-architecture
会输出例如amd64
、arm64
。
命令替换$(...)
先执行,再把结果嵌入字符串。signed-by=/etc/apt/keyrings/docker.gpg
告诉 APT 只用指定的密钥文件验证此仓库签名,避免与其它仓库密钥混淆。
正是前面gpg --dearmor
生成的那一份。
https://download.docker.com/linux/ubuntu
Docker 官方提供的仓库根地址。
$(. /etc/os-release; echo $VERSION_CODENAME)
命令替换,动态获取当前 Ubuntu 版本的代号(如 jammy
、focal
)。
步骤:
点命令
. /etc/os-release
把系统版本信息文件“source”进当前 Shell,定义变量。然后
echo $VERSION_CODENAME
取出代号。
结果嵌入后形如jammy
。
stable
Docker 仓库的**组件(component)**名称,对应“稳定版”频道。同一仓库还可有 test
、nightly
,但这里只启用 stable
。
|
管道,把 echo 产生的一行源记录文本送给后面命令的标准输入。
tee
“T 形接头”工具:把 stdin 内容同时写屏和写文件。这里用 sudo tee 就能让普通用户把内容写进受保护的文件。
/etc/apt/sources.list.d/docker.list
目标文件,APT 会自动扫描 *.list
文件里每一行作为额外源。
单独放文件的好处:卸载或变更时只需删除/替换这一个文件,不动主 sources.list
。
> /dev/null
把 tee 本来要输出到屏幕的内容重定向进黑洞,使命令行干净。
因为我们只关心写文件,不需要再看一遍源字符串。
用 root 权限一次性自动安装 Docker 社区版守护进程、客户端、底层容器运行时 containerd,以及官方提供的构建插件 buildx 和编排插件 compose,全程无需人工确认。
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker-ce
Docker Community Edition 的主守护进程与客户端合体包。包含 dockerd
(守护进程)与 docker
(CLI),是运行容器的核心。
docker-ce-cli
仅包含 Docker CLI 可执行文件(/usr/bin/docker
)。
如果另一台机器只想装客户端远程连接,可以只装这个包;这里与 docker-ce
同时装,确保版本一致。
containerd.io
Docker 官方打包的 containerd 独立包。
containerd 是真正管理容器生命周期(拉镜像、创建容器、管理底层快照)的守护进程,Docker 公司把它拆出来方便其它项目(如 Kubernetes)直接依赖。
docker-buildx-plugin
官方提供的 CLI 插件包,安装后 docker buildx
命令可用。
buildx 支持多平台构建、跨架构镜像、BuildKit 全部特性,已成为现代镜像构建的标准工具。
docker-compose-plugin
官方提供的 CLI 插件包,安装后 docker compose
(注意无连字符)命令可用。
它是新一代 Compose(基于 Go 重写),与旧版 Python docker-compose
兼容,但集成在 Docker CLI 插件体系内,性能更好、维护更活跃。
root 权限把 Docker 服务设为开机自启,立即启动它,使容器引擎立即可用。
sudo systemctl enable --now docker
systemctl
systemd 的主命令行工具,用于 控制与查询系统服务(units)。
enable
子命令:把指定服务设为“开机自启”。
实际动作:在 /etc/systemd/system/*.wants/
目录里创建指向 docker.service
的软链接。
--now
一个 快捷选项,含义是“立即同时 start(启动)”该服务,相当于额外再执行一次 systemctl start docker
。不加 --now
的话,仅仅设置开机自启,当前会话不会启动。
docker
服务单元名(省略了后缀 .service
,systemd 会自动补全)。
对应文件通常是 /lib/systemd/system/docker.service
,由 docker-ce
包提供。
用 root 权限,根据当前目录下的 docker-compose.yml 文件,一次性预先拉取所有所需镜像,但不启动容器
sudo docker compose pull
docker
Docker CLI 可执行文件(/usr/bin/docker
)。
注意:这里用的是 新版插件形式 的 docker compose
(空格,不是旧版的 docker-compose
连字符)
compose
Docker CLI 的 官方插件(docker-compose-plugin
包提供)。
把 compose
子命令挂进 docker
,实现与 Docker Compose 相同的功能
pull
docker compose
的子命令:
仅下载(拉取) docker-compose.yml
里定义的所有镜像,不创建/启动容器。相当于提前缓存镜像,后续 docker compose up
能直接启动而无需再下载
用 root 权限,根据 docker-compose.yml 的定义,一次性创建并启动所有服务容器,随后转入后台运行,终端可继续他用
sudo docker compose up -d
up
docker compose
的核心子命令:
读取当前目录下的
docker-compose.yml
(及可选docker-compose.override.yml
);根据定义 创建网络、卷、服务容器;
如果镜像本地不存在,会自动先拉取;
默认把各服务的 日志前台聚合输出(除非加
-d
)
-d
--detach
的缩写。
作用:让容器在 后台运行(detached mode),命令行立即返回,日志不再直接刷屏输出。
不加 -d
时,日志会占住终端,按 Ctrl+C
会停止并移除容器。
用 root 权限查看当前 docker-compose 项目里所有服务容器的运行状态摘要。
sudo docker compose ps
ps
docker compose
的子命令:
列出 当前项目(即当前目录下 docker-compose.yml
所定义的所有服务)的 容器运行状态。
输出字段通常包括:
服务名(NAME)
容器实际运行命令(COMMAND)
当前状态(STATUS:Up / Exit / Restarting …)
端口映射(PORTS)
仅显示属于该项目的容器,不会列出系统里其它无关容器。