介绍
在当今快速发展的开发环境中,容器化彻底改变了应用程序的构建、部署和管理方式。Docker 作为领先的容器化平台,允许开发人员和系统管理员将应用程序及其所有依赖项打包成名为容器的标准化单元。这些容器可以在不同环境中保持一致运行,从开发笔记本电脑到生产服务器。
如果您正在专用服务器上运行应用程序,使用 Docker 对它们进行容器化可以显著提高部署效率、资源利用率和可扩展性。本综合指南将引导您完成在专用服务器上容器化应用程序的整个过程,从初始设置到高级管理技术。
无论您是寻求简化工作流程的开发人员,还是旨在优化服务器资源的系统管理员,本指南都将为您提供在 TildaVPS 专用服务器上成功实施 Docker 所需的知识和实用步骤。
第 1 部分:理解 Docker 及其优势
什么是 Docker?
Docker 是一个开源平台,可自动化应用程序在轻量级、可移植容器内的部署。与模拟整个操作系统的传统虚拟化不同,Docker 容器共享主机系统的内核,并将应用程序进程彼此隔离,也与底层基础设施隔离。
解释: 将 Docker 容器视为软件的标准集装箱。正如集装箱通过提供一种标准的货物运输方式(无论货物内容如何)彻底改变了全球贸易一样,Docker 容器通过将应用程序及其依赖项打包成可在任何地方运行的独立单元来标准化软件部署。
技术细节: Docker 采用客户端-服务器架构,包含几个关键组件:
- Docker 守护进程 (dockerd):管理 Docker 容器的持久性进程
- Docker 客户端:用于与 Docker 交互的命令行界面
- Docker 镜像:用于创建容器的只读模板
- Docker 容器:Docker 镜像的可运行实例
- Docker 注册表:用于存储和分发 Docker 镜像的仓库
Docker 容器化应用程序的优势
在专用服务器上容器化您的应用程序具有众多优势:
-
跨环境一致性: Docker 确保您的应用程序在开发、测试和生产环境中以相同方式运行,从而消除“在我的机器上可以运行”的问题。
-
隔离性和安全性: 每个容器都独立运行,防止应用程序之间发生冲突,并提供额外的安全层。
-
资源效率: 容器共享主机操作系统内核,比传统虚拟机更有效地利用资源,使您可以在相同硬件上运行更多应用程序。
-
快速部署: Docker 支持快速应用程序部署和扩展,容器可在数秒内启动,而非数分钟。
-
版本控制和组件复用: Docker 镜像可以进行版本控制,允许您跟踪更改并在需要时回滚。组件可以在不同项目之间复用。
-
简化更新和回滚: 更新应用程序变得像拉取新镜像并重启容器一样简单。如果出现问题,您可以快速回滚到以前的版本。
-
微服务架构支持: Docker 有助于实现微服务架构,允许您将复杂的应用程序分解为更小、更易于管理的服务。
可视化元素: [图片:比较传统部署与 Docker 容器化的图表,展示 Docker 如何通过将应用程序及其依赖项打包来消除环境不一致性。]
何时在专用服务器上使用 Docker
Docker 在以下场景中特别有益:
- 微服务架构: 当将单体应用程序分解为更小、独立可部署的服务时
- 持续集成/持续部署 (CI/CD): 用于简化开发工作流程并自动化测试和部署
- 遗留应用程序迁移: 用于现代化和标准化旧应用程序的部署
- 开发和测试环境: 用于创建一致、可重现的开发和测试环境
- 多租户应用程序: 当为不同客户端运行同一应用程序的多个实例时
本节总结: Docker 提供了一种标准化打包和部署应用程序的方式,具有一致性、隔离性、效率和简化管理等优势。对于专用服务器用户而言,Docker 可以显著提高资源利用率和部署工作流程。
迷你常见问题:
Docker 和虚拟化是一回事吗?
不是,Docker 使用的是容器化技术,这与传统虚拟化不同。虚拟机模拟整个操作系统,而 Docker 容器共享主机系统的内核,只隔离应用程序进程,使其更轻量、更高效。
我可以在任何专用服务器上运行 Docker 吗?
Docker 可以在大多数运行 Linux 或 Windows Server 的现代专用服务器上运行。TildaVPS 专用服务器特别适合 Docker 部署,为容器化应用程序提供了所需的性能和可靠性。
第 2 部分:为 Docker 准备您的专用服务器
系统要求
在专用服务器上安装 Docker 之前,请确保您的系统满足以下要求:
适用于基于 Linux 的服务器:
- 64 位架构
- 内核版本 3.10 或更高(推荐 4.x 或更新版本)
- 至少 2GB RAM(生产环境推荐 4GB 以上)
- 足够的存储空间用于 Docker 镜像和容器
适用于基于 Windows 的服务器:
- Windows Server 2016 或更高版本
- 已启用 Hyper-V 功能
- 至少 4GB RAM
TildaVPS 专用服务器通常超出这些要求,为 Docker 部署提供了理想的基础。如果您不确定服务器规格,可以在 Linux 上使用以下命令进行检查:
# 检查内核版本
uname -r
# 检查系统架构
uname -m
# 检查可用内存
free -h
# 检查可用磁盘空间
df -h
选择合适的操作系统
尽管 Docker 可以在各种操作系统上运行,但 Linux 发行版通常因其对容器化技术的原生支持而更受 Docker 部署的青睐。
推荐用于 Docker 的 Linux 发行版:
- Ubuntu Server 20.04 LTS 或更新版本
- CentOS 8 或更新版本
- Debian 10 或更新版本
- RHEL 8 或更新版本
Ubuntu Server 特别适合 Docker,因为它拥有广泛的文档、定期更新和强大的社区支持。TildaVPS 为其专用服务器提供所有这些发行版,让您可以选择最适合您需求的发行版。
更新您的系统
在安装 Docker 之前,请确保您的系统是最新的:
适用于 Ubuntu/Debian:
sudo apt update
sudo apt upgrade -y
适用于 CentOS/RHEL:
sudo yum update -y
设置所需依赖项
Docker 需要某些软件包才能正常运行。安装这些依赖项:
适用于 Ubuntu/Debian:
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
适用于 CentOS/RHEL:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
配置防火墙规则
如果您的专用服务器上启用了防火墙,则需要对其进行配置以允许 Docker 流量:
适用于 UFW (Ubuntu):
# 允许 Docker 守护进程端口
sudo ufw allow 2375/tcp
sudo ufw allow 2376/tcp
# 根据需要允许容器端口
# 示例:允许 HTTP 和 HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
适用于 firewalld (CentOS/RHEL):
sudo firewall-cmd --permanent --zone=public --add-port=2375/tcp
sudo firewall-cmd --permanent --zone=public --add-port=2376/tcp
sudo firewall-cmd --permanent --zone=public --add-port=80/tcp
sudo firewall-cmd --permanent --zone=public --add-port=443/tcp
sudo firewall-cmd --reload
可视化元素: [表格:比较不同 Linux 发行版用于 Docker 部署,展示每个发行版的主要特性、优势和注意事项。]
设置 Docker 专用用户
出于安全原因,建议为 Docker 操作创建一个专用用户:
# 创建新用户
sudo adduser dockeruser
# 将用户添加到 sudo 组
sudo usermod -aG sudo dockeruser
# 切换到新用户
su - dockeruser
本节总结: 专用服务器的正确准备对于成功的 Docker 部署至关重要。请确保您的系统满足要求,选择合适的操作系统,更新您的系统,安装依赖项,配置防火墙规则,并为 Docker 操作设置专用用户。
迷你常见问题:
我需要为 Docker 禁用 SELinux 或 AppArmor 吗?
不需要,现代 Docker 版本与 SELinux 和 AppArmor 配合良好。建议保持这些安全功能启用并正确配置,而不是禁用它们。
我可以在虚拟专用服务器 (VPS) 而不是专用服务器上运行 Docker 吗?
是的,Docker 可以在 VPS 上运行,但 TildaVPS 的专用服务器由于有保证的资源且没有噪音邻居问题,可以提供更好的性能,特别是对于生产工作负载。
第 3 部分:安装和配置 Docker
安装 Docker 引擎
安装过程因操作系统的不同而略有差异。请按照以下分步说明进行特定发行版的安装:
Ubuntu/Debian 安装
- 添加 Docker 的官方 GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- 设置稳定版仓库:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 更新软件包索引并安装 Docker:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
- 验证安装:
sudo docker --version
CentOS/RHEL 安装
- 添加 Docker 仓库:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 安装 Docker:
sudo yum install -y docker-ce docker-ce-cli containerd.io
- 启动并启用 Docker 服务:
sudo systemctl start docker
sudo systemctl enable docker
- 验证安装:
sudo docker --version
安装后步骤
安装 Docker 后,完成这些重要的安装后步骤:
- 将您的用户添加到 docker 用户组,以便无需 sudo 即可运行 Docker 命令:
sudo usermod -aG docker $USER
- 注销并重新登录以使组更改生效,或者运行:
newgrp docker
- 验证 Docker 是否正常运行:
docker run hello-world
此命令会下载一个测试镜像并在容器中运行它。如果成功,它会打印一条确认消息,表明 Docker 已正确安装并正在运行。
配置 Docker 守护进程
可以配置 Docker 守护进程 (dockerd) 以自定义其行为。配置文件位于 /etc/docker/daemon.json
:
- 创建或编辑配置文件:
sudo nano /etc/docker/daemon.json
- 添加您的配置选项。以下是一个配置示例:
{
"data-root": "/var/lib/docker",
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"default-address-pools": [
{"base": "172.17.0.0/16", "size": 24}
],
"registry-mirrors": [],
"dns": ["8.8.8.8", "8.8.4.4"]
}
- 保存文件并重启 Docker 以应用更改:
sudo systemctl restart docker
安装 Docker Compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用以下命令安装它:
# 下载当前稳定版
sudo curl -L "https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 应用可执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
设置 Docker 注册表访问
如果您计划使用私有 Docker 注册表,则需要配置身份验证:
- 登录到您的 Docker 注册表:
docker login [registry-url]
- 对于 Docker Hub:
docker login
- 根据提示输入您的用户名和密码。
可视化元素: [图片:显示成功安装 Docker 和“docker run hello-world”命令输出的屏幕截图。]
配置存储驱动程序
Docker 使用存储驱动程序来管理镜像和容器的内容。对于大多数用例,推荐的存储驱动程序是 overlay2
:
- 检查您当前的存储驱动程序:
docker info | grep "Storage Driver"
- 要更改存储驱动程序,请编辑 daemon.json 文件:
sudo nano /etc/docker/daemon.json
- 添加或修改存储驱动程序设置:
{
"storage-driver": "overlay2"
}
- 保存并重启 Docker:
sudo systemctl restart docker
本节总结: 在专用服务器上安装和配置 Docker 涉及添加 Docker 仓库、安装 Docker 引擎、执行安装后步骤、配置 Docker 守护进程、安装 Docker Compose、设置注册表访问和配置存储驱动程序。遵循这些步骤可确保 Docker 环境正常运行。
迷你常见问题:
我应该使用 Docker 的最新版本还是稳定版?
对于专用服务器上的生产环境,建议使用 Docker 的稳定版本以确保可靠性。TildaVPS 服务器与这两个版本都兼容,但稳定版本提供更好的长期支持。
安装后如何更新 Docker?
要更新 Docker,请使用您系统的软件包管理器:
- 对于 Ubuntu/Debian:
sudo apt update && sudo apt upgrade docker-ce docker-ce-cli containerd.io
- 对于 CentOS/RHEL:
sudo yum update docker-ce docker-ce-cli containerd.io
第 4 部分:创建您的第一个 Docker 容器
理解 Docker 镜像和容器
在创建您的第一个容器之前,理解 Docker 镜像和容器之间的关系很重要:
- Docker 镜像: 一个只读模板,包含创建 Docker 容器的指令。它包括应用程序代码、运行时、库、环境变量和配置文件。
- Docker 容器: Docker 镜像的可运行实例。您可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。
将镜像视为面向对象编程中的一个类,而容器是该类的一个实例。
查找和拉取 Docker 镜像
Docker Hub 是 Docker 镜像的默认公共注册表。您可以使用 Docker CLI 或 Docker Hub 网站搜索镜像:
# 搜索镜像
docker search nginx
# 从 Docker Hub 拉取镜像
docker pull nginx:latest
latest
标签指的是镜像的最新版本。您可以通过使用不同的标签来指定特定版本:
# 拉取特定版本
docker pull nginx:1.21.6
运行您的第一个容器
让我们使用官方 Nginx 镜像创建一个简单的 Web 服务器容器:
# 运行一个 Nginx 容器
docker run --name my-nginx -p 80:80 -d nginx
此命令:
- 创建一个名为 "my-nginx" 的容器
- 将容器的 80 端口映射到主机的 80 端口
- 以分离模式 (-d) 运行容器
- 使用 nginx 镜像
现在您可以通过在 Web 浏览器中导航到服务器的 IP 地址来访问 Nginx 欢迎页面。
基本容器管理
以下是一些管理 Docker 容器的基本命令:
# 列出正在运行的容器
docker ps
# 列出所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop my-nginx
# 启动已停止的容器
docker start my-nginx
# 重启容器
docker restart my-nginx
# 删除容器(必须先停止)
docker rm my-nginx
# 强制删除容器(即使正在运行)
docker rm -f my-nginx
自定义容器配置
Docker 允许您自定义容器的各个方面:
环境变量
使用 -e
标志将环境变量传递给您的容器:
docker run -d --name my-app -e DB_HOST=localhost -e DB_PORT=5432 my-app-image
卷挂载
将主机目录挂载到容器目录以实现持久存储:
# 将主机目录挂载到容器目录
docker run -d --name my-nginx -p 80:80 -v /path/on/host:/usr/share/nginx/html nginx
网络配置
为容器通信创建自定义网络:
# 创建网络
docker network create my-network
# 在网络上运行容器
docker run -d --name my-app --network my-network my-app-image
使用 Dockerfile 创建自定义 Docker 镜像
Dockerfile 是一个包含构建 Docker 镜像指令的文本文件。让我们为 Node.js 应用程序创建一个简单的 Dockerfile:
- 为您的项目创建一个新目录:
mkdir node-app
cd node-app
- 创建一个简单的 Node.js 应用程序:
# 创建 package.json
echo '{
"name": "node-app",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.2"
}
}' > package.json
# 创建 server.js
echo 'const express = require("express");
const app = express();
const PORT = process.env.PORT || 3000;
app.get("/", (req, res) => {
res.send("Hello from Docker on TildaVPS!");
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});' > server.js
- 创建 Dockerfile:
echo 'FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]' > Dockerfile
- 构建 Docker 镜像:
docker build -t my-node-app .
- 从您的镜像运行容器:
docker run -d --name my-node-app -p 3000:3000 my-node-app
现在您可以通过在端口 3000 上导航到服务器的 IP 地址来访问您的 Node.js 应用程序。
可视化元素: [图片:显示 Docker 镜像构建过程的图表,从 Dockerfile 到运行中的容器,每个步骤都有插图。]
分步指南:使用 Docker 部署 Web 应用程序
让我们逐步完成容器化一个简单 Web 应用程序的整个过程:
-
准备您的应用程序代码
- 确保您的应用程序在本地可以工作
- 识别依赖项和要求
-
创建 Dockerfile
- 选择一个合适的基础镜像
- 复制应用程序文件
- 安装依赖项
- 配置入口点
-
构建 Docker 镜像
bashdocker build -t my-web-app:v1 .
-
在本地测试镜像
bashdocker run -d -p 8080:80 --name test-app my-web-app:v1
-
将镜像推送到注册表(可选)
bashdocker tag my-web-app:v1 username/my-web-app:v1 docker push username/my-web-app:v1
-
在您的生产服务器上部署容器
bashdocker run -d -p 80:80 --restart always --name production-app my-web-app:v1
-
设置监控和日志记录
bashdocker logs -f production-app
本节总结: 创建和管理 Docker 容器涉及理解镜像和容器、查找和拉取镜像、运行容器、使用基本命令管理它们、自定义配置、使用 Dockerfile 创建自定义镜像以及遵循分步部署过程。这些技能构成了在专用服务器上使用 Docker 的基础。
迷你常见问题:
如何访问运行中容器的日志?
您可以使用 docker logs
命令访问容器日志:
docker logs my-container-name
# 用于连续日志输出
docker logs -f my-container-name
我可以限制容器可以使用的资源吗?
是的,Docker 允许您限制 CPU、内存和其他资源:
# 将容器限制为 2 个 CPU 和 1GB 内存
docker run -d --name resource-limited-app --cpus=2 --memory=1g my-app-image
第 5 部分:管理 Docker 容器和镜像
高效的镜像管理
随着您使用 Docker,您会积累占用磁盘空间的镜像。以下是如何高效管理它们:
列出和检查镜像
# 列出所有镜像
docker images
# 获取有关镜像的详细信息
docker inspect nginx
# 显示镜像的历史记录
docker history nginx
删除未使用的镜像
# 删除特定镜像
docker rmi nginx:1.21.6
# 删除悬空镜像(未标记的镜像)
docker image prune
# 删除所有未使用的镜像
docker image prune -a
容器生命周期管理
理解容器生命周期有助于您有效地管理应用程序:
容器状态
容器可以处于以下状态之一:
- 已创建 (Created): 容器已创建但未启动
- 运行中 (Running): 容器正在运行,所有进程都处于活动状态
- 已暂停 (Paused): 容器进程已暂停
- 已停止 (Stopped): 容器进程已停止
- 已删除 (Deleted): 容器已移除且不再存在
管理容器生命周期
# 创建容器而不启动它
docker create --name my-container nginx
# 启动已创建的容器
docker start my-container
# 暂停运行中的容器
docker pause my-container
# 取消暂停已暂停的容器
docker unpause my-container
# 停止运行中的容器
docker stop my-container
# 移除容器
docker rm my-container
容器资源监控
监控容器资源使用情况对于性能优化至关重要:
# 显示运行中容器的状态
docker stats
# 显示特定容器的状态
docker stats container1 container2
# 以 JSON 格式获取一次性状态
docker stats --no-stream --format "{{json .}}" container1
如需更详细的监控,请考虑使用 cAdvisor、Prometheus 或 Grafana 等工具,它们本身也可以作为 Docker 容器部署。
自动化容器管理
自动重启策略
配置容器在系统重启或崩溃后自动重启:
# 始终重启容器
docker run -d --restart always --name my-app my-app-image
# 仅在失败时重启
docker run -d --restart on-failure --name my-app my-app-image
# 在失败时重启,并设置最大重试次数
docker run -d --restart on-failure:5 --name my-app my-app-image
健康检查
实施健康检查以监控容器健康状况:
docker run -d --name my-web-app \
--health-cmd="curl -f http://localhost/ || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
nginx
可视化元素: [表格:容器重启策略,包含描述、用例和每种策略的示例。]
使用 Docker 卷进行数据管理
Docker 卷为容器数据提供持久存储:
创建和管理卷
# 创建一个命名卷
docker volume create my-data
# 列出卷
docker volume ls
# 检查卷
docker volume inspect my-data
# 删除卷
docker volume rm my-data
# 删除所有未使用的卷
docker volume prune
在容器中使用卷
# 挂载命名卷
docker run -d --name my-db -v my-data:/var/lib/mysql mysql:8.0
# 挂载主机目录
docker run -d --name my-web -v /path/on/host:/usr/share/nginx/html nginx
备份和恢复容器数据
备份卷
# 创建一个备份容器,挂载卷并将其备份到 tar 文件
docker run --rm -v my-data:/source -v $(pwd):/backup alpine tar -czf /backup/my-data-backup.tar.gz -C /source .
恢复卷
# 创建一个新卷
docker volume create my-data-restored
# 从备份中恢复
docker run --rm -v my-data-restored:/target -v $(pwd):/backup alpine sh -c "tar -xzf /backup/my-data-backup.tar.gz -C /target"
本节总结: 有效的 Docker 容器和镜像管理包括理解镜像管理、容器生命周期、资源监控、自动化、使用卷进行数据管理以及备份/恢复过程。掌握这些方面可确保在专用服务器上高效运行容器化应用程序。
迷你常见问题:
如何减小 Docker 镜像的大小?
使用多阶段构建,最小化层数,使用 Alpine 等更小的基础镜像,并在创建它们的同一层中清理不必要的文件。
Docker 卷和绑定挂载有什么区别?
Docker 卷由 Docker 管理并存储在 Docker 的存储目录中,而绑定挂载将主机文件或目录映射到容器路径。卷通常是持久化数据的首选,因为它们更易于备份,并且不依赖于主机的目录结构。
第 6 部分:使用 Docker Compose 管理多容器应用程序
Docker Compose 简介
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件配置应用程序的服务、网络和卷,然后通过一个命令创建并启动所有服务。
安装 Docker Compose(如果尚未安装)
如果您尚未安装 Docker Compose,请按照以下步骤操作:
# 下载 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 应用可执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
创建 Docker Compose 文件
Docker Compose 文件(通常命名为 docker-compose.yml
)定义了应用程序的服务、网络和卷:
- 为您的项目创建一个新目录:
mkdir compose-demo
cd compose-demo
- 创建一个
docker-compose.yml
文件:
nano docker-compose.yml
- 添加以下内容,用于一个简单的带有数据库的 Web 应用程序:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./website:/usr/share/nginx/html
depends_on:
- app
networks:
- frontend
- backend
app:
build: ./app
environment:
- DB_HOST=db
- DB_USER=myuser
- DB_PASSWORD=mypassword
- DB_NAME=mydb
depends_on:
- db
networks:
- backend
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=mydb
- MYSQL_USER=myuser
- MYSQL_PASSWORD=mypassword
volumes:
- db-data:/var/lib/mysql
networks:
- backend
networks:
frontend:
backend:
volumes:
db-data:
Docker Compose 基本命令
# 以分离模式启动服务
docker-compose up -d
# 查看运行中的服务
docker-compose ps
# 查看所有服务的日志
docker-compose logs
# 查看特定服务的日志
docker-compose logs app
# 停止服务
docker-compose stop
# 停止并删除容器、网络和卷
docker-compose down
# 停止并删除容器、网络、卷和镜像
docker-compose down --rmi all --volumes
分步指南:使用 Docker Compose 部署 LAMP 堆栈
让我们使用 Docker Compose 创建一个完整的 LAMP(Linux、Apache、MySQL、PHP)堆栈:
- 创建一个项目目录:
mkdir lamp-docker
cd lamp-docker
- 创建必要的子目录:
mkdir -p www/html
mkdir mysql
- 创建一个简单的 PHP 文件来测试设置:
echo '<?php
phpinfo();
?>' > www/html/index.php
- 创建 Docker Compose 文件:
nano docker-compose.yml
- 添加以下内容:
version: '3.8'
services:
webserver:
image: php:8.0-apache
ports:
- "80:80"
volumes:
- ./www/html:/var/www/html
depends_on:
- db
networks:
- lamp-network
db:
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: lamp_db
MYSQL_USER: lamp_user
MYSQL_PASSWORD: lamp_password
volumes:
- ./mysql:/var/lib/mysql
networks:
- lamp-network
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8080:80"
environment:
PMA_HOST: db
PMA_PORT: 3306
depends_on:
- db
networks:
- lamp-network
networks:
lamp-network:
- 启动 LAMP 堆栈:
docker-compose up -d
- 访问您的应用程序:
- PHP 应用程序:http://your-server-ip
- phpMyAdmin:http://your-server-ip:8080(使用 lamp_user/lamp_password 登录)
可视化元素: [图片:显示使用 Docker Compose 构建 LAMP 堆栈的架构图,说明容器如何相互连接。]
环境变量和秘密管理
对于生产环境,安全管理敏感信息非常重要:
使用 .env 文件
- 创建
.env
文件:
nano .env
- 添加您的环境变量:
MYSQL_ROOT_PASSWORD=securepassword
MYSQL_DATABASE=production_db
MYSQL_USER=prod_user
MYSQL_PASSWORD=prod_password
- 在您的 docker-compose.yml 中引用这些变量:
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
使用 Docker Secrets(适用于 Docker Swarm)
如果您使用 Docker Swarm,可以使用 Docker Secrets 来处理敏感数据:
services:
db:
image: mysql:8.0
secrets:
- db_root_password
- db_password
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_root_password:
file: ./secrets/db_root_password.txt
db_password:
file: ./secrets/db_password.txt
本节总结: Docker Compose 通过允许您在单个 YAML 文件中定义整个堆栈来简化多容器应用程序的部署和管理。通过 Docker Compose,您可以轻松部署像 LAMP 堆栈这样的复杂应用程序,管理环境变量和秘密,并使用简单的命令控制所有容器的生命周期。
迷你常见问题
我可以在生产环境中使用 Docker Compose 吗?
是的,Docker Compose 可以用于生产环境,特别是对于小型部署。对于更大、更复杂的部署,您可能会考虑 Docker Swarm 或 Kubernetes 以获得额外的编排功能。TildaVPS 专用服务器提供了生产 Docker Compose 部署所需的性能。
如何更新 Docker Compose 中定义的服务?
要更新服务,请修改您的 docker-compose.yml 文件,然后运行:
docker-compose up -d --build
此命令在必要时重建镜像,并重新创建带有更改的容器,同时保留卷和数据。
第 7 部分:Docker 安全最佳实践
理解 Docker 安全风险
虽然 Docker 在容器和主机系统之间提供了隔离,但仍有几个安全考虑需要解决:
- 容器逃逸: 如果容器受到威胁,攻击者可能会尝试逃逸容器并访问主机系统。
- 镜像漏洞: Docker 镜像可能包含易受攻击的软件或恶意代码。
- 过度特权: 以不必要特权运行的容器会带来安全风险。
- 不安全配置: 配置错误的容器可能暴露敏感数据或服务。
- 资源滥用: 如果没有适当的限制,容器可能会消耗过多资源,导致拒绝服务。
保护 Docker 守护进程
Docker 守护进程是一个关键组件,需要进行保护:
- 使用 TLS 身份验证:
# 生成 CA、服务器和客户端证书
mkdir -p ~/.docker/certs
cd ~/.docker/certs
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
- 配置 Docker 以使用 TLS:
编辑
/etc/docker/daemon.json
:
{
"tls": true,
"tlscacert": "/root/.docker/certs/ca.pem",
"tlscert": "/root/.docker/certs/server-cert.pem",
"tlskey": "/root/.docker/certs/server-key.pem",
"tlsverify": true
}
- 重启 Docker:
sudo systemctl restart docker
镜像安全
确保 Docker 镜像的安全性:
-
使用官方或验证镜像: 始终优先选择 Docker Hub 上的官方镜像或经过验证的发布者。
-
扫描镜像漏洞:
# 安装 Docker Scan
docker scan --version
# 扫描镜像
docker scan nginx:latest
- 使用最小基础镜像: 使用 Alpine 或 distroless 镜像以减少攻击面:
FROM alpine:3.16
# 而不是
# FROM ubuntu:22.04
- 保持镜像更新: 定期更新您的镜像以包含安全补丁:
docker pull nginx:latest
- 实施多阶段构建:
# 构建阶段
FROM node:16 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
容器运行时安全
保护运行中的容器:
- 以非 Root 用户运行容器:
# 在您的 Dockerfile 中添加非 root 用户
RUN addgroup -g 1000 appuser && \
adduser -u 1000 -G appuser -s /bin/sh -D appuser
USER appuser
- 使用只读文件系统:
docker run --read-only --tmpfs /tmp nginx
- 限制容器能力:
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
- 设置资源限制:
docker run --memory=512m --cpus=0.5 nginx
- 使用安全选项:
docker run --security-opt=no-new-privileges nginx
可视化元素: [表格:Docker 安全选项,包含描述、示例以及不同类型应用程序的推荐设置。]
网络安全
保护容器网络:
- 使用自定义桥接网络:
# 创建自定义网络
docker network create --driver bridge secure-network
# 在此网络上运行容器
docker run --network secure-network --name app1 my-app
docker run --network secure-network --name db mysql
- 限制外部访问: 仅暴露必要的端口:
# 仅暴露给 localhost
docker run -p 127.0.0.1:80:80 nginx
- 使用网络策略: 如果使用 Kubernetes 或 Docker Swarm,实施网络策略以控制容器之间的流量。
秘密管理
安全管理敏感数据:
- 使用环境变量文件:
# 创建一个 env 文件
echo "DB_PASSWORD=securepassword" > .env
# 在 Docker run 中使用它
docker run --env-file .env my-app
- 将秘密作为文件挂载:
# 创建一个 secrets 目录
mkdir -p secrets
echo "securepassword" > secrets/db_password
# 以只读文件形式挂载
docker run -v $(pwd)/secrets/db_password:/run/secrets/db_password:ro my-app
- 使用 Docker Secrets(Swarm 模式):
# 创建一个秘密
echo "securepassword" | docker secret create db_password -
# 在服务中使用秘密
docker service create --name my-app --secret db_password my-app
监控和审计
实施监控和审计以确保安全:
- 启用 Docker 审计日志: 配置 Linux 审计系统以监控 Docker:
sudo auditctl -w /usr/bin/docker -p rwxa
- 使用容器监控工具: 部署 Prometheus 和 Grafana 等监控解决方案:
# 运行 Prometheus
docker run -d -p 9090:9090 --name prometheus prom/prometheus
# 运行 Grafana
docker run -d -p 3000:3000 --name grafana grafana/grafana
- 实施运行时安全监控: 考虑使用 Falco 等工具进行运行时安全监控:
docker run -d --name falco --privileged -v /var/run/docker.sock:/var/run/docker.sock falcosecurity/falco
分步指南:实施安全的 Docker 环境
- 将 Docker 更新到最新版本
sudo apt update
sudo apt upgrade docker-ce docker-ce-cli containerd.io
- 为 Docker 操作创建一个专用用户
sudo adduser dockeruser
sudo usermod -aG docker dockeruser
- 配置 Docker 守护进程安全性
编辑
/etc/docker/daemon.json
:
{
"icc": false,
"userns-remap": "default",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"no-new-privileges": true
}
- 重启 Docker
sudo systemctl restart docker
- 创建安全的 Docker 网络
docker network create --driver bridge secure-network
- 在您的工作流程中实施镜像扫描
# 使用 Trivy 示例
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image nginx:latest
- 设置监控
# 运行 cAdvisor 进行容器监控
docker run -d --name cadvisor \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
gcr.io/cadvisor/cadvisor:latest
本节总结: Docker 安全是一个多层方法,涉及保护 Docker 守护进程、镜像、容器、网络和敏感数据。通过实施最佳实践,如以非 root 用户运行容器、使用最小基础镜像、限制能力、设置资源限制以及实施适当的监控,您可以显著增强专用服务器上 Docker 环境的安全性。
迷你常见问题:
Docker 默认安全吗?
Docker 默认提供一些安全功能,但真正安全的 Docker 环境需要额外的配置和最佳实践实施。TildaVPS 专用服务器提供了实施这些安全措施的灵活性。
我应该多久更新一次 Docker 镜像?
您应该定期更新您的 Docker 镜像,最好作为自动化 CI/CD 流水线的一部分。至少每月更新一次镜像以包含安全补丁,或者在宣布关键漏洞时立即更新。
结论
在您的专用服务器上容器化应用程序提供了诸多好处,从改进的资源利用率和部署一致性到增强的可扩展性和隔离性。在本指南中,我们涵盖了在您的专用服务器上实施 Docker 的整个过程:
- 理解 Docker 及其对服务器环境的优势
- 准备您的专用服务器,选择正确的操作系统和配置
- 安装和配置 Docker 以获得最佳性能
- 创建和管理 Docker 容器 以运行您的应用程序
- 使用 Docker Compose 管理多容器应用程序
- 实施安全最佳实践 以保护您的 Docker 环境
通过遵循本指南中概述的循序渐进的说明和最佳实践,您可以成功地在您的 TildaVPS 专用服务器上容器化您的应用程序,从而创建更高效、可扩展和易于管理的基础设施。
Docker 容器化对于 TildaVPS 专用服务器用户尤为重要,因为它允许您最大限度地利用服务器硬件的性能和能力。借助 Docker,您可以在一台服务器上运行多个隔离的应用程序,实现一致的开发和部署工作流程,并根据需要轻松扩展您的应用程序。
无论您是运行高流量网站、复杂的微服务架构,还是开发环境,Docker 都提供了满足您需求的工具和灵活性。立即开始在您的 TildaVPS 专用服务器上实施 Docker,体验现代容器化技术的优势。
行动号召: 准备好容器化您的应用程序了吗?TildaVPS 提供高性能专用服务器,非常适合 Docker 部署。访问 TildaVPS 的专用服务器页面 探索服务器选项,或联系他们的支持团队,根据您的特定 Docker 工作负载要求获取个性化建议。
常见问题 (FAQ)
Docker 和传统虚拟化有什么区别?
传统虚拟化(如 VMware 或 VirtualBox)创建带有自己操作系统的完整虚拟机,这需要大量资源。Docker 使用容器化技术,它共享主机操作系统的内核,只隔离应用程序进程。这使得 Docker 容器比传统虚拟机更轻量、启动更快、资源效率更高。在 TildaVPS 专用服务器上,这意味着您可以使用相同的硬件运行比虚拟机更多的 Docker 容器。
我可以在 Windows Server 上运行 Docker 吗?
是的,Docker 可用于 Windows Server 2016 及更高版本。Windows Server 可以同时运行 Windows 和 Linux 容器(后者通过轻量级 Linux VM)。然而,由于更好的性能和原生支持,Linux 通常更受 Docker 部署的青睐。TildaVPS 提供 Windows 和 Linux 专用服务器,让您可以选择最适合您 Docker 需求的平台。
如何将我现有的应用程序迁移到 Docker?
将现有应用程序迁移到 Docker 涉及几个步骤:分析应用程序的依赖项,创建定义环境的 Dockerfile,构建 Docker 镜像,测试容器化应用程序,然后将其部署到生产环境。该过程因应用程序类型而异,但通常遵循以下步骤:
- 识别所有依赖项和运行时要求
- 创建 Dockerfile 以复制环境
- 在本地构建和测试 Docker 镜像
- 调整配置以适应容器化操作
- 使用 Docker 卷设置持久存储
- 将容器化应用程序部署到您的生产服务器
运行 Docker 的资源要求是什么?
Docker 本身开销极小,但您需要考虑容器化应用程序所需的资源。对于专用服务器上的生产环境,我们建议:
- CPU:至少 2 核(多容器工作负载需要更多)
- 内存:最低 4GB(生产环境推荐 8GB 以上)
- 存储:20GB+ 用于 Docker 引擎和镜像
- 网络:标准以太网连接(推荐 1Gbps) TildaVPS 专用服务器超出这些要求,为 Docker 部署提供了充足的资源。
如何处理 Docker 的数据库持久性?
Docker 中的数据库持久性通常通过卷来管理。以下是设置方法:
- 创建一个命名卷:
docker volume create db-data
- 使用该卷运行您的数据库容器:
docker run -d --name mysql -v db-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql:8.0
- 要进行备份,请使用:
docker run --rm -v db-data:/source -v $(pwd):/backup alpine tar -czf /backup/db-backup.tar.gz -C /source .
这确保即使容器被移除或替换,您的数据也能持久保存。
我可以使用 Docker 处理生产工作负载吗?
当然可以。Docker 广泛用于生产环境,从小型应用程序到大规模微服务架构。对于生产用途,请考虑以下最佳实践:
- 使用特定的镜像标签而不是“latest”
- 为容器实施健康检查
- 设置适当的监控和日志记录
- 使用 Docker Compose 或 Docker Swarm 或 Kubernetes 等编排工具
- 实施安全最佳实践
- 为卷设置自动化备份
- 为您的自定义镜像使用注册表
TildaVPS 专用服务器提供生产 Docker 工作负载所需的稳定性和性能。
如何在不停机的情况下更新 Docker 容器?
为了以最小或不停机的方式更新容器,您可以使用以下方法:
- 蓝绿部署 (Blue-Green Deployment): 新容器与旧容器并行运行,一旦新容器准备就绪,则切换流量。
# 拉取新镜像
docker pull myapp:v2
# 在不同端口运行新容器
docker run -d --name myapp-v2 -p 8081:80 myapp:v2
# 测试新容器
# 更新负载均衡器指向新容器
# 停止旧容器
docker stop myapp-v1
- 使用 Docker Swarm 或 Kubernetes: 这些编排工具会自动处理滚动更新。
监控 Docker 容器的最佳方法是什么?
有几个工具可以帮助监控 Docker 容器:
- Docker 内置工具:
docker stats
和docker events
- cAdvisor: 提供容器特定的性能指标
- Prometheus + Grafana: 用于指标收集和可视化的强大组合
- ELK Stack: 用于日志聚合和分析
- Portainer: 一个用于 Docker 管理和监控的 Web UI
要在您的 TildaVPS 专用服务器上实现全面的监控解决方案,请考虑在容器中设置 Prometheus 和 Grafana:
# 为监控创建一个网络
docker network create monitoring
# 运行 Prometheus
docker run -d --name prometheus \
--network monitoring \
-p 9090:9090 \
-v prometheus-data:/prometheus \
prom/prometheus
# 运行 Grafana
docker run -d --name grafana \
--network monitoring \
-p 3000:3000 \
-v grafana-data:/var/lib/grafana \
grafana/grafana
关键要点
- Docker 容器化为专用服务器环境提供了显著优势,包括改进的资源利用率、部署一致性和应用程序隔离。
- 正确准备专用服务器对于成功的 Docker 实施至关重要,包括选择正确的操作系统和配置系统设置。
- Docker Compose 简化了多容器应用程序的部署和管理,使得在单个服务器上运行复杂堆栈变得更加容易。
- 在实施 Docker 时,安全性应作为优先事项,最佳实践包括以非 root 用户运行容器、使用最小基础镜像和实施适当的监控。
- Docker 卷为容器化应用程序提供持久存储,确保数据在容器生命周期中的持久性。
- 定期维护,包括镜像更新和安全扫描,对于健康的 Docker 环境至关重要。
术语表
- 容器 (Container):一个轻量级、独立、可执行的软件包,包含运行软件所需的一切。
- Docker 守护进程 (Docker Daemon):在系统上管理 Docker 容器的后台服务。
- Docker Hub:一个基于云的 Docker 镜像注册表服务。
- Docker 镜像 (Docker Image):用于创建 Docker 容器的只读模板。
- Dockerfile:一个包含构建 Docker 镜像指令的文本文件。
- Docker Compose:一个用于定义和运行多容器 Docker 应用程序的工具。
- 卷 (Volume):Docker 容器的持久数据存储机制。
- 注册表/仓库 (Registry):用于存储和分发 Docker 镜像的仓库。
- 层 (Layer):对镜像的修改,由 Dockerfile 中的指令表示。层在构建过程中被缓存以提高效率。
- 编排 (Orchestration):容器的自动化安排、协调和管理,通常使用 Docker Swarm 或 Kubernetes 等工具。
- 桥接网络 (Bridge Network):Docker 容器的默认网络驱动程序,允许同一主机上的容器进行通信。
- 绑定挂载 (Bind Mount):将主机文件或目录映射到容器文件或目录。
- Docker Swarm:Docker 的原生集群和编排解决方案。
- 容器生命周期 (Container Lifecycle):容器可以经历的各种状态,从创建到删除。
- Docker 套接字 (Docker Socket):Docker 守护进程默认监听的 Unix 套接字。
- 多阶段构建 (Multi-stage Build):一种 Dockerfile 模式,使用多个 FROM 语句来优化镜像大小和安全性。
- 健康检查 (Health Check):Docker 运行的命令,用于确定容器是否健康。
- Docker 上下文 (Docker Context):在构建过程中发送到 Docker 守护进程的文件和目录集。