前言
第一次听到”Docker”这个词的时候,你是不是也像我一样觉得这是个很高深的东西?我当初也是这么想的,甚至还把它和码头工人(docker本身就是这个词)联系在一起,觉得这东西肯定跟搬运货物有关。
后来真正用了才发现,Docker其实就是程序员用来”装软件”的神器——它能让你把应用程序和它需要的所有依赖打包在一起,不管你电脑是什么系统,装上Docker就能跑起来。再也不用听”在我这儿能跑啊”这种话了。
今天这篇文章,就是给完全没接触过Docker的小白写的。我会从最基础的概念讲起,手把手带你走完Docker入门的所有步骤。即使你是第一次接触容器技术,跟着这篇文章也能快速上手。

什么是Docker?
一句话解释Docker
简单来说,Docker就是一个容器技术。容器是什么?想象一下集装箱——不管里面装的是衣服还是电器,用集装箱运输,到哪儿都能原封不动地卸下来。Docker容器就是这个”集装箱”,把你的代码和运行环境打包在一起,确保”在我这儿能跑,到你那儿也能跑”。
这个比喻非常贴切。你想想,传统软件开发中,开发人员经常遇到这样的问题:
“代码在我电脑上是好的啊,为什么到你那儿就报错了?”
“我装的是Python 3.8,你的怎么是3.6?”
“缺少xxx.dll文件,请重新安装”——经典的DLL地狱
这些问题的根源就是环境不一致。Docker通过容器化技术,把你的应用和它所需的一切(代码、运行时、系统工具、系统库)全部打包,从根本上解决了这个问题。
Docker和虚拟机的区别
你可能用过虚拟机,比如VMware或者VirtualBox。虚拟机就像是在你电脑里再装一台完整的电脑,要分配内存、硬盘,还要装操作系统,占用资源大,启动也慢。
Docker容器则不一样,它直接复用你电脑的系统内核,只是把你的应用和依赖隔离出来。打个比方:
- 虚拟机就像买了一套房子,里面有完整的厨房、卧室、卫生间
- Docker容器就像租了一个单间,只需要和其他租客共享厨房和卫生间
| 特性 | 虚拟机 | Docker容器 |
|---|---|---|
| 启动时间 | 几分钟 | 几秒钟 |
| 占用空间 | 几个GB | 几十到几百MB |
| 资源消耗 | 大 | 小 |
| 隔离性 | 完全隔离 | 共享内核 |
| 操作系统 | 完整系统 | 共享宿主机内核 |
Docker的应用场景
Docker在实际工作中有非常多的应用场景:
1. 开发和测试环境统一
团队里十个人,可能有人用Windows,有人用Mac,有人用Ubuntu。如果每个人都按自己的方式搭建开发环境,那”环境问题”就会成为开发的最大障碍。
用Docker后,大家使用相同的容器镜像,确保每个人的开发环境完全一致。
2. 持续集成和持续部署(CI/CD)
在自动化部署中,Docker可以把应用打包成镜像,推送到服务器,然后用同样的镜像启动容器。整个过程可重复、可追溯。
3. 微服务架构
微服务把一个大应用拆成多个小服务,每个服务独立开发、独立部署。每个微服务可以打包成一个或多个Docker容器,灵活扩展。
4. 快速搭建学习环境
想学Redis?直接docker run redis。想学MySQL?docker run mysql。再也不用担心安装配置问题。
Docker核心概念详解
在深入实践之前,我们先来理解Docker的三个核心概念:镜像(Image)、容器(Container)和仓库(Repository)。
镜像
镜像你可以理解成是一个”模具”,它定义了运行某个应用需要的所有东西:
- 代码和依赖
- 系统工具和库
- 环境变量
- 配置文件
镜像是只读的,一旦创建就不能修改。就像一个模具,可以用来铸造出多个相同的铸件。
常见的镜像命名格式是镜像名:标签,比如:
ubuntu:20.04– Ubuntu操作系统的20.04版本python:3.11– Python 3.11运行环境nginx:latest– 最新版本的Nginx
容器
容器就是镜像的”实例”。你可以把镜像理解成类,容器理解成对象——类是用来定义模板的,对象是真正在运行的实体。
同一个镜像可以创建多个容器,每个容器都是独立的。
仓库
仓库就是存储和分发镜像的地方。最常用的就是Docker Hub,它是Docker官方维护的”应用商店”,里面有海量的官方镜像和社区镜像。
类比一下:
- 镜像就像软件
- 仓库就像应用商店
安装Docker
Windows系统
- 确认系统要求
- Windows 10专业版/企业版或更高(需要支持WSL2)
- 开启BIOS虚拟化(VT-x/AMD-V)
- 下载Docker Desktop
访问官网下载:https://www.docker.com/products/docker-desktop - 安装
- 双击安装包,按提示一路下一步
- 安装程序会自动启用WSL2和Hyper-V
- 验证安装
安装完成后,Docker会自动启动,你会在任务栏看到一个鲸鱼图标。右键点击图标,选择”Dashboard”可以打开Docker管理界面。
macOS系统
- 下载Docker Desktop for Mac
官网下载对应芯片版本(Apple M1/M2用ARM64版,Intel芯片用AMD64版) - 安装
- 把Docker拖到Applications文件夹
- 首次启动可能需要输入密码授权
- 验证
打开终端,输入docker version,看到版本信息就说明安装成功了。
Linux系统(Ubuntu为例)
bash
# 更新apt源
sudo apt-get update
# 安装依赖包
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加Docker仓库
echo "deb [arch=amd64 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-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 把当前用户加入docker组(避免每次sudo)
sudo usermod -aG docker $USER
# 验证安装
docker run hello-world
第一个Docker容器
安装完成后,我们来运行第一个容器,感受一下Docker的神奇之处。
打开终端(Windows打开PowerShell或CMD),输入:
bash
docker run hello-world
如果一切正常,你会看到类似这样的输出:
plaintext
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:abc123...
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
这行命令做了三件事:
- 检查本地是否有hello-world镜像
- 没有的话,从Docker Hub下载(Pull)
- 用这个镜像创建并启动一个容器
Docker常用命令
镜像相关命令
bash
# 查看本地所有镜像
docker images
# 搜索镜像
docker search nginx
# 下载镜像
docker pull nginx:latest
# 删除镜像
docker rmi nginx:latest
# 构建镜像(后面会详细讲)
docker build -t my-app .
容器相关命令
bash
# 列出正在运行的容器
docker ps
# 列出所有容器(包括已停止的)
docker ps -a
# 启动容器
docker start container_id
# 停止容器
docker stop container_id
# 重启容器
docker restart container_id
# 删除容器
docker rm container_id
# 进入容器内部(类似SSH登录)
docker exec -it container_id /bin/bash
# 查看容器日志
docker logs container_id
# 实时查看日志
docker logs -f container_id
实战:部署一个Python Web应用
光说不练假把式,现在我们来实战一下,用Docker部署一个Flask Web应用。
步骤1:创建项目结构
首先创建一个项目文件夹:
bash
mkdir my-web-app
cd my-web-app
在文件夹里创建以下文件:
app.py – 我们的Web应用:
python
from flask import Flask, jsonify
import os
import socket
app = Flask(__name__)
@app.route('/')
def hello():
name = os.environ.get('NAME', 'Developer')
hostname = socket.gethostname()
return f'''
<h1>Hello {name}!</h1>
<p>Welcome to Docker!</p>
<p>Hostname: {hostname}</p>
'''
@app.route('/api/health')
def health():
return jsonify({
'status': 'healthy',
'service': 'my-web-app'
})
@app.route('/api/info')
def info():
return jsonify({
'python_version': os.sys.version,
'platform': os.name
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
requirements.txt – Python依赖:
plaintext
flask==2.3.0
gunicorn==20.1.0
Dockerfile – 这是关键文件,定义了我们如何构建镜像:
dockerfile
# 指定基础镜像
FROM python:3.11-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件到容器
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY app.py .
# 设置环境变量
ENV NAME=Developer
ENV FLASK_ENV=production
# 暴露端口
EXPOSE 5000
# 启动命令(生产环境用gunicorn)
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]
步骤2:构建镜像
在项目文件夹里运行:
bash
docker build -t my-web-app .
-t参数给镜像起个名字,后面的.表示Dockerfile在当前目录。
构建过程会输出很多日志,耐心等待即可。完成后用docker images查看:
bash
docker images
# 输出类似:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-web-app latest a1b2c3d4e5f6 10 seconds ago 150MB
python 3.11-slim a1b2c3d4e5f7 3 days ago 150MB
步骤3:运行容器
bash
# 前台运行(方便查看日志)
docker run -p 5000:5000 --name my-app my-web-app
# 或后台运行
docker run -d -p 5000:5000 --name my-app my-web-app
参数说明:
-d:后台运行(detached模式)-p 5000:5000:把容器的5000端口映射到主机的5000端口--name my-app:给容器起个名字my-web-app:使用哪个镜像
现在打开浏览器访问http://localhost:5000,你应该能看到欢迎页面。
步骤4:常用操作
bash
# 查看运行中的容器
docker ps
# 查看所有容器
docker ps -a
# 停止容器
docker stop my-app
# 启动已停止的容器
docker start my-app
# 重启容器
docker restart my-app
# 查看容器日志
docker logs my-app
# 实时查看日志
docker logs -f my-app
# 删除容器
docker rm my-app
# 查看容器详细信息
docker inspect my-app
Docker Compose:管理多容器应用
当你需要运行多个容器时(比如Web应用+数据库+缓存),一个个启动就很麻烦了。Docker Compose就是来解决这个问题的。
安装Docker Compose
Docker Desktop已经自带了Docker Compose。如果你用的是Linux:
bash
sudo apt-get install docker-compose
或者使用插件版本(推荐):
bash
sudo apt-get install docker-compose-plugin
创建docker-compose.yml
在项目目录创建docker-compose.yml:
yaml
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- NAME=Developer
- REDIS_HOST=redis
volumes:
- .:/app
depends_on:
- redis
restart: unless-stopped
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
restart: unless-stopped
volumes:
redis-data:
这个配置定义了两个服务:
- web:我们的Python应用
- redis:Redis缓存服务
使用Docker Compose
bash
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止所有服务
docker-compose down
# 重新构建并启动
docker-compose up --build -d
# 只启动某个服务
docker-compose up -d redis
Docker Hub:分享和获取镜像
Docker Hub是Docker官方维护的镜像仓库,里面有海量的官方镜像和社区镜像。
常用官方镜像
| 镜像名 | 说明 | 使用场景 |
|---|---|---|
| nginx | Web服务器 | 静态网站、反向代理 |
| redis | 内存数据库 | 缓存、Session存储 |
| mysql | MySQL数据库 | 关系型数据存储 |
| postgres | PostgreSQL数据库 | 高级关系型数据存储 |
| mongo | MongoDB数据库 | 文档型数据存储 |
| node | Node.js运行环境 | JavaScript后端开发 |
| python | Python运行环境 | Python开发 |
| postgres | PostgreSQL数据库 | 企业级数据库 |
部署一个完整博客系统
光跑个Hello World还不够过瘾,我们来部署一个真实的博客系统——Ghost。
bash
docker run -d \
--name ghost-blog \
-p 3001:2368 \
-e NODE_ENV=production \
-e url=http://localhost:3001 \
-e mail__transport=SMTP \
-e mail__options__host=smtp.example.com \
-e mail__options__port=587 \
-e mail__options__auth__user=you@example.com \
-e mail__options__auth__pass=yourpassword \
ghost:latest
现在访问http://localhost:3001/ghost,你就能看到Ghost博客的管理界面了!
进阶:优化Dockerfile
写Dockerfile也是有讲究的,好的Dockerfile能让镜像更小、构建更快。
使用多阶段构建
dockerfile
# 第一阶段:构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# 第二阶段:运行
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
多阶段构建可以显著减小最终镜像大小,因为构建工具不会被包含在最终镜像中。
使用.dockerignore
在项目根目录创建.dockerignore文件,排除不需要的文件:
plaintext
node_modules
.git
.gitignore
*.md
Dockerfile
.dockerignore
.env*
npm-debug.log
镜像大小优化技巧
- 使用合适的基础镜像:Alpine镜像比Ubuntu小很多
- 合并RUN指令:减少镜像层数
- 清理缓存:pip安装后删除缓存
- 使用多阶段构建:分离构建和运行环境
常见问题解答
1. Docker下载镜像太慢怎么办?
配置国内镜像加速。在Docker Desktop设置中添加镜像源:
- 阿里云镜像:https://mirror.ccs.tencentyun.com
- 中科大镜像:https://docker.mirrors.ustc.edu.cn
- 网易镜像:https://hub-mirror.c.163.com
或者编辑/etc/docker/daemon.json(Linux):
json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn"
]
}
修改后重启Docker服务:
bash
sudo systemctl restart docker
2. 容器里改文件后,主机上看不到?
使用数据卷挂载:
bash
docker run -v /path/on/host:/path/in/container ...
这样容器内的文件和主机实时同步,修改立即生效。
3. 容器怎么和主机网络通信?
Docker会创建一个虚拟网络(bridge网络),默认情况下:
- 容器之间可以通过容器名互相访问
- 容器可以通过网关访问主机和外网
- 主机通过端口映射访问容器
4. 如何在容器内使用GPU?
安装nvidia-container-toolkit:
bash
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install nvidia-container-toolkit
sudo systemctl restart docker
然后运行时加上--gpus all参数:
bash
docker run --gpus all nvidia/cuda:11.0-base nvidia-smi
5. 容器自动退出了怎么办?
检查日志找出原因:
bash
docker logs container_id
常见原因:
- 应用代码报错
- 缺少环境变量
- 端口被占用
- 配置文件错误
总结
Docker其实没那么可怕,它就是一个帮你管理”装软件”问题的工具。通过今天的教程,你应该已经掌握了:
- Docker的基本概念(镜像、容器、仓库)
- 安装Docker的不同平台方法
- 构建自己的Docker镜像
- 运行和管理容器
- 使用Docker Compose管理多容器应用
- Dockerfile的优化技巧
- 常见问题的解决方法
Docker是现代云原生开发的基础,学会它你就迈出了成为DevOps工程师的第一步。不管你是前端、后端还是运维工程师,了解Docker都能让你的工作更加高效。
相关推荐:
Docker,让”在我这儿能跑”不再是问题!

发表回复