Docker 完全入门教程

从零开始掌握容器化技术


目录

  1. 什么是 Docker?
  2. 核心概念
  3. 安装 Docker
  4. 基本命令
  5. Dockerfile 编写
  6. Docker Compose
  7. 数据持久化
  8. 网络管理
  9. 实战示例:部署 Node.js 应用
  10. 常见问题与技巧
  11. 总结

什么是 Docker?

Docker 是一个开源的容器化平台,让开发者可以将应用及其依赖打包到一个轻量级、可移植的容器中,从而实现"一次构建,到处运行"。

为什么使用 Docker?

传统部署 Docker 容器化
环境配置繁琐 环境一致性保证
依赖冲突频繁 依赖隔离
扩容困难 秒级启停,弹性扩缩
资源利用率低 轻量高效,共享宿主内核

核心概念

镜像(Image)

镜像是一个只读的模板,包含运行应用所需的代码、运行时、库和配置。可以把它理解为一个"快照"或"安装包"。

复制代码
镜像 = 操作系统层 + 运行时 + 应用代码 + 依赖

容器(Container)

容器是镜像的运行实例。一个镜像可以启动多个容器,每个容器相互隔离。

复制代码
容器 = 镜像 + 可写层 + 运行进程

仓库(Registry)

仓库用于存储和分发镜像 。最常用的是 Docker Hub,也可以搭建私有仓库。

ini 复制代码
Docker Hub = GitHub(但存放的是镜像,不是代码)

安装 Docker

macOS / Windows

Docker 官网 下载并安装 Docker Desktop,安装完成后即可使用。

⚠️ 注意授权 :Docker Desktop 对个人、教育及小型企业(员工 < 250 人且年收入 < 1000 万美元)免费;超出此范围的商业用途需购买付费订阅。

Linux(Ubuntu 为例)

bash 复制代码
# 更新包索引
sudo apt-get update

# 安装依赖
sudo apt-get install -y ca-certificates curl gnupg

# 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 添加仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.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-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# 验证安装
docker --version

验证安装

arduino 复制代码
docker run hello-world

看到 Hello from Docker! 说明安装成功 🎉


基本命令

镜像操作

perl 复制代码
# 搜索镜像
docker search nginx

# 拉取镜像(不指定标签默认拉取 latest)
docker pull nginx
docker pull nginx:1.25

# 查看本地镜像
docker images

# 删除镜像
docker rmi nginx:latest

# 构建镜像
docker build -t my-app:1.0 .

容器操作

perl 复制代码
# 运行容器
docker run nginx

# 后台运行(-d: detach)
docker run -d nginx

# 指定名称 + 端口映射
docker run -d --name my-nginx -p 8080:80 nginx

# 交互模式进入容器
docker run -it ubuntu bash

# 查看运行中的容器
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 exec -it my-nginx bash

# 查看容器日志
docker logs my-nginx
docker logs -f my-nginx   # 实时跟踪日志

# 查看容器详细信息
docker inspect my-nginx

系统清理

perl 复制代码
# 删除所有停止的容器
docker container prune

# 删除未使用的镜像
docker image prune

# 一键清理所有未使用资源
docker system prune -a

Dockerfile 编写

Dockerfile 是构建镜像的配置文件,每条指令对应镜像的一层。

常用指令

指令 说明
FROM 指定基础镜像
WORKDIR 设置工作目录
COPY 复制文件到镜像
ADD 复制文件(支持URL和解压tar)
RUN 构建时执行命令
ENV 设置环境变量
EXPOSE 声明容器监听端口
CMD 容器启动时执行的默认命令
ENTRYPOINT 容器启动入口点

示例:Python Flask 应用

ini 复制代码
# 1. 指定基础镜像
FROM python:3.11-slim

# 2. 设置工作目录
WORKDIR /app

# 3. 先复制依赖文件(利用构建缓存)
COPY requirements.txt .

# 4. 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 5. 复制应用代码
COPY . .

# 6. 设置环境变量
ENV FLASK_APP=app.py
ENV FLASK_ENV=production

# 7. 暴露端口
EXPOSE 5000

# 8. 启动命令
CMD ["flask", "run", "--host=0.0.0.0"]

构建与运行

yaml 复制代码
# 构建镜像
docker build -t flask-app:latest .

# 运行容器
docker run -d -p 5000:5000 --name flask-app flask-app:latest

.dockerignore 文件

类似 .gitignore,排除不需要打包的文件:

bash 复制代码
__pycache__/
*.pyc
.env
.git
node_modules/
*.log

Docker Compose

Docker Compose 用于定义和管理多容器应用,通过一个 YAML 文件描述所有服务。

安装

Docker Desktop 已内置 Compose;Linux 用户执行:

arduino 复制代码
sudo apt-get install docker-compose-plugin
docker compose version

docker-compose.yml 示例

以下是一个包含 Web 应用、数据库和缓存的典型配置:

yaml 复制代码
version: '3.8'

services:
  # Web 应用
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/mydb
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    volumes:
      - ./app:/app
    restart: unless-stopped

  # PostgreSQL 数据库
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  # Redis 缓存
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

# 数据卷
volumes:
  postgres_data:

Compose 常用命令

python 复制代码
# 启动所有服务(后台)
docker compose up -d

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f web

# 停止服务
docker compose stop

# 停止并删除容器
docker compose down

# 停止并删除容器、镜像、数据卷
docker compose down --volumes --rmi all

# 重新构建镜像
docker compose build

# 进入某个服务的容器
docker compose exec web bash

数据持久化

容器删除后,容器内的数据会一起消失。Docker 提供三种数据持久化方式:

1. Volume(推荐)

由 Docker 管理,存储在宿主机的 /var/lib/docker/volumes/ 目录。

bash 复制代码
# 创建 volume
docker volume create mydata

# 使用 volume
docker run -d -v mydata:/app/data nginx

# 查看所有 volume
docker volume ls

# 删除 volume
docker volume rm mydata

2. Bind Mount(绑定挂载)

将宿主机目录直接挂载到容器,适合开发阶段实时同步代码。

ruby 复制代码
# 将当前目录挂载到容器的 /app
docker run -d -v $(pwd):/app -p 3000:3000 node-app

3. tmpfs Mount

数据存储在宿主机内存中,容器停止后消失,适合存储敏感临时数据。

arduino 复制代码
docker run -d --tmpfs /tmp nginx

网络管理

Docker 网络类型

类型 说明
bridge 默认网络,容器间可通过容器名互通
host 共享宿主机网络,性能最好
none 无网络,完全隔离
overlay 跨主机容器通信(Swarm 集群)

自定义网络

perl 复制代码
# 创建自定义网络
docker network create my-network

# 在指定网络中运行容器
docker run -d --network my-network --name app my-app
docker run -d --network my-network --name db postgres

# 此时 app 容器可以直接用 "db" 作为主机名访问数据库

# 查看网络
docker network ls
docker network inspect my-network

# 删除网络
docker network rm my-network

实战示例:部署 Node.js 应用

项目结构

css 复制代码
my-node-app/
├── src/
│   └── index.js
├── package.json
├── Dockerfile
├── .dockerignore
└── docker-compose.yml

src/index.js

ini 复制代码
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({ message: 'Hello from Docker!', env: process.env.NODE_ENV });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Dockerfile

ini 复制代码
FROM node:20-alpine

WORKDIR /app

# 先复制 package 文件,充分利用缓存
COPY package*.json ./
RUN npm ci --only=production

COPY src/ ./src/

ENV NODE_ENV=production
EXPOSE 3000

# 使用非 root 用户运行(安全最佳实践)
USER node

CMD ["node", "src/index.js"]

docker-compose.yml

yaml 复制代码
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
    restart: unless-stopped

部署步骤

bash 复制代码
# 1. 构建并启动
docker compose up -d --build

# 2. 验证运行
curl http://localhost:3000

# 3. 查看日志
docker compose logs -f app

常见问题与技巧

减小镜像体积

bash 复制代码
# ✅ 使用 alpine 版本
FROM node:20-alpine    # ~50MB vs node:20 ~1GB

# ✅ 合并 RUN 命令,减少层数
RUN apt-get update && \
    apt-get install -y curl && \
    rm -rf /var/lib/apt/lists/*

# ✅ 多阶段构建(适合编译型语言)
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o server .

FROM alpine:latest          # 最终镜像只包含可执行文件
COPY --from=builder /app/server .
CMD ["./server"]

常用快捷操作

bash 复制代码
# 删除所有停止的容器
docker rm $(docker ps -aq -f status=exited)

# 删除所有 <none> 镜像(悬空镜像)
docker rmi $(docker images -f "dangling=true" -q)

# 查看容器资源使用情况
docker stats

# 从容器复制文件到宿主机
docker cp my-container:/app/logs ./logs

# 将容器保存为镜像
docker commit my-container my-snapshot:v1

安全建议

  • 不要以 root 用户运行 :在 Dockerfile 中添加 USER node(或其他非root用户)
  • 不要在镜像中硬编码密码:使用环境变量或 Docker Secrets
  • 定期更新基础镜像:及时获取安全补丁
  • 使用 .dockerignore :避免将 .env、密钥等敏感文件打包进镜像
  • 扫描镜像漏洞 :使用 docker scout 或 Trivy 等工具

总结

场景 命令/工具
运行单个容器 docker run
构建自定义镜像 Dockerfile + docker build
管理多容器应用 docker-compose.yml + docker compose up
数据持久化 Volume / Bind Mount
容器间通信 自定义网络

掌握这些核心知识,你已经具备在生产环境中使用 Docker 的基础能力。下一步可以探索 Kubernetes (容器编排)和 CI/CD 集成,进一步提升你的云原生技术栈!


Happy Dockerizing! 🐳

相关推荐
用户467245132232 小时前
多线程编程的噩梦:线程"挂住了"怎么办?
后端
神奇小汤圆2 小时前
Spring AI 实战:用Java搭一个Multi-Agent多智能体系统,附完整源码
后端
TE-茶叶蛋3 小时前
Spring最核心扩展点:BeanPostProcessor
java·后端·spring
阿丰资源3 小时前
基于SpringBoot智能化体育馆管理系统(附源码+文档+数据库,一键运行)
数据库·spring boot·后端
千云3 小时前
问题排查报告:一次因元空间溢出导致的CPU飙升与接口超时
java·后端
breeze微风4 小时前
HashMap设计思想深度分析
后端
kree4 小时前
Kubernetes (k8s) 完全入门教程
后端
Jutick4 小时前
Python 行情数据清洗实战:Z-Score、MAD 与分位数过滤的异常值检测
后端·架构
NineData5 小时前
玖章算术NineData成功入选杭州市“新雏鹰”企业
运维·数据库·后端