“为什么刚刚能运行,现在就不行,为什么刚刚不运行,现在就可以,为什么他的可以跑,我的不能跑,为什么我的可以跑,他的就不行,为什么这台电脑能,那台就不能”
在软件开发中最大的问题之一就是环境不一致。
Docker 就是为了解决这些问题而生的,所以我开始学习Docker,并通过书写教程的方式,来巩固自己学习的记录
准备工作
Docker简介
Docker 是一个开源的应用容器化平台,它允许开发者将应用及其所有依赖打包到一个称为“容器”的标准化单元中,让它可以在任何环境中以相同的方式运行。
核心概念
为了更好地理解 Docker,我们需要掌握三个核心概念:
1. 镜像 (Image):可以理解为容器的“蓝图”或“模板”。它包含了运行应用所需的所有内容——代码、运行时、系统工具、库和设置。镜像是一个只读的静态文件。
2. 容器 (Container):镜像的运行实例。你可以把容器看作是一个轻量级的、独立的执行环境。容器是可写的、可启动、停止和删除的。
3. 仓库 (Registry):存储和分发镜像的地方。Docker Hub 是最流行的公共镜像仓库,你可以在这里找到成千上万的官方和社区镜像。
Docker 与虚拟机的区别
很多人会把 Docker 和虚拟机混淆,但它们的本质完全不同,简单来说,虚拟机虚拟的是硬件,而 Docker 虚拟的是操作系统。因此容器更加轻量、快速和高效。
安装 Docker
在Linux上安装(Centos为例)
安装依赖包
sudo yum install -y yum-utils添加 Docker 软件源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo安装 Docker
sudo yum install docker-ce docker-ce-cli containerd.io启动 Docker 服务
sudo systemctl start dockersudo systemctl enable docker验证安装
docker --versionDocker实践
让我们从最经典的程序开始:
docker run hello-world这个命令会,检查本地是否有 hello-world 镜像,如果没有则从 Docker Hub 拉取,创建一个容器并运行,输出欢迎信息后容器自动停止
常用基础命令
镜像相关
列出本地镜像
docker images搜索镜像
docker search nginx拉取镜像:latest指的是最后一个版本,也就是最新版
docker pull nginx:latest删除镜像
docker rmi <镜像ID>构建镜像
docker build -t my-app:v1 .容器相关命令
运行容器(前台运行)
docker run nginx运行容器(后台运行)加入参数-d
docker run -d nginx列出运行中的容器
docker ps列出所有容器(包括停止的)
docker ps -a停止容器
docker stop <容器ID>启动已停止的容器
docker start <容器ID>进入容器内部
docker exec -it <容器ID> /bin/bash删除容器
docker rm <容器ID>查看容器日志
docker logs <容器ID>查看容器资源占用
docker stats <容器ID>运行一个真正的 Web 应用示例
让我们运行一个 Nginx Web 服务器:
拉取 Nginx 镜像
docker pull nginx运行 Nginx 容器,映射端口 80 到宿主机的 8080
docker run -d -p 8080:80 --name my-nginx nginx验证:在浏览器访问 http://localhost:8080,你应该能看到 Nginx 的欢迎页面
查看容器日志
解释:
- -d:后台运行(detach 模式)
- -p 8080:80:端口映射,将容器的 80 端口映射到宿主机的 8080 端口
- --name my-nginx:为容器指定名称
Volume 的使用
容器被删除后,里面的数据也会丢失。为了持久化数据,我们需要使用卷(Volume):
创建数据卷
docker volume create my-data运行容器并挂载数据卷
docker run -d -v my-data:/usr/share/nginx/html -p 8080:80 --name nginx-with-data nginx或者使用绑定挂载(将宿主机目录挂载到容器)
docker run -d -v /path/to/host:/usr/share/nginx/html -p 8080:80 nginx构建自定义的镜像
Dockerfile 是一个文本文件,包含了构建镜像所需的全部指令。让我们创建一个简单的 Python Web 应用镜像。
首先创建一个项目目录:
mkdir my-python-app
cd my-python-app创建 app.py:(这个是我ai的,仅仅作为示例)
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello():
return f'Hello from Docker! Hostname: {os.uname().nodename}'
if name == '__main__':
app.run(host='0.0.0.0', port=5000)创建 requirements.txt:
flask==2.3.2创建 Dockerfile:
# 使用官方 Python 镜像作为基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY app.py .
# 暴露端口
EXPOSE 5000
# 启动命令
CMD ["python", "app.py"]构建并运行:
构建镜像
docker build -t my-python-app:v1 .运行容器并验证
docker run -d -p 5000:5000 --name my-app my-python-app:v1在浏览器访问 http://localhost:5000
Docker Compose管理多容器应用
当应用由多个服务组成(如 Web 应用 + 数据库)时,Docker Compose 可以让管理变得简单。
创建 docker-compose.yml:(规则)
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- REDIS_HOST=redis
depends_on:
- redis
volumes:
- ./app.py:/app/app.py
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
volumes:
redis-data:使用 Compose 管理应用:
启动所有服务
docker-compose up -d查看服务状态
docker-compose ps查看日志
docker-compose logs web停止并删除所有服务
docker-compose down停止并删除所有服务,同时删除数据卷
docker-compose down -vDocker 最佳实践建议
镜像优化: 使用多阶段构建减小镜像体积
FROM python:3.9-slim AS builder
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.9-slim
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]Docker 安全配置 Q&A
Q:为什么不要以 root 用户运行容器?
A:容器内 root 权限存在提权风险,攻击者可能借此控制宿主机。应创建专用用户运行应用。
Q:如何在 Dockerfile 中创建非 root 用户?
A:
RUN useradd -m -u 1000 appuser
USER appuserQ:"使用最新镜像"具体指什么?
A:指定期更新基础镜像版本,及时修复已知漏洞。但生产环境建议锁定精确版本(如 nginx:1.25.3),而非 latest,避免环境不一致。
Q:如何扫描镜像漏洞?
A:使用 docker scan <镜像名> 命令即可扫描已知漏洞。
Q:如何限制容器的 CPU 和内存?
A:运行容器时添加参数:
docker run --memory=512m --cpus=1.5 my-app:v1dockerignore
类似于 .gitignore,创建一个 .dockerignore 文件排除不需要的文件:
node_modules
*.log
Dockerfile
.dockerignore日志管理
配置日志驱动
docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 nginx常见问题排查
端口被占用时:
查看端口占用
netstat -tulpn | grep 8080或
lsof -i :8080停止占用端口的容器
docker stop <容器ID>磁盘空间不足时
查看 Docker 磁盘使用情况
docker system df清理未使用的资源
docker system prune -a清理所有停止的容器、网络、镜像和缓存
docker system prune -a -f容器无法启动时
查看详细日志
docker logs <容器ID>进入容器的调试模式
docker run -it --entrypoint /bin/bash <镜像名>推荐的下一步学习计划与建议
接下来是个人走过的学习路径,推荐按照这个顺序进行学习:
学习 Kubernetes,管理大规模容器集群
探索 CI/CD,将 Docker 集成到持续集成/持续部署流程
了解容器网络,理解 Docker 的网络模式
研究安全最佳实践:构建更加安全的容器化应用
【编程】Docker 学习记录回顾与实践
https://enento.cloud/archives/docker-shi-jian
评论