你有没有遇到过这种情况?
代码在你电脑上跑得好好,部署到服务器就报错。
或者换了台电脑,装了一堆依赖还是跑不起来。
程序员最怕的一句话:“在我这里明明是可以的。”
Docker就是为了解决这个问题而生的。
Docker是什么?
想象一下,你要搬家。
普通的搬家方式:把家具一件件拆了,到新地方再重新组装。组装过程可能出问题,可能少零件,可能装不对。
Docker的方式:把整个房间打包进一个标准集装箱。箱子本身是密封的,里面的一切都是完整的。搬到你任意目的地,开箱即用。
这个集装箱,就是Docker容器。
Docker是一个开源的容器化平台。它让开发者可以把应用和所有依赖打包成一个标准单元,在任何支持Docker的机器上运行。
核心就一句话:一次打包,到处运行。
为什么需要Docker?
问题一:环境不一致
开发用Mac,测试用Linux,生产用云服务器。每台机器的系统版本、依赖库版本都不一样。代码在一个环境能跑,换个环境就出错。
Docker解决了这个痛点。容器里自带完整运行环境,不管宿主机器是什么系统,容器内部永远一致。
问题二:依赖冲突
项目A需要Python 3.8,项目B需要Python 3.11。装在同一台机器上,互相打架。
Docker里每个容器都是隔离的。项目A用Python 3.8的容器,项目B用Python 3.11的容器,互不干扰。
问题三:部署繁琐
以前部署一个应用:装系统、配环境、装依赖、改配置、启服务。一步一步来,容易漏。
Docker部署只需要一条命令:拉取镜像,启动容器。几十秒搞定。
Docker的核心概念
镜像(Image)
镜像就是集装箱的"图纸"。它是一个只读的模板,包含了运行应用所需的所有东西:代码、运行时、库、配置文件。
你可以从镜像创建容器。同一个镜像可以创建多个容器实例。
镜像通常存储在镜像仓库里,最流行的是Docker Hub,相当于代码的GitHub。
容器(Container)
容器是镜像的运行实例。就像房子和样板间的关系——图纸是镜像,建好的房子是容器。
容器是隔离的、轻量的。它共享宿主机的内核,但有自己的文件系统、网络、进程空间。
Dockerfile
Dockerfile是一个文本文件,记录了如何构建镜像。
它告诉你:基于哪个基础镜像、复制哪些文件、安装什么依赖、启动哪个命令。
写好Dockerfile后,Docker会自动按步骤构建出镜像。
仓库(Registry)
仓库存放镜像的地方。Docker Hub是默认的公共仓库,也可以搭建私有仓库。
推送到仓库,别人就能拉取使用。
Docker常用命令
基础操作
# 从仓库拉取镜像
docker pull nginx
# 查看本地所有镜像
docker images
# 运行容器
docker run -d -p 80:80 --name my-nginx nginx
# 查看运行中的容器
docker ps
# 停止容器
docker stop my-nginx
# 删除容器
docker rm my-nginx
# 删除镜像
docker rmi nginx
实用技巧
# 进入运行中的容器
docker exec -it my-nginx bash
# 查看容器日志
docker logs my-nginx
# 查看所有容器(包括已停止的)
docker ps -a
# 重启容器
docker restart my-nginx
# 批量清理停止的容器
docker container prune
Docker能做什么?
本地开发环境
写代码前不用装几十项依赖。拉一个镜像,启动容器,开箱即写。
微服务架构
每个微服务跑在独立容器里,各自独立部署、扩缩容。
CI/CD流水线
代码提交后自动构建镜像、运行测试、部署上线,全程容器化。
跨平台部署
开发环境是Mac,生产环境是Linux。同一个镜像,两边跑起来完全一致。
和虚拟机的区别
很多人会把Docker和虚拟机搞混。
虚拟机是完整的操作系统,启动慢、占用资源大。一台物理机只能跑几个虚拟机。
Docker容器共享宿主机内核,没有独立操作系统。启动秒级,占用资源极小。一台物理机可以跑成百上千个容器。
打个比方:虚拟机是盖一栋独立房子, Docker是在一栋大楼里隔出独立房间。
总结
Docker的本质是容器化技术。它把应用和运行环境打包在一起,解决了"环境不一致"这个程序员最头疼的问题。
核心概念记住四个:镜像、容器、Dockerfile、仓库。
常用命令记住五个:pull、run、ps、stop、exec。
掌握了这些,你就已经跨过了Docker的门槛。剩下的就是多练,在实践中熟悉更多高级用法。
你的下一个项目,要不要试试用Docker跑起来?