快速开始
本指南将带你快速上手 Docker,通过实际操作理解 Docker 的基本概念。
运行第一个容器
确保你已经安装了 Docker,然后运行:
docker run hello-world你会看到类似输出:
Hello from Docker!This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.发生了什么?
当你运行 docker run hello-world 时,Docker 执行了以下操作:
- 🔍 在本地查找
hello-world镜像 - ⬇️ 本地没有,从 Docker Hub 下载
- 📦 创建一个新容器
- ▶️ 启动容器并执行程序
- 📝 输出信息到终端
- ⏹️ 容器执行完毕后停止
交互式容器
运行一个 Ubuntu 容器并进入交互模式:
docker run -it ubuntu bash参数说明:
-i: 保持标准输入打开(interactive)-t: 分配一个伪终端(TTY)ubuntu: 使用的镜像名称bash: 在容器中执行的命令
现在你在容器内部了!试试这些命令:
# 查看系统信息cat /etc/os-release
# 查看当前目录pwd
# 创建文件echo "Hello from container" > test.txtcat test.txt
# 退出容器exit运行 Web 服务器
让我们运行一个真实的 web 服务器:
docker run -d -p 8080:80 --name my-nginx nginx参数说明:
-d: 后台运行(detached 模式)-p 8080:80: 端口映射,主机 8080 映射到容器 80--name my-nginx: 给容器命名nginx: 使用的镜像
访问服务
在浏览器中打开 http://localhost:8080,你会看到 Nginx 欢迎页面!
查看运行的容器
# 查看正在运行的容器docker ps
# 输出示例CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESa1b2c3d4e5f6 nginx "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 0.0.0.0:8080->80/tcp my-nginx查看容器日志
docker logs my-nginx停止和启动容器
# 停止容器docker stop my-nginx
# 启动容器docker start my-nginx
# 重启容器docker restart my-nginx删除容器
# 必须先停止容器docker stop my-nginx
# 删除容器docker rm my-nginx
# 或者强制删除(一步完成)docker rm -f my-nginx管理镜像
查看本地镜像
docker images
# 输出示例REPOSITORY TAG IMAGE ID CREATED SIZEnginx latest a6bd71f48f68 2 weeks ago 187MBubuntu latest 08d22c0ceb15 4 weeks ago 77.8MBhello-world latest 9c7a54a9a43c 6 months ago 13.3kB搜索镜像
# 在 Docker Hub 搜索 Redis 相关镜像docker search redis
# 输出示例NAME DESCRIPTION STARS OFFICIALredis Redis is an open source key-value store... 12000 [OK]redislabs/redisearch Redis with RedisSearch module... 500下载镜像
# 下载最新版本docker pull redis
# 下载指定版本docker pull redis:7.2-alpine
# 查看镜像详细信息docker inspect redis删除镜像
# 删除指定镜像docker rmi nginx
# 删除所有未使用的镜像docker image prune -a实战:运行数据库
运行 MySQL
docker run -d \ --name mysql-db \ -e MYSQL_ROOT_PASSWORD=my-secret-pw \ -e MYSQL_DATABASE=myapp \ -p 3306:3306 \ mysql:8连接数据库:
# 使用 MySQL 客户端连接mysql -h 127.0.0.1 -P 3306 -u root -p# 输入密码: my-secret-pw
# 或者进入容器内部docker exec -it mysql-db mysql -u root -p运行 Redis
docker run -d \ --name redis-cache \ -p 6379:6379 \ redis:alpine测试连接:
# 进入容器运行 redis-clidocker exec -it redis-cache redis-cli
# 测试命令127.0.0.1:6379> SET mykey "Hello Docker"OK127.0.0.1:6379> GET mykey"Hello Docker"127.0.0.1:6379> exit运行 PostgreSQL
docker run -d \ --name postgres-db \ -e POSTGRES_PASSWORD=mysecretpassword \ -e POSTGRES_DB=myapp \ -p 5432:5432 \ postgres:15-alpine实战:运行应用
Node.js 应用
创建一个简单的 Node.js 应用:
# 创建项目目录mkdir my-node-app && cd my-node-app
# 创建 app.jscat > app.js << 'EOF'const http = require('http');
const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from Node.js in Docker!\n');});
server.listen(3000, '0.0.0.0', () => { console.log('Server running on port 3000');});EOF
# 创建 Dockerfilecat > Dockerfile << 'EOF'FROM node:18-alpineWORKDIR /appCOPY app.js .EXPOSE 3000CMD ["node", "app.js"]EOF
# 构建镜像docker build -t my-node-app .
# 运行容器docker run -d -p 3000:3000 --name node-app my-node-app
# 测试curl http://localhost:3000Python Flask 应用
# 创建项目目录mkdir my-flask-app && cd my-flask-app
# 创建 app.pycat > app.py << 'EOF'from flask import Flask
app = Flask(__name__)
@app.route('/')def hello(): return 'Hello from Flask in Docker!'
if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)EOF
# 创建 requirements.txtecho "flask==3.0.0" > requirements.txt
# 创建 Dockerfilecat > Dockerfile << 'EOF'FROM python:3.11-slimWORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txtCOPY app.py .EXPOSE 5000CMD ["python", "app.py"]EOF
# 构建和运行docker build -t my-flask-app .docker run -d -p 5000:5000 --name flask-app my-flask-app
# 测试curl http://localhost:5000常用命令速查
容器操作
# 运行容器docker run [OPTIONS] IMAGE [COMMAND]
# 列出容器docker ps # 运行中的容器docker ps -a # 所有容器
# 停止/启动/重启docker stop CONTAINERdocker start CONTAINERdocker restart CONTAINER
# 删除容器docker rm CONTAINERdocker rm -f CONTAINER # 强制删除
# 查看日志docker logs CONTAINERdocker logs -f CONTAINER # 实时查看
# 进入容器docker exec -it CONTAINER bash
# 查看容器详情docker inspect CONTAINER镜像操作
# 列出镜像docker images
# 搜索镜像docker search IMAGE
# 下载镜像docker pull IMAGE
# 删除镜像docker rmi IMAGE
# 构建镜像docker build -t NAME:TAG .
# 查看镜像历史docker history IMAGE清理命令
# 清理停止的容器docker container prune
# 清理未使用的镜像docker image prune
# 清理未使用的卷docker volume prune
# 清理所有未使用的资源docker system prune -a常见问题
1. 端口已被占用
# 错误Error: Bind for 0.0.0.0:8080 failed: port is already allocated
# 解决:使用不同端口docker run -p 8081:80 nginx2. 容器立即退出
# 查看退出原因docker logs CONTAINER_ID
# 以交互模式运行调试docker run -it IMAGE bash3. 无法连接到容器服务
# 确保端口映射正确docker ps # 查看 PORTS 列
# 检查容器内服务是否启动docker logs CONTAINER_ID
# 检查防火墙设置4. 磁盘空间不足
# 查看磁盘使用docker system df
# 清理未使用资源docker system prune -a --volumes下一步
恭喜!你已经掌握了 Docker 的基本操作。接下来可以:
实用技巧
1. 容器别名
# 在 .bashrc 或 .zshrc 中添加alias dps='docker ps'alias dpa='docker ps -a'alias di='docker images'alias drm='docker rm'alias drmi='docker rmi'2. 自动删除容器
# 使用 --rm 参数,容器退出后自动删除docker run --rm -it ubuntu bash3. 后台运行并查看日志
# 后台运行docker run -d --name myapp myimage
# 实时查看日志docker logs -f myapp4. 复制文件
# 从容器复制到主机docker cp CONTAINER:/path/to/file /host/path
# 从主机复制到容器docker cp /host/path CONTAINER:/path/to/file5. 查看资源使用
# 查看所有容器的资源使用情况docker stats
# 查看特定容器docker stats CONTAINER