文章列表
9 分钟阅读

Docker 安装与使用教程:从零部署第一个容器服务


系列:容器部署基础

第 1 / 10 篇

  1. Docker 安装与使用教程:从零部署第一个容器服务
  2. Dockerfile 入门:构建自己的应用镜像
  3. Docker Compose 使用指南:管理多容器服务
  4. Docker 数据卷与备份:数据库容器怎么保护数据
  5. Docker 网络与端口映射:容器之间怎么通信
  6. Docker 日志和排障:logs、exec、inspect、stats
  7. 用 Docker 部署一个 Python Web 项目
  8. Nginx 反向代理入门:静态文件、HTTPS 和 Web 服务转发
  9. HTTPS 和证书部署指南:Let’s Encrypt、Cloudflare、Nginx 怎么配
  10. Docker 生产环境部署注意事项:镜像、日志、数据卷和健康检查

背景

部署一个 Web 服务、数据库、监控面板或个人项目时,传统方式通常需要手动安装运行环境、配置依赖版本、管理后台进程。不同项目之间还容易产生端口、依赖库和运行环境冲突。

Docker 将应用及其依赖打包成可运行的容器。你可以把它理解为一种更轻量、可重复、可迁移的部署方式:

镜像(Image) :应用的只读模板
容器(Container) :由镜像启动的运行实例
数据卷(Volume) :独立于容器生命周期的持久化数据
网络(Network) :让多个容器能够互相访问
Compose :用一个 YAML 文件管理多个容器

本文以 Debian / Ubuntu 服务器为例,使用 Docker 官方 APT 仓库安装 Docker Engine,并通过 Nginx 和 Docker Compose 演示最常见的使用方式。

本文的命令适合开发机和个人服务器。生产环境还需要额外考虑域名、HTTPS、反向代理、备份、监控、防火墙和镜像更新策略。

步骤

1. 安装前检查系统信息

先确认当前系统、版本和 CPU 架构:

Terminal window
cat /etc/os-release
uname -m

常见架构说明:

x86_64:Intel / AMD 64 位服务器
aarch64:ARM 64 位服务器,例如部分云服务器、树莓派和 NAS

本文主要适用于 Debian 12 / 13,以及 Ubuntu 22.04 / 24.04 / 26.04 的 64 位系统。

如果系统之前安装过发行版自带的旧 Docker 包,建议先卸载可能冲突的组件:

Terminal window
sudo apt remove \
docker.io docker-compose docker-compose-v2 docker-doc \
podman-docker containerd runc

如果终端提示某些软件包没有安装,可以忽略。

注意:卸载软件包通常不会自动删除已有镜像、容器和数据卷。不要在已有生产 Docker 环境的服务器上直接执行清理操作。

2. 通过 Docker 官方仓库安装 Docker Engine

以下是 Debian 的安装方式。

先安装必要依赖,并添加 Docker 的 GPG 密钥:

Terminal window
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

添加 Docker 的 APT 软件源:

Terminal window
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

更新软件包索引并安装 Docker Engine、Buildx 和 Compose 插件:

Terminal window
sudo apt update
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin

Ubuntu 的步骤基本相同,区别是下载 GPG 密钥和软件源时将路径中的 debian 替换为 ubuntu

Terminal window
https://download.docker.com/linux/ubuntu/gpg
https://download.docker.com/linux/ubuntu

安装完成后,确认 Docker 服务状态:

Terminal window
sudo systemctl status docker

若服务没有启动:

Terminal window
sudo systemctl start docker
sudo systemctl enable docker

验证安装:

Terminal window
sudo docker run hello-world

看到 Docker 输出欢迎信息,说明安装成功。

3. 配置当前用户使用 Docker

默认情况下,Docker 守护进程由 root 管理,因此需要在命令前加 sudo

Terminal window
sudo docker ps

如果这是你自己的开发机或个人服务器,可以将当前用户加入 docker 用户组:

Terminal window
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

重新验证:

Terminal window
docker run hello-world

**安全提示:**加入 docker 组相当于授予该用户接近 root 的权限。对于多人共用的服务器,不要随意把普通账号加入此组;更严格的场景应评估 Docker Rootless Mode 或使用独立的受限部署账号。

4. 认识 Docker 的基础命令

查看 Docker 版本:

Terminal window
docker version
docker compose version

查看本地镜像:

Terminal window
docker images

查看正在运行的容器:

Terminal window
docker ps

查看全部容器,包括已退出的容器:

Terminal window
docker ps -a

Docker 的日常操作通常围绕下面这条流程:

拉取镜像 → 创建并运行容器 → 查看日志 → 进入容器排查 → 停止或删除容器

5. 运行第一个 Nginx 容器

先拉取 Nginx 镜像:

Terminal window
docker pull nginx:alpine

启动一个后台运行的 Nginx 容器:

Terminal window
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 127.0.0.1:8080:80 \
nginx:alpine

参数含义:

-d 后台运行
--name nginx-web 指定容器名称
--restart unless-stopped
Docker 重启后自动恢复容器;手动停止后不自动启动
-p 127.0.0.1:8080:80 将宿主机本机的 8080 映射到容器的 80 端口
nginx:alpine 使用体积较小的 Nginx 镜像

在服务器上测试:

Terminal window
curl http://127.0.0.1:8080

如果需要让外部网络直接访问容器端口,可以写成:

Terminal window
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 8080:80 \
nginx:alpine

但这会把 8080 暴露到服务器网络。对于公网服务器,更推荐把应用只绑定到 127.0.0.1,再由 Caddy、Nginx 或 Traefik 统一处理 HTTPS 和外部访问。

6. 查看日志、进入容器和管理生命周期

实时查看容器日志:

Terminal window
docker logs -f nginx-web

查看容器详细信息:

Terminal window
docker inspect nginx-web

进入正在运行的容器:

Terminal window
docker exec -it nginx-web sh

停止容器:

Terminal window
docker stop nginx-web

启动已经停止的容器:

Terminal window
docker start nginx-web

重启容器:

Terminal window
docker restart nginx-web

删除容器:

Terminal window
docker rm -f nginx-web

删除容器只会删除容器本身,不一定会删除它挂载的数据卷。持久化数据应通过数据卷或宿主机目录管理,而不是只存放在容器内部。

7. 使用数据卷保存持久化数据

容器被删除后,写在容器内部的文件通常也会丢失。因此数据库、上传文件、配置文件等内容应使用数据卷保存。

创建一个名为 mysql-data 的数据卷:

Terminal window
docker volume create mysql-data

查看数据卷:

Terminal window
docker volume ls

以 MySQL 为例,将数据库数据保存到数据卷:

Terminal window
docker run -d \
--name mysql8 \
--restart unless-stopped \
-e MYSQL_ROOT_PASSWORD='请替换为强密码' \
-e MYSQL_DATABASE=appdb \
-v mysql-data:/var/lib/mysql \
mysql:8

这里的关键参数是:

-v mysql-data:/var/lib/mysql

左侧是宿主机上的 Docker 数据卷名称,右侧是容器内部 MySQL 保存数据的位置。即使容器被重新创建,只要继续挂载同一个数据卷,数据仍然存在。

查看数据卷详细信息:

Terminal window
docker volume inspect mysql-data

8. 使用 Docker Compose 管理多个服务

当一个项目包含 Web 服务、数据库、缓存、反向代理时,逐条输入 docker run 会很难维护。Docker Compose 可以用一个 compose.yaml 文件统一描述服务、端口、数据卷和网络。

创建项目目录:

Terminal window
mkdir -p ~/docker-demo
cd ~/docker-demo

创建 compose.yaml

services:
web:
image: nginx:alpine
container_name: demo-web
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
redis:
image: redis:7-alpine
container_name: demo-redis
restart: unless-stopped
volumes:
- redis-data:/data
volumes:
redis-data:

创建测试页面:

Terminal window
mkdir -p html
cat > html/index.html <<'EOF'
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Docker Compose Demo</title>
</head>
<body>
<h1>Docker Compose 已正常运行</h1>
</body>
</html>
EOF

启动全部服务:

Terminal window
docker compose up -d

查看 Compose 管理的服务状态:

Terminal window
docker compose ps

实时查看日志:

Terminal window
docker compose logs -f

停止并删除 Compose 创建的容器和网络:

Terminal window
docker compose down

如果需要连同 Compose 创建的命名数据卷一起删除:

Terminal window
docker compose down -v

docker compose down -v 会删除相关数据卷。数据库或业务数据存在时,执行前必须确认已经备份。

9. 构建自己的镜像

如果你的项目不是直接使用现成镜像,而是自己写的 FastAPI、Node.js 或 Go 服务,就需要用 Dockerfile 构建镜像。

下面是一个简单的 Python Web 服务示例。

创建 app.py

from flask import Flask
app = Flask(__name__)
@app.get("/")
def index():
return {"message": "Hello from Docker"}

创建 requirements.txt

flask
gunicorn

创建 Dockerfile

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 8000
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]

构建镜像:

Terminal window
docker build -t my-flask-app:1.0 .

运行容器:

Terminal window
docker run -d \
--name my-flask-app \
--restart unless-stopped \
-p 127.0.0.1:8000:8000 \
my-flask-app:1.0

测试服务:

Terminal window
curl http://127.0.0.1:8000

10. 清理不再使用的 Docker 资源

Docker 长期使用后,未使用镜像、已退出容器、构建缓存可能会占用大量磁盘空间。

查看总体占用:

Terminal window
docker system df

删除已退出的容器:

Terminal window
docker container prune

删除未被使用的镜像:

Terminal window
docker image prune -a

删除未被使用的网络:

Terminal window
docker network prune

交互式清理常见无用资源:

Terminal window
docker system prune

更彻底的清理:

Terminal window
docker system prune -a

docker system prune -a 会删除所有未被运行中容器使用的镜像。执行前先使用 docker imagesdocker ps -a 检查,避免删掉后续仍要使用的镜像。

常见问题

1. 执行 docker 提示 permission denied

常见报错:

permission denied while trying to connect to the Docker daemon socket

先临时使用 sudo

Terminal window
sudo docker ps

如果希望当前用户直接运行 Docker,确认已经完成用户组配置:

Terminal window
sudo usermod -aG docker $USER
newgrp docker

如果仍然不生效,退出当前 SSH 会话并重新登录,或者重启服务器后再试。

2. Docker 服务没有启动怎么办?

查看状态:

Terminal window
sudo systemctl status docker

启动服务:

Terminal window
sudo systemctl start docker

设置开机启动:

Terminal window
sudo systemctl enable docker

查看 Docker 服务日志:

Terminal window
sudo journalctl -u docker -n 100 --no-pager

3. 为什么映射端口后 UFW 规则没有按预期生效?

Docker 在发布容器端口时会操作 iptables 规则,部分情况下可能绕过 UFW 或 firewalld 的常规规则。

不要仅依赖“服务器已经安装 UFW”来判断容器端口是否安全。对于公网服务,建议:

  1. 尽量使用 127.0.0.1:宿主机端口:容器端口,避免直接对公网暴露内部服务;
  2. 统一通过反向代理提供 HTTPS;
  3. 在云厂商安全组、防火墙和 Docker 网络层同时限制访问范围;
  4. 定期使用 ss -lntpdocker ps 检查暴露端口。

4. 容器停止后,为什么服务不能自动恢复?

确认容器是否设置重启策略:

Terminal window
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' 容器名

推荐个人服务器中的长期服务使用:

--restart unless-stopped

对于 Docker Compose:

restart: unless-stopped

5. docker compose 和 docker-compose 有什么区别?

当前推荐使用:

Terminal window
docker compose

这是 Docker Compose v2 插件的调用方式。

旧教程中常见的:

Terminal window
docker-compose

通常是旧版独立程序。新项目建议统一使用 docker compose,避免混用。

6. Docker 能完全替代虚拟机吗?

不能完全替代。

Docker 容器共享宿主机内核,适合运行服务、开发环境和持续部署;虚拟机则拥有更完整的系统隔离,适合运行不同内核需求的系统、桌面环境或更强隔离需求的场景。

可以简单理解为:

Docker:更轻量、更快启动、适合应用部署
虚拟机:隔离更完整、适合运行完整操作系统

总结

Docker 的核心价值,是让应用部署从“手动配置一台机器”变成“用镜像和配置重复创建同样的运行环境”。

日常最常用的命令包括:

docker ps 查看运行中的容器
docker ps -a 查看全部容器
docker images 查看镜像
docker logs -f 容器名 实时查看日志
docker exec -it 容器名 sh 进入容器
docker stop / start / restart 管理容器生命周期
docker compose up -d 启动多容器项目
docker compose logs -f 查看 Compose 项目日志
docker system df 查看 Docker 磁盘占用

对于个人服务器,推荐形成下面的部署习惯:

Docker Compose 管理项目
数据卷保存数据库与业务数据
反向代理统一处理域名与 HTTPS
容器只绑定必要端口
定期备份数据卷与 Compose 配置
定期检查日志、磁盘占用和镜像更新

继续部署真实项目时,可以参考 Tmux 入门教程:让 SSH 断线和多任务终端不再中断 保持远程操作现场,也可以结合 Git 安装与使用教程:Linux 和 Windows 从零开始版本管理 管理 Compose 配置。Docker 版本、镜像和 Compose 语法建议以 Docker 官方文档 为准。