peakchao

搜索

peakchao

peakchao

前端开发工程师 | Go 爱好者

联系方式

Docker 完全指南:从入门到实践

peakchao 2025-12-13 05:20 10 次浏览 0 条评论

Docker 简介

什么是 Docker?

Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖项打包到一个轻量级、可移植的容器中。容器是一种标准化的软件单元,可以在任何支持 Docker 的环境中运行,无论是开发者的笔记本电脑、测试服务器还是生产环境的云平台。

Docker 由 Docker Inc.(前身为 dotCloud)于 2013 年发布,基于 Go 语言开发,并利用 Linux 内核的多项特性(如 cgroups、namespaces)来实现容器的隔离和资源管理。

Docker 架构

Docker 采用客户端-服务器(C/S)架构:

┌─────────────────────────────────────────────────────────────┐
│                        Docker 架构                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐        ┌─────────────────────────────┐   │
│   │   Docker    │  REST  │       Docker Daemon         │   │
│   │   Client    │◄──────►│        (dockerd)            │   │
│   │  (docker)   │  API   │                             │   │
│   └─────────────┘        └──────────┬──────────────────┘   │
│                                     │                       │
│                    ┌────────────────┼────────────────┐      │
│                    ▼                ▼                ▼      │
│              ┌──────────┐    ┌──────────┐    ┌──────────┐  │
│              │ Container│    │ Container│    │  Image   │  │
│              │     1    │    │     2    │    │  Registry│  │
│              └──────────┘    └──────────┘    └──────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘
  • Docker Client(docker):用户与 Docker 交互的主要方式,通过命令行工具发送命令
  • Docker Daemon(dockerd):后台服务,负责管理 Docker 对象(镜像、容器、网络、卷等)
  • Docker Registry:存储 Docker 镜像的仓库,Docker Hub 是官方的公共仓库

容器 vs 虚拟机

特性Docker 容器虚拟机
启动时间秒级分钟级
硬盘占用MB 级别GB 级别
性能接近原生弱于原生
系统支持量单机支持上千个容器一般几十个
隔离性进程级别系统级别(更强)
操作系统共享宿主机内核独立操作系统

Docker 的意义与价值

1. 解决“在我电脑上能运行“的问题

传统开发中,开发、测试、生产环境的差异经常导致“在我电脑上能运行“的尴尬局面。Docker 通过将应用及其所有依赖打包在一起,确保了环境的一致性。

2. 简化部署流程

# 传统部署方式
安装操作系统 → 配置环境 → 安装依赖 → 复制代码 → 配置服务 → 启动应用

# Docker 部署方式
拉取镜像 → 运行容器
docker pull myapp:latest && docker run -d myapp:latest

3. 提高资源利用率

容器共享宿主机的操作系统内核,不需要为每个应用分配独立的操作系统资源,大大提高了服务器的资源利用率。

4. 支持微服务架构

Docker 天然支持微服务架构,每个微服务可以独立打包、部署、扩展,降低了服务间的耦合度。

5. 快速扩展和回滚

# 快速扩展到 5 个实例
docker service scale myapp=5

# 快速回滚到上一版本
docker service rollback myapp

6. 持续集成/持续部署 (CI/CD)

Docker 与 CI/CD 工具(如 Jenkins、GitLab CI、GitHub Actions)完美集成,实现自动化构建、测试和部署。


Docker 安装

macOS 安装

推荐使用 Docker Desktop for Mac:

# 使用 Homebrew 安装
brew install --cask docker

# 或者从官网下载
# https://www.docker.com/products/docker-desktop

安装完成后,启动 Docker Desktop 应用程序。

Ubuntu/Debian 安装

# 1. 更新包索引并安装依赖
sudo apt-get update
sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

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

# 3. 添加 Docker 仓库
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

# 4. 安装 Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 5. 验证安装
sudo docker run hello-world

CentOS/RHEL 安装

# 1. 移除旧版本
sudo yum remove docker \
                docker-client \
                docker-client-latest \
                docker-common \
                docker-latest \
                docker-latest-logrotate \
                docker-logrotate \
                docker-engine

# 2. 安装依赖
sudo yum install -y yum-utils

# 3. 添加 Docker 仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 4. 安装 Docker Engine
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 5. 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker

# 6. 验证安装
sudo docker run hello-world

配置非 root 用户使用 Docker

# 创建 docker 组(如果不存在)
sudo groupadd docker

# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER

# 激活组更改(需要重新登录或运行以下命令)
newgrp docker

# 验证(无需 sudo)
docker run hello-world

配置 Docker 镜像加速(中国大陆用户)

编辑或创建 /etc/docker/daemon.json

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

重启 Docker 服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

Docker 核心概念

镜像 (Image)

镜像是一个只读的模板,包含创建 Docker 容器的指令。镜像采用分层存储的方式,每一层都是对上一层的修改。

# 查看本地镜像
docker images

# 输出示例
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         latest    a6bd71f48f68   2 weeks ago    187MB
redis         7.0       e40e2763392d   3 weeks ago    138MB
mysql         8.0       3218b38490ce   4 weeks ago    516MB

容器 (Container)

容器是镜像的可运行实例。可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。

数据卷 (Volume)

数据卷用于持久化容器产生的数据,即使容器被删除,数据卷中的数据也会保留。

网络 (Network)

Docker 网络允许容器之间以及容器与外部世界之间进行通信。


常用命令详解

镜像管理命令

docker pull - 拉取镜像

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

参数说明:

  • NAME:镜像名称
  • TAG:镜像标签,默认为 latest
  • DIGEST:镜像摘要

示例:

# 拉取最新版 nginx
docker pull nginx

# 拉取指定版本
docker pull nginx:1.25.3

# 拉取指定摘要的镜像
docker pull nginx@sha256:abc123...

docker images - 列出镜像

docker images [OPTIONS] [REPOSITORY[:TAG]]

常用参数:

参数说明
-a, --all显示所有镜像(包括中间层)
-q, --quiet只显示镜像 ID
--filter根据条件过滤
--format自定义输出格式

示例:

# 列出所有镜像
docker images

# 只显示镜像 ID
docker images -q

# 过滤悬空镜像
docker images --filter "dangling=true"

# 自定义格式输出
docker images --format "{{.Repository}}:{{.Tag}} - {{.Size}}"

docker rmi - 删除镜像

docker rmi [OPTIONS] IMAGE [IMAGE...]

常用参数:

参数说明
-f, --force强制删除
--no-prune不删除未标记的父镜像

示例:

# 删除指定镜像
docker rmi nginx:latest

# 强制删除
docker rmi -f nginx:latest

# 删除所有悬空镜像
docker image prune

# 删除所有未使用的镜像
docker image prune -a

docker build - 构建镜像

docker build [OPTIONS] PATH | URL | -

常用参数:

参数说明
-t, --tag为镜像打标签
-f, --file指定 Dockerfile 路径
--build-arg设置构建时变量
--no-cache不使用缓存
--platform指定目标平台

示例:

# 基本构建
docker build -t myapp:1.0 .

# 指定 Dockerfile
docker build -t myapp:1.0 -f Dockerfile.prod .

# 传递构建参数
docker build --build-arg VERSION=1.0 -t myapp:1.0 .

# 多平台构建
docker build --platform linux/amd64,linux/arm64 -t myapp:1.0 .

容器管理命令

docker run - 创建并启动容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

常用参数详解:

参数说明示例
-d, --detach后台运行容器docker run -d nginx
-p, --publish端口映射 (主机端口:容器端口)docker run -p 8080:80 nginx
-P, --publish-all随机映射所有暴露端口docker run -P nginx
-v, --volume挂载数据卷docker run -v /host/path:/container/path nginx
--mount更详细的挂载选项docker run --mount type=bind,src=/host,dst=/container nginx
-e, --env设置环境变量docker run -e MYSQL_ROOT_PASSWORD=123456 mysql
--env-file从文件读取环境变量docker run --env-file .env myapp
--name为容器命名docker run --name my-nginx nginx
--network指定网络docker run --network my-network nginx
--restart重启策略docker run --restart=always nginx
-it交互式终端docker run -it ubuntu /bin/bash
--rm容器退出时自动删除docker run --rm nginx
-m, --memory内存限制docker run -m 512m nginx
--cpusCPU 限制docker run --cpus 1.5 nginx
-w, --workdir工作目录docker run -w /app myapp
-u, --user指定用户docker run -u 1000:1000 myapp

常用示例:

# 后台运行 nginx,映射 80 端口
docker run -d -p 80:80 --name web nginx

# 运行 MySQL,设置密码和持久化数据
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=secret \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

# 运行临时容器进行调试
docker run --rm -it alpine sh

# 带资源限制运行容器
docker run -d \
  --name limited-app \
  --memory 256m \
  --cpus 0.5 \
  myapp:latest

docker ps - 列出容器

docker ps [OPTIONS]

常用参数:

参数说明
-a, --all显示所有容器(包括已停止的)
-q, --quiet只显示容器 ID
-n, --last显示最近创建的 n 个容器
-l, --latest显示最近创建的容器
--filter根据条件过滤
--format自定义输出格式

示例:

# 查看运行中的容器
docker ps

# 查看所有容器
docker ps -a

# 只显示容器 ID
docker ps -q

# 过滤特定状态的容器
docker ps --filter "status=exited"

# 自定义格式
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

docker start/stop/restart - 容器生命周期管理

# 启动一个或多个已停止的容器
docker start [OPTIONS] CONTAINER [CONTAINER...]

# 停止一个或多个运行中的容器
docker stop [OPTIONS] CONTAINER [CONTAINER...]

# 重启容器
docker restart [OPTIONS] CONTAINER [CONTAINER...]

常用参数:

参数说明
-t, --time等待停止的超时时间(秒)

示例:

# 启动容器
docker start my-nginx

# 停止容器(默认等待 10 秒)
docker stop my-nginx

# 立即停止容器
docker stop -t 0 my-nginx

# 重启容器
docker restart my-nginx

# 停止所有运行中的容器
docker stop $(docker ps -q)

docker rm - 删除容器

docker rm [OPTIONS] CONTAINER [CONTAINER...]

常用参数:

参数说明
-f, --force强制删除运行中的容器
-v, --volumes同时删除关联的数据卷

示例:

# 删除已停止的容器
docker rm my-container

# 强制删除运行中的容器
docker rm -f my-container

# 删除所有已停止的容器
docker container prune

# 删除所有容器(包括运行中的)
docker rm -f $(docker ps -aq)

docker logs - 查看容器日志

docker logs [OPTIONS] CONTAINER

常用参数:

参数说明
-f, --follow跟踪日志输出(类似 tail -f)
--tail显示最后 n 行
-t, --timestamps显示时间戳
--since显示指定时间之后的日志
--until显示指定时间之前的日志

示例:

# 查看所有日志
docker logs my-container

# 实时跟踪日志
docker logs -f my-container

# 查看最后 100 行
docker logs --tail 100 my-container

# 显示时间戳
docker logs -t my-container

# 查看最近 1 小时的日志
docker logs --since 1h my-container

docker inspect - 查看详细信息

docker inspect [OPTIONS] NAME|ID [NAME|ID...]

示例:

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

# 查看容器 IP 地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container

# 查看容器挂载信息
docker inspect -f '{{json .Mounts}}' my-container | jq

网络管理命令

# 创建网络
docker network create my-network

# 列出网络
docker network ls

# 查看网络详情
docker network inspect my-network

# 连接容器到网络
docker network connect my-network my-container

# 断开容器与网络的连接
docker network disconnect my-network my-container

# 删除网络
docker network rm my-network

数据卷管理命令

# 创建数据卷
docker volume create my-volume

# 列出数据卷
docker volume ls

# 查看数据卷详情
docker volume inspect my-volume

# 删除数据卷
docker volume rm my-volume

# 删除所有未使用的数据卷
docker volume prune

进入容器终端

docker exec - 在运行中的容器内执行命令

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

常用参数:

参数说明
-i, --interactive保持 STDIN 打开
-t, --tty分配一个伪终端
-d, --detach后台运行命令
-e, --env设置环境变量
-u, --user指定用户
-w, --workdir指定工作目录

示例:

# 进入容器的 bash 终端
docker exec -it my-container /bin/bash

# 进入容器的 sh 终端(适用于 Alpine 等轻量镜像)
docker exec -it my-container /bin/sh

# 以 root 用户进入容器
docker exec -it -u root my-container /bin/bash

# 在容器内执行单个命令
docker exec my-container ls -la /var/log

# 在后台执行命令
docker exec -d my-container touch /tmp/test.txt

# 设置环境变量执行命令
docker exec -e MY_VAR=hello my-container printenv MY_VAR

docker attach - 附加到运行中的容器

docker attach [OPTIONS] CONTAINER

注意: attach 连接的是容器的主进程(PID 1),退出时可能会导致容器停止。使用 Ctrl+P Ctrl+Q 可以在不停止容器的情况下分离。

# 附加到容器
docker attach my-container

# 分离快捷键:Ctrl+P Ctrl+Q

docker exec vs docker attach 对比

特性docker execdocker attach
创建新进程
可执行任意命令
退出影响容器不影响可能停止容器
使用场景调试、运维查看主进程输出

Dockerfile 详解

Dockerfile 是什么?

Dockerfile 是一个文本文件,包含了构建 Docker 镜像所需的所有指令。Docker 通过读取 Dockerfile 中的指令自动构建镜像。

Dockerfile 指令详解

FROM - 基础镜像

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

说明: 指定基础镜像,必须是 Dockerfile 的第一条指令。

# 使用官方 Node.js 镜像
FROM node:18-alpine

# 多阶段构建
FROM golang:1.21 AS builder
FROM alpine:3.18 AS runtime

LABEL - 元数据

LABEL <key>=<value> <key>=<value> ...
LABEL maintainer="your@email.com"
LABEL version="1.0"
LABEL description="My awesome application"

ENV - 环境变量

ENV <key>=<value> ...
ENV NODE_ENV=production
ENV APP_HOME=/app \
    APP_PORT=3000

ARG - 构建参数

ARG <name>[=<default value>]

说明: 定义构建时的变量,只在构建阶段有效。

ARG VERSION=1.0
ARG BUILD_DATE

# 使用构建参数
RUN echo "Building version ${VERSION}"

构建时传递参数:

docker build --build-arg VERSION=2.0 -t myapp .

WORKDIR - 工作目录

WORKDIR /path/to/workdir
WORKDIR /app
# 后续的 RUN、CMD、COPY 等指令都在 /app 目录下执行

COPY - 复制文件

COPY [--chown=<user>:<group>] <src>... <dest>
# 复制单个文件
COPY package.json .

# 复制多个文件
COPY package.json package-lock.json ./

# 复制目录
COPY src/ ./src/

# 设置文件所有者
COPY --chown=node:node . .

ADD - 添加文件

ADD [--chown=<user>:<group>] <src>... <dest>

说明: 与 COPY 类似,但支持自动解压压缩文件和远程 URL。

# 自动解压 tar 文件
ADD archive.tar.gz /app

# 从 URL 下载文件
ADD https://example.com/file.txt /app/

最佳实践: 除非需要自动解压功能,否则优先使用 COPY。

RUN - 执行命令

# Shell 形式
RUN <command>

# Exec 形式
RUN ["executable", "param1", "param2"]
# 安装依赖
RUN apt-get update && apt-get install -y \
    curl \
    vim \
    && rm -rf /var/lib/apt/lists/*

# 多条命令合并(减少层数)
RUN npm install && \
    npm run build && \
    npm prune --production

CMD - 容器启动命令

# Exec 形式(推荐)
CMD ["executable", "param1", "param2"]

# Shell 形式
CMD command param1 param2

# 作为 ENTRYPOINT 的默认参数
CMD ["param1", "param2"]
# 启动 Node.js 应用
CMD ["node", "server.js"]

# 启动 nginx
CMD ["nginx", "-g", "daemon off;"]

注意: Dockerfile 中只能有一条 CMD 指令,如果有多条,只有最后一条生效。

ENTRYPOINT - 入口点

# Exec 形式(推荐)
ENTRYPOINT ["executable", "param1", "param2"]

# Shell 形式
ENTRYPOINT command param1 param2
# 定义入口点
ENTRYPOINT ["python", "app.py"]

# 配合 CMD 使用
ENTRYPOINT ["python"]
CMD ["app.py"]  # 可以被 docker run 的参数覆盖

EXPOSE - 暴露端口

EXPOSE <port> [<port>/<protocol>...]
# 暴露 HTTP 端口
EXPOSE 80

# 暴露多个端口
EXPOSE 80 443

# 指定协议
EXPOSE 80/tcp
EXPOSE 53/udp

注意: EXPOSE 只是声明端口,实际发布端口需要在运行时使用 -p 参数。

VOLUME - 数据卷

VOLUME ["/data"]
# 声明数据卷
VOLUME /var/lib/mysql
VOLUME ["/data", "/logs"]

USER - 切换用户

USER <user>[:<group>]
# 创建用户并切换
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# 或使用 UID:GID
USER 1000:1000

HEALTHCHECK - 健康检查

HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE  # 禁用健康检查

选项:

选项默认值说明
--interval30s检查间隔
--timeout30s超时时间
--start-period0s启动等待时间
--retries3失败重试次数
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD curl -f http://localhost/ || exit 1

# 对于非 HTTP 服务
HEALTHCHECK --interval=30s --timeout=3s \
  CMD pg_isready -U postgres || exit 1

SHELL - 默认 Shell

SHELL ["executable", "parameters"]
# Windows 示例
SHELL ["powershell", "-Command"]

# Linux 示例
SHELL ["/bin/bash", "-c"]

完整 Dockerfile 示例

Node.js 应用

# 使用官方 Node.js Alpine 镜像
FROM node:18-alpine

# 设置元数据
LABEL maintainer="developer@example.com"
LABEL version="1.0.0"

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY package*.json ./

# 安装依赖(生产环境)
RUN npm ci --only=production

# 复制源代码
COPY . .

# 创建非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

# 启动命令
CMD ["node", "server.js"]

Go 应用(多阶段构建)

# ==================== 构建阶段 ====================
FROM golang:1.21-alpine AS builder

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY go.mod go.sum ./

# 下载依赖
RUN go mod download

# 复制源代码
COPY . .

# 构建二进制文件
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

# ==================== 运行阶段 ====================
FROM alpine:3.18

# 安装 CA 证书(用于 HTTPS 请求)
RUN apk --no-cache add ca-certificates

# 设置工作目录
WORKDIR /root/

# 从构建阶段复制二进制文件
COPY --from=builder /app/main .

# 复制配置文件
COPY --from=builder /app/config ./config

# 暴露端口
EXPOSE 8080

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1

# 启动命令
CMD ["./main"]

Python 应用

FROM python:3.11-slim

# 避免 Python 缓冲输出
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

# 设置工作目录
WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    gcc \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .

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

# 复制源代码
COPY . .

# 创建非 root 用户
RUN useradd -m appuser && chown -R appuser:appuser /app
USER appuser

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

.dockerignore 文件

类似于 .gitignore,用于排除不需要复制到镜像中的文件:

# Git
.git
.gitignore

# Node.js
node_modules
npm-debug.log

# Python
__pycache__
*.pyc
.venv
venv

# IDE
.idea
.vscode
*.swp

# Build
dist
build
*.log

# Docker
Dockerfile*
docker-compose*.yml

# 其他
.env
.env.local
README.md
docs/
tests/

生成自定义镜像

使用 docker build 构建

# 基本构建
docker build -t myapp:1.0 .

# 指定 Dockerfile
docker build -t myapp:1.0 -f Dockerfile.prod .

# 不使用缓存
docker build --no-cache -t myapp:1.0 .

# 多平台构建
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:1.0 .

使用 docker commit 从容器创建镜像

# 从运行中的容器创建镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

常用参数:

参数说明
-a, --author作者
-m, --message提交信息
-c, --change应用 Dockerfile 指令

示例:

# 启动基础容器
docker run -it --name my-ubuntu ubuntu:22.04 /bin/bash

# 在容器内安装软件
apt-get update && apt-get install -y vim curl

# 退出容器
exit

# 从容器创建镜像
docker commit -a "Your Name" -m "Added vim and curl" my-ubuntu my-ubuntu-with-tools:1.0

注意: 推荐使用 Dockerfile 构建镜像,因为它更加透明、可重复和易于维护。

镜像标签管理

# 添加标签
docker tag myapp:1.0 myapp:latest
docker tag myapp:1.0 myregistry.com/myapp:1.0

# 查看镜像标签
docker images myapp

推送镜像到仓库

推送到 Docker Hub

# 1. 登录 Docker Hub
docker login
# 输入用户名和密码

# 2. 为镜像打标签(必须包含用户名)
docker tag myapp:1.0 username/myapp:1.0

# 3. 推送镜像
docker push username/myapp:1.0

# 4. 推送所有标签
docker push username/myapp --all-tags

推送到私有仓库

# 1. 登录私有仓库
docker login myregistry.com

# 2. 为镜像打标签
docker tag myapp:1.0 myregistry.com/project/myapp:1.0

# 3. 推送镜像
docker push myregistry.com/project/myapp:1.0

推送到阿里云容器镜像服务

# 1. 登录阿里云镜像仓库
docker login --username=your-username registry.cn-hangzhou.aliyuncs.com

# 2. 为镜像打标签
docker tag myapp:1.0 registry.cn-hangzhou.aliyuncs.com/your-namespace/myapp:1.0

# 3. 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/myapp:1.0

推送到 GitHub Container Registry

# 1. 创建 Personal Access Token (PAT)
# 在 GitHub Settings > Developer settings > Personal access tokens

# 2. 登录
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin

# 3. 为镜像打标签
docker tag myapp:1.0 ghcr.io/username/myapp:1.0

# 4. 推送镜像
docker push ghcr.io/username/myapp:1.0

Docker Compose 简介

Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。

安装 Docker Compose

Docker Desktop 已包含 Docker Compose。对于 Linux:

# 使用包管理器安装(推荐)
sudo apt-get install docker-compose-plugin

# 验证安装
docker compose version

docker-compose.yml 示例

version: '3.8'

services:
  # Web 应用
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://postgres:password@db:5432/myapp
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - app-network

  # 数据库
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

  # Redis 缓存
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - app-network

  # Nginx 反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - web
    networks:
      - app-network

volumes:
  postgres-data:
  redis-data:

networks:
  app-network:
    driver: bridge

Docker Compose 常用命令

# 启动所有服务
docker compose up

# 后台启动
docker compose up -d

# 构建并启动
docker compose up --build

# 停止所有服务
docker compose down

# 停止并删除数据卷
docker compose down -v

# 查看服务日志
docker compose logs -f

# 查看服务状态
docker compose ps

# 进入服务容器
docker compose exec web /bin/sh

# 扩展服务实例
docker compose up -d --scale web=3

最佳实践

1. 镜像构建最佳实践

  • 使用官方基础镜像:选择官方维护的镜像作为基础
  • 选择精简镜像:优先使用 Alpine 或 Distroless 镜像
  • 使用多阶段构建:分离构建环境和运行环境
  • 减少层数:合并 RUN 指令
  • 合理利用缓存:将变化频率低的指令放在前面

2. 安全最佳实践

# 使用非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# 只复制必要的文件
COPY --chown=appuser:appgroup . .

# 使用特定版本而非 latest
FROM node:18.19.0-alpine

# 定期更新基础镜像
# 扫描镜像漏洞
docker scout cves myapp:latest

3. 性能优化

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

# 先复制依赖文件,再复制源代码
COPY package*.json ./
RUN npm install
COPY . .

# 使用 .dockerignore 排除不必要的文件

4. 日志管理

# 配置日志驱动
docker run -d \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  myapp

5. 资源限制

# 限制内存和 CPU
docker run -d \
  --memory 512m \
  --memory-swap 1g \
  --cpus 1.5 \
  myapp

参考资料

官方文档

学习资源

工具推荐

相关技术


本文更新日期:2024年12月

如果这篇文章对你有帮助,欢迎点赞和分享!有任何问题,欢迎在评论区讨论。

评论 (0)

请先登录后再发表评论

暂无评论,来发表第一条评论吧!