Docker 完全操作指南
📚 目录
1. Docker 基础命令
1.1 镜像管理
bash
# 查看本地所有镜像
docker images
docker image ls
# 搜索远程仓库中的镜像
docker search ubuntu
docker search mysql
# 拉取镜像
docker pull ubuntu:22.04
docker pull mysql:8.0
# 删除镜像
docker rmi 镜像名:标签
docker rmi 镜像ID
# 删除所有未使用的镜像
docker image prune -a
1.2 容器管理
bash
# 查看容器
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器(包括已停止的)
docker ps -aq # 只显示容器ID
# 创建并运行容器
docker run 镜像名 # 最基本运行
docker run -d 镜像名 # 后台运行
docker run -it 镜像名 bash # 交互式运行
docker run --name 容器名 镜像名 # 指定容器名称
# 端口映射
docker run -p 宿主机端口:容器端口 镜像名
# 停止/启动容器
docker stop 容器名/ID
docker start 容器名/ID
docker restart 容器名/ID
# 删除容器
docker rm 容器名/ID
docker rm -f 容器名/ID # 强制删除运行中的容器
# 进入容器
docker exec -it 容器名 bash
docker attach 容器名
# 查看容器日志
docker logs 容器名
docker logs -f 容器名 # 实时跟踪日志
docker logs --tail 100 容器名 # 查看最后100行
1.3 其他常用命令
bash
# 查看容器/镜像详细信息
docker inspect 容器名/镜像名
# 查看容器资源使用情况
docker stats
# 查看Docker磁盘使用情况
docker system df
# 清理未使用的资源
docker system prune -a
2. 查看和拉取镜像
2.1 Ubuntu 系统镜像
查看可用的 Ubuntu 版本:
bash
# 在 Docker Hub 搜索 Ubuntu 镜像
docker search ubuntu --limit 10
# 或者直接在浏览器访问:
# https://hub.docker.com/_/ubuntu
常用 Ubuntu 标签:
| 标签 | 说明 | 大小 |
|---|---|---|
ubuntu:latest |
最新版 Ubuntu | ~78MB |
ubuntu:22.04 |
Ubuntu 22.04 (Jammy) | ~78MB |
ubuntu:20.04 |
Ubuntu 20.04 (Focal) | ~72MB |
ubuntu:18.04 |
Ubuntu 18.04 (Bionic) | ~63MB |
拉取 Ubuntu 镜像:
bash
# 拉取最新版
docker pull ubuntu:latest
# 拉取指定版本
docker pull ubuntu:22.04
docker pull ubuntu:20.04
docker pull ubuntu:18.04
# 拉取精简版
docker pull ubuntu:22.04-minimal
2.2 MySQL 镜像
查看可用的 MySQL 版本:
bash
# 搜索 MySQL 镜像
docker search mysql --limit 10
# 查看所有可用标签
# https://hub.docker.com/_/mysql/tags
常用 MySQL 标签:
| 标签 | 说明 | 大小 |
|---|---|---|
mysql:latest |
最新版 MySQL | ~600MB |
mysql:8.0 |
MySQL 8.0 系列 | ~600MB |
mysql:8.0.31 |
MySQL 8.0.31 特定版本 | ~600MB |
mysql:5.7 |
MySQL 5.7 系列 | ~500MB |
mysql:5.6 |
MySQL 5.6 系列 | ~500MB |
拉取 MySQL 镜像:
bash
# 拉取最新版
docker pull mysql:latest
# 拉取指定版本
docker pull mysql:8.0
docker pull mysql:8.0.31
docker pull mysql:5.7
3. 镜像的导出与导入
3.1 从一台机器导出镜像
方法一:使用 docker save 导出为 tar 文件
bash
# 查看本地镜像
docker images
# 导出单个镜像
docker save -o ubuntu-22.04.tar ubuntu:22.04
docker save -o mysql-8.0.tar mysql:8.0
# 导出多个镜像到同一个文件
docker save -o multiple-images.tar ubuntu:22.04 mysql:8.0
# 使用 gzip 压缩导出(推荐,体积更小)
docker save ubuntu:22.04 | gzip > ubuntu-22.04.tar.gz
方法二:使用 docker export 导出容器(包含容器内的修改)
bash
# 先创建一个容器并做一些修改
docker run -it --name my-ubuntu ubuntu:22.04 bash
# 在容器内安装软件、修改文件等操作后退出
# 将容器导出为 tar 文件
docker export -o my-ubuntu-container.tar my-ubuntu
# 压缩导出
docker export my-ubuntu | gzip > my-ubuntu-container.tar.gz
3.2 在另一台机器导入镜像
方法一:使用 docker load 导入镜像
bash
# 将 tar 文件复制到目标机器
# scp ubuntu-22.04.tar user@另一台机器:/path/
# 导入镜像
docker load -i ubuntu-22.04.tar
docker load < ubuntu-22.04.tar
# 导入压缩文件
gunzip -c ubuntu-22.04.tar.gz | docker load
方法二:使用 docker import 导入容器
bash
# 导入容器 tar 文件为镜像
cat my-ubuntu-container.tar | docker import - my-ubuntu:custom
# 或者
docker import my-ubuntu-container.tar my-ubuntu:custom
3.3 导出与导入的区别
| 操作 | docker save / docker load |
docker export / docker import |
|---|---|---|
| 对象 | 镜像 | 容器 |
| 保留历史 | ✅ 保留镜像层历史和元数据 | ❌ 不保留历史,扁平化 |
| 保留配置 | ✅ 保留 ENTRYPOINT、CMD 等 | ❌ 需要重新指定 |
| 文件大小 | 较大 | 较小 |
| 适用场景 | 镜像备份、分发 | 分享容器快照 |
4. 容器操作详解
4.1 Ubuntu 容器操作
创建并运行 Ubuntu 容器:
bash
# 基本运行(退出后容器停止)
docker run ubuntu:22.04 echo "Hello World"
# 交互式运行(可长期运行)
docker run -it --name ubuntu-dev ubuntu:22.04 bash
# 后台运行并保持(分配伪终端)
docker run -dit --name ubuntu-server ubuntu:22.04 bash
# 带目录挂载的运行
docker run -it --name ubuntu-work \
-v /宿主机/路径:/容器/路径 \
ubuntu:22.04 bash
在 Ubuntu 容器中安装软件:
bash
# 进入容器
docker exec -it ubuntu-dev bash
# 更新软件源并安装软件
apt-get update
apt-get install -y vim curl wget git net-tools
apt-get install -y python3 python3-pip
apt-get install -y build-essential
# 安装完成后退出
exit
将修改后的容器保存为新镜像:
bash
# 将容器提交为新镜像
docker commit ubuntu-dev my-ubuntu:with-tools
# 查看新镜像
docker images | grep my-ubuntu
4.2 MySQL 容器操作
创建并运行 MySQL 容器:
bash
# 基础运行(开发测试)
docker run -d \
--name mysql-dev \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
mysql:8.0
# 生产环境运行(数据持久化)
docker run -d \
--name mysql-prod \
--restart always \
-e MYSQL_ROOT_PASSWORD=YourStrongPassword \
-e MYSQL_DATABASE=appdb \
-e MYSQL_USER=appuser \
-e MYSQL_PASSWORD=userpass \
-p 3307:3306 \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/conf:/etc/mysql/conf.d \
-v /data/mysql/logs:/var/log/mysql \
mysql:8.0 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
环境变量说明:
| 环境变量 | 作用 |
|---|---|
MYSQL_ROOT_PASSWORD |
设置 root 密码(必须) |
MYSQL_DATABASE |
自动创建指定数据库 |
MYSQL_USER |
创建普通用户 |
MYSQL_PASSWORD |
设置普通用户密码 |
MYSQL_ALLOW_EMPTY_PASSWORD |
允许空密码 |
MYSQL_RANDOM_ROOT_PASSWORD |
随机生成 root 密码 |
5. MySQL 容器配置
5.1 连接 MySQL 容器
bash
# 方法1:从容器内连接
docker exec -it mysql-prod mysql -u root -p
# 方法2:从宿主机连接(需要安装 mysql-client)
mysql -h 127.0.0.1 -P 3307 -u root -p
# 方法3:使用 docker exec 直接执行命令
docker exec mysql-prod mysql -u root -pYourStrongPassword -e "SHOW DATABASES;"
5.2 配置 MySQL
方法1:通过环境变量配置(简单)
bash
docker run -d \
--name mysql-config \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=testdb \
-e MYSQL_USER=test \
-e MYSQL_PASSWORD=test123 \
mysql:8.0
方法2:通过配置文件挂载(推荐)
创建配置文件 my.cnf:
ini
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default_authentication_plugin=mysql_native_password
max_connections=1000
innodb_buffer_pool_size=1G
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
[client]
default-character-set=utf8mb4
启动容器:
bash
docker run -d \
--name mysql-custom \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
-v /path/to/my.cnf:/etc/mysql/conf.d/my.cnf \
-v /data/mysql/data:/var/lib/mysql \
mysql:8.0
5.3 MySQL 备份与恢复
bash
# 备份所有数据库
docker exec mysql-prod mysqldump -u root -pYourStrongPassword --all-databases > /backup/all.sql
# 备份单个数据库
docker exec mysql-prod mysqldump -u root -pYourStrongPassword appdb > /backup/appdb.sql
# 压缩备份
docker exec mysql-prod mysqldump -u root -pYourStrongPassword appdb | gzip > appdb.sql.gz
# 恢复数据库
cat /backup/appdb.sql | docker exec -i mysql-prod mysql -u root -pYourStrongPassword appdb
# 从压缩文件恢复
gunzip -c appdb.sql.gz | docker exec -i mysql-prod mysql -u root -pYourStrongPassword appdb
6. 将程序打包成镜像
6.1 准备你的程序
假设你的程序结构如下:
myapp/
├── app.py # Python 主程序
├── requirements.txt # Python 依赖
├── static/ # 静态文件
├── templates/ # 模板文件
└── config/ # 配置文件
6.2 编写 Dockerfile
创建 Dockerfile:
dockerfile
# 使用 Ubuntu 作为基础镜像
FROM ubuntu:22.04
# 设置环境变量
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
ENV PYTHONUNBUFFERED=1
# 设置工作目录
WORKDIR /app
# 更新软件源并安装依赖
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
python3-venv \
curl \
vim \
net-tools \
&& ln -s /usr/bin/python3 /usr/bin/python \
&& ln -s /usr/bin/pip3 /usr/bin/pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件并安装 Python 包
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用程序代码
COPY . .
# 创建日志目录
RUN mkdir -p /app/logs
# 暴露应用端口
EXPOSE 5000
# 设置启动命令
CMD ["python", "app.py"]
6.3 创建 requirements.txt
txt
flask==2.3.0
gunicorn==21.2.0
pymysql==1.1.0
redis==5.0.0
requests==2.31.0
6.4 简单的示例程序 app.py
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, jsonify
import os
import socket
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify({
'message': 'Hello from Docker!',
'hostname': socket.gethostname(),
'version': '1.0.0'
})
@app.route('/health')
def health():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port, debug=False)
6.5 构建镜像
bash
# 进入项目目录
cd myapp
# 构建镜像
docker build -t myapp:1.0.0 .
# 构建时指定 Dockerfile
docker build -f Dockerfile -t myapp:1.0.0 .
# 构建并添加标签
docker build -t myapp:1.0.0 -t myapp:latest .
# 查看构建的镜像
docker images | grep myapp
6.6 运行容器
bash
# 基础运行
docker run -d \
--name myapp-dev \
-p 5000:5000 \
myapp:1.0.0
# 带环境变量的运行
docker run -d \
--name myapp-prod \
--restart always \
-p 8080:5000 \
-e PORT=5000 \
-e ENV=production \
-v /data/myapp/logs:/app/logs \
myapp:1.0.0
# 查看运行状态
docker ps | grep myapp
docker logs myapp-prod
# 测试应用
curl http://localhost:8080
6.7 多阶段构建(优化镜像大小)
dockerfile
# 构建阶段
FROM ubuntu:22.04 AS builder
WORKDIR /build
# 安装编译依赖
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& apt-get clean
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# 运行阶段
FROM ubuntu:22.04
WORKDIR /app
# 只复制需要的文件
COPY --from=builder /root/.local /root/.local
COPY . .
# 设置 PATH
ENV PATH=/root/.local/bin:$PATH
EXPOSE 5000
CMD ["python", "app.py"]
6.8 使用 docker-compose 编排
创建 docker-compose.yml:
yaml
version: '3.8'
services:
app:
build: .
container_name: myapp
restart: always
ports:
- "8080:5000"
environment:
- ENV=production
- DB_HOST=mysql
- REDIS_HOST=redis
volumes:
- ./logs:/app/logs
depends_on:
- mysql
- redis
networks:
- app-network
mysql:
image: mysql:8.0
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: appdb
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3307:3306"
networks:
- app-network
redis:
image: redis:7-alpine
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- app-network
volumes:
mysql-data:
redis-data:
networks:
app-network:
driver: bridge
启动多容器应用:
bash
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止所有服务
docker-compose down
# 重新构建并启动
docker-compose up -d --build
6.9 镜像优化技巧
dockerfile
# 1. 使用 .dockerignore 文件
# .dockerignore 内容:
.git
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env/
venv/
.env
.DS_Store
docker-compose.yml
README.md
.gitignore
# 2. 合并 RUN 命令减少层数
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 3. 使用更小的基础镜像
FROM python:3.9-slim # 比 ubuntu + python 安装更小
FROM alpine:latest # 最小化的 Linux
# 4. 多阶段构建
FROM golang:1.20 AS builder
COPY main.go .
RUN go build -o app main.go
FROM alpine:latest
COPY --from=builder /go/app /app
CMD ["/app"]
📋 常用命令速查表
| 操作 | 命令 |
|---|---|
| 查看镜像 | docker images |
| 拉取镜像 | docker pull 镜像名:标签 |
| 删除镜像 | docker rmi 镜像ID |
| 查看容器 | docker ps -a |
| 创建容器 | docker run -d --name 容器名 镜像名 |
| 进入容器 | docker exec -it 容器名 bash |
| 查看日志 | docker logs -f 容器名 |
| 停止容器 | docker stop 容器名 |
| 删除容器 | docker rm -f 容器名 |
| 导出镜像 | docker save -o 文件.tar 镜像名 |
| 导入镜像 | docker load -i 文件.tar |
| 构建镜像 | docker build -t 镜像名:标签 . |
| 查看网络 | docker network ls |
| 查看卷 | docker volume ls |
| 清理 | docker system prune -a |
🔍 常见问题解决
问题1:容器启动后立即退出
原因 :主进程没有保持运行
解决:
bash
# 使用 -it 参数交互式运行
docker run -it ubuntu:22.04 bash
# 或使用 tail -f
docker run -d ubuntu:22.04 tail -f /dev/null
问题2:无法拉取镜像
原因 :网络问题
解决:
bash
# 配置镜像加速器
sudo vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
sudo systemctl restart docker
问题3:容器内无法联网
原因 :DNS 配置问题
解决:
bash
# 启动容器时指定 DNS
docker run --dns 114.114.114.114 ubuntu:22.04
# 或在 daemon.json 中配置
{
"dns": ["114.114.114.114", "8.8.8.8"]
}
这个文档涵盖了 Docker 的常用操作和典型场景。建议从基础命令开始练习,逐步尝试打包自己的程序。如果在使用过程中遇到问题,可以根据错误信息查阅文档或使用 docker 命令 --help 获取帮助。