从零到一:Docker核心命令实战手册与避坑指南
2026/5/16 16:56:20 网站建设 项目流程

1. Docker入门:从安装到第一个容器

第一次接触Docker时,我完全被各种新概念搞晕了——镜像、容器、仓库,这些到底是什么关系?后来我发现用快递仓库来比喻特别形象:镜像是打包好的快递,容器是正在运输中的快递,而仓库就是存放快递的物流中心。下面我就用最直白的语言,带你快速上手Docker。

安装Docker其实比想象中简单。以Ubuntu系统为例,只需要在终端执行这几条命令:

sudo apt update sudo apt install docker.io sudo systemctl start docker sudo docker run hello-world

如果看到"Hello from Docker!"的提示,说明安装成功了。这里有个新手常踩的坑:忘记加sudo权限。Docker默认需要root权限,如果不想每次都加sudo,可以把当前用户加入docker组:

sudo usermod -aG docker $USER

执行完需要重新登录才能生效。我刚开始用时经常忘记这步,每次报错都以为是安装出了问题。

验证安装后,我们来运行第一个真正的容器。比如想用Nginx搭建网站,传统方式要配置环境、解决依赖,用Docker只需一行命令:

docker run -d -p 8080:80 --name my_nginx nginx

这行命令做了三件事:从仓库拉取nginx镜像(如果本地没有)、创建容器、启动服务。参数解释:

  • -d让容器在后台运行
  • -p 8080:80把容器的80端口映射到主机的8080
  • --name给容器起个名字

打开浏览器访问localhost:8080,就能看到Nginx的欢迎页面。这种秒级部署的体验,正是Docker最迷人的地方。

2. 镜像管理:从搜索到自定义

镜像就像软件的安装包,但比安装包更强大。它不仅包含软件本身,还有完整的运行环境。管理镜像是Docker使用的核心技能,我整理了几个最常用的场景。

查找镜像时,别急着用百度。Docker Hub是官方仓库,可以直接命令行搜索:

docker search mysql

搜索结果会显示星级、是否官方镜像等关键信息。建议优先选择OFFICIAL标注的官方镜像,比如mysql、nginx这些,质量和安全性更有保障。

下载镜像要特别注意版本控制。很多人直接docker pull mysql,这会下载latest标签的版本。在生产环境这是非常危险的做法,因为新版本可能不兼容。正确的做法是明确指定版本:

docker pull mysql:5.7

下载后查看本地镜像列表:

docker images

输出类似这样:

REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 c20987f18b13 2 weeks ago 448MB ubuntu latest ba6acccedd29 2 months ago 72.8MB

随着使用时间增长,镜像会占用大量磁盘空间。清理时要注意:

  • docker rmi删除单个镜像
  • docker image prune清理悬空镜像
  • docker system df查看磁盘使用情况

最实用的技巧是自定义镜像。比如需要在Ubuntu基础上安装Python环境,可以写Dockerfile:

FROM ubuntu:20.04 RUN apt update && apt install -y python3 CMD ["python3"]

然后构建镜像:

docker build -t my_python .

这样就能拥有一个开箱即用的Python环境。Dockerfile的更多用法我们后面会详细展开。

3. 容器操作:从启动到持久化

容器是镜像的运行实例,理解容器生命周期管理是日常使用的关键。下面这些命令我每天都要用上好几遍。

启动容器时,docker run是最常用的命令,但参数组合很有讲究。比如开发Web应用时,我常用这样的组合:

docker run -d -p 3000:3000 -v $(pwd):/app --name my_app node:14

这里新出现了-v参数,它把主机当前目录挂载到容器的/app目录,实现文件实时同步。这对开发调试特别有用,修改代码后容器内立即生效。

查看运行中的容器:

docker ps

查看所有容器(包括已停止的):

docker ps -a

进入容器有两种方式:

  1. docker attach直接附加到主进程,退出会导致容器停止
  2. docker exec更推荐的方式,可以开新终端进入

比如要调试正在运行的容器:

docker exec -it my_app /bin/bash

-it参数让我们可以交互式操作,就像SSH到服务器一样。调试完成后exit退出,不会影响容器运行。

数据持久化是容器使用中的重点。容器本身是临时的,删除后所有更改都会丢失。持久化数据有三种方式:

  1. 挂载主机目录(-v /host/path:/container/path)
  2. 使用数据卷(docker volume create)
  3. 数据卷容器

最简单的还是直接挂载主机目录,比如数据库数据:

docker run -d -v /data/mysql:/var/lib/mysql mysql:5.7

这样即使容器删除,数据仍然保存在主机上。我曾经因为没做数据持久化,丢过一整天的测试数据,这个教训特别深刻。

4. 高级技巧:网络与多容器编排

当需要运行多个关联的容器时,比如Web应用+数据库,就需要用到Docker网络和编排技巧了。

容器网络默认是隔离的,但可以通过多种方式互联:

  • --link参数(已过时,不推荐)
  • 自定义网络(推荐方式)

创建自定义网络:

docker network create my_network

然后运行容器时加入同一网络:

docker run -d --net=my_network --name db mysql:5.7 docker run -d --net=my_network -p 3000:3000 --name web my_web_app

这样web容器就可以直接用db作为主机名访问数据库,不需要知道具体IP。这种基于服务名的发现机制,是微服务架构的基础。

多容器管理推荐使用docker-compose。用一个yml文件定义所有服务,比如:

version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"

然后一键启动:

docker-compose up -d

这种方式把复杂的容器关系声明化,特别适合开发测试环境。我在团队中推广后,新成员搭建环境的时间从半天缩短到10分钟。

性能监控也很重要。查看容器资源占用:

docker stats

查看容器日志:

docker logs -f my_container

-f参数可以实时跟踪日志输出,调试时非常有用。记得定期清理日志,防止磁盘爆满。

5. 避坑指南:常见问题解决

在长期使用Docker的过程中,我踩过不少坑,这里总结几个典型问题的解决方案。

端口冲突是最常见的问题。比如运行容器时报错"端口已被占用",可以:

  1. 更改主机端口:-p 8081:80
  2. 停止占用端口的服务
  3. 使用netstat -tulnp找出占用进程

磁盘空间不足也是个头疼的问题。Docker默认把所有东西都存在/var/lib/docker目录。清理时可以:

docker system prune

这会删除所有停止的容器、悬空镜像和网络。更彻底的清理:

docker system prune -a

但要注意这会删除所有未被使用的镜像,慎用!

容器时区问题经常被忽略。默认容器使用UTC时间,要使用本地时间可以:

docker run -v /etc/localtime:/etc/localtime:ro ...

或者构建镜像时设置时区:

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

权限问题也经常遇到。容器内进程默认以root运行,如果挂载了主机目录,可能导致权限混乱。解决方案:

  1. 运行时指定用户:-u $(id -u):$(id -g)
  2. 在Dockerfile中创建特定用户

最后提醒一点:生产环境一定要设置容器重启策略,比如:

docker run --restart unless-stopped ...

这样即使宿主机重启,容器也会自动恢复。我曾经因为没设置这个,半夜被报警叫起来手动重启服务。

6. 实战案例:开发到部署的全流程

用一个实际项目演示Docker的完整使用流程。假设我们要开发一个Python Flask应用,使用MySQL数据库。

开发阶段的Dockerfile:

FROM python:3.8-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["gunicorn", "-b :5000", "app:app"]

对应的docker-compose.yml:

version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/app depends_on: - db db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:

开发时只需运行:

docker-compose up

代码修改会实时生效,数据库数据持久化保存。

测试阶段可以构建专门用于测试的镜像:

FROM development_image RUN pip install pytest COPY tests . CMD ["pytest"]

生产部署则需要优化镜像:

FROM python:3.8-slim as builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt FROM python:3.8-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH CMD ["gunicorn", "-b :5000", "--workers=4", "app:app"]

这种多阶段构建能显著减小镜像体积。最后用docker-compose.prod.yml部署:

version: '3' services: web: build: . ports: - "80:5000" deploy: replicas: 3 db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:

部署命令:

docker stack deploy -c docker-compose.prod.yml my_app

这套流程从开发到生产保持环境一致,真正实现了"一次构建,到处运行"。我在多个项目中实践后,部署效率提升了70%以上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询