Docker 入门与实战:从安装到容器管理的完整指南

🚀 Docker 入门与实战:从安装到容器管理的完整指南 🌟


📖 简介

在现代软件开发中,容器化技术已经成为不可或缺的一部分。而 Docker 作为容器化领域的领头羊,以其轻量级、高效和跨平台的特性,深受开发者们的喜爱。本文将带你从零开始,逐步掌握 Docker 的安装、配置以及日常使用技巧,并结合实际案例为你提供一份详实的 Docker 使用指南。无论你是初学者还是有一定经验的开发者,都能从中受益!🚀


🔧 目录

  • [🚀 **Docker 入门与实战:从安装到容器管理的完整指南** 🌟](#🚀 Docker 入门与实战:从安装到容器管理的完整指南 🌟)
    • [📖 **简介**](#📖 简介)
    • [🛠 **安装 Docker**](#🛠 安装 Docker)
      • [**1. 更新系统并安装依赖**](#1. 更新系统并安装依赖)
      • [**2. 添加 Docker 官方 GPG 密钥**](#2. 添加 Docker 官方 GPG 密钥)
      • [**3. 设置 Docker 存储库**](#3. 设置 Docker 存储库)
      • [**4. 安装 Docker 引擎**](#4. 安装 Docker 引擎)
      • [**5. 查看 Docker 和 Docker Compose 版本**](#5. 查看 Docker 和 Docker Compose 版本)
      • [**6. 启动 Docker 服务**](#6. 启动 Docker 服务)
        • [**方法 1:使用 `service` 命令**](#方法 1:使用 service 命令)
        • [**方法 2:使用 `systemctl` 命令**](#方法 2:使用 systemctl 命令)
      • [**7. 验证安装**](#7. 验证安装)
      • [**8. 设置 Docker 服务开机自启**](#8. 设置 Docker 服务开机自启)
    • [📊 **Docker 常用命令**](#📊 Docker 常用命令)
    • [💾 **镜像与容器管理**](#💾 镜像与容器管理)
      • [**1. 查询镜像**](#1. 查询镜像)
      • [**2. 拉取镜像**](#2. 拉取镜像)
      • [**3. 删除镜像**](#3. 删除镜像)
      • [**4. 启动容器**](#4. 启动容器)
      • [**5. 进入容器**](#5. 进入容器)
      • [**6. 复制文件**](#6. 复制文件)
      • [**7. 加载镜像**](#7. 加载镜像)
      • [**8. 创建新镜像**](#8. 创建新镜像)
      • [**9. 保存镜像**](#9. 保存镜像)
      • [**10. 挂载目录**](#10. 挂载目录)
      • [**11. 重命名镜像**](#11. 重命名镜像)
      • [**12. 退出容器**](#12. 退出容器)
    • [⚙️ **解决常见问题**](#⚙️ 解决常见问题)
      • [1. 网络超时问题](#1. 网络超时问题)
        • [**配置 DNS**](#配置 DNS)
        • [**修改 Docker 配置**](#修改 Docker 配置)
          • [**Docker 配置文件解释**](#Docker 配置文件解释)
          • [**Docker 镜像源列表**](#Docker 镜像源列表)
      • [2. 解决 GPG 公钥缺失问题](#2. 解决 GPG 公钥缺失问题)
      • [3. 解决 Docker 权限问题](#3. 解决 Docker 权限问题)
        • [**步骤 1:创建 `docker` 组**](#步骤 1:创建 docker)
        • [**步骤 2:将当前用户添加到 `docker` 组**](#步骤 2:将当前用户添加到 docker)
        • [**步骤 3:注销并重新登录**](#步骤 3:注销并重新登录)
        • [**步骤 4(可选):立即激活组更改**](#步骤 4(可选):立即激活组更改)
        • [**步骤 5:验证权限配置**](#步骤 5:验证权限配置)
        • **注意事项**
      • [4. 配置 Docker 代理以登录 Docker Hub](#4. 配置 Docker 代理以登录 Docker Hub)
        • [**1. 创建 Docker 服务目录和代理配置文件**](#1. 创建 Docker 服务目录和代理配置文件)
        • [**2. 配置代理环境变量**](#2. 配置代理环境变量)
        • [**3. 重新加载配置并重启 Docker 服务**](#3. 重新加载配置并重启 Docker 服务)
        • [**4. 验证代理配置是否生效**](#4. 验证代理配置是否生效)
          • [**测试 1:登录 Docker Hub**](#测试 1:登录 Docker Hub)
          • [**测试 2:拉取镜像**](#测试 2:拉取镜像)
        • [**5. (可选):排除特定地址的代理**](#5. (可选):排除特定地址的代理)
        • **注意事项**
      • [5. 解决 Docker 容器无法启动时的调试与修复方法](#5. 解决 Docker 容器无法启动时的调试与修复方法)
        • [**1. 查看容器日志**](#1. 查看容器日志)
        • [**2. 检查容器配置**](#2. 检查容器配置)
        • [**3. 使用临时容器挂载故障容器的卷**](#3. 使用临时容器挂载故障容器的卷)
        • [**4. 直接编辑容器文件系统**](#4. 直接编辑容器文件系统)
          • [方法 1:挂载容器的文件系统](#方法 1:挂载容器的文件系统)
          • [方法 2:直接修改宿主机上的文件](#方法 2:直接修改宿主机上的文件)
        • [**5. 提交容器为镜像并重新启动**](#5. 提交容器为镜像并重新启动)
        • [**6. 删除并重新创建容器**](#6. 删除并重新创建容器)
        • **避免类似问题的建议**
          • [(1) **挂载代码目录**](#(1) 挂载代码目录)
          • [(2) **分离启动逻辑**](#(2) 分离启动逻辑)
          • [(3) **定期提交更改**](#(3) 定期提交更改)
    • [📋 **Docker Compose 命令详解**](#📋 Docker Compose 命令详解)
    • [**Docker Compose 常用选项**](#Docker Compose 常用选项)
    • [🌟 **实战案例:运行 Flask 应用**](#🌟 实战案例:运行 Flask 应用)
    • [📚 **参考链接**](#📚 参考链接)
    • [🎉 **总结**](#🎉 总结)

🛠 安装 Docker

1. 更新系统并安装依赖

在安装 Docker 之前,确保你的系统是最新的,并安装必要的依赖包。

bash 复制代码
sudo apt-get update
sudo apt-get install ca-certificates curl

2. 添加 Docker 官方 GPG 密钥

为了确保下载的软件包安全,我们需要添加 Docker 的官方 GPG 密钥并设置权限

bash 复制代码
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

如果遇到网络问题、防火墙限制或 SSL 配置问题,可以使用国内镜像源:

curl: (35) OpenSSL SSL_connect: 连接被对方重设 in connection to download.docker.com:443

使用国内镜像源下载 GPG 密钥。例如,清华大学开源镜像站:

bash 复制代码
sudo curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

3. 设置 Docker 存储库

接下来,我们将 Docker 的存储库添加到系统的 APT 源列表中。

bash 复制代码
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

4. 安装 Docker 引擎

更新包索引后,安装 Docker Engine 和相关工具。

bash 复制代码
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

5. 查看 Docker 和 Docker Compose 版本

在安装完成后,可以通过以下命令验证 Docker 和 Docker Compose 是否正确安装并查看其版本信息:

bash 复制代码
docker --version  或 docker -v

输出示例:

Docker version 27.5.1, build 9f9e405

如果你使用的是新版 Docker Compose(从 Docker Desktop 3.4.0 和 Docker Engine 20.10.13 开始,Docker Compose 已被集成到 Docker CLI 中),可以使用以下命令查看版本:

bash 复制代码
docker compose version

输出示例:

Docker Compose version v2.32.4

注意 :旧版独立安装的 Docker Compose 使用 docker-compose --version 查看版本。

6. 启动 Docker 服务

安装完成后,Docker 服务通常会默认自启。如果未启动,可以通过以下命令手动启动 Docker 服务。

方法 1:使用 service 命令
bash 复制代码
sudo service docker start   # 启动 Docker 服务
sudo service docker status  # 查询 Docker 服务状态
方法 2:使用 systemctl 命令
bash 复制代码
sudo systemctl start docker.service   # 启动 Docker 服务
sudo systemctl status docker.service  # 查询 Docker 服务状态

两种方法的区别

  • service 命令:这是一个较老的服务管理工具,兼容性较好,适用于 SysVinit 系统(如较旧的 Ubuntu 版本)。
  • systemctl 命令 :这是 systemd 系统的服务管理工具,适用于现代 Linux 发行版(如 Ubuntu 16.04 及更高版本)。推荐在支持 systemd 的系统中使用 systemctl,因为它功能更强大且更灵活。

7. 验证安装

通过运行一个简单的测试镜像来验证 Docker 是否安装成功。

bash 复制代码
sudo docker run hello-world

如果一切顺利,你将看到类似以下的输出:

Hello from Docker!
This message shows that your installation appears to be working correctly.

8. 设置 Docker 服务开机自启

为了确保 Docker 服务在宿主机启动时自动运行,需要将其设置为开机自启。以下是具体操作步骤:

  1. 检查 Docker 服务状态

    bash 复制代码
    systemctl status docker
  2. 启用 Docker 服务开机自启

    如果未启用开机自启,执行以下命令:

    bash 复制代码
    sudo systemctl enable docker
  3. 验证设置是否生效

    重启宿主机后,检查 Docker 服务是否已自动启动:

    bash 复制代码
    systemctl is-enabled docker

    输出示例:

    enabled
    

📊 Docker 常用命令

命令 描述
docker --versiondocker -v 查看 Docker 的版本信息
docker images 查看本地所有镜像
docker pull <image_name> 从 Docker Hub 拉取镜像
docker rmi <image_id> 删除本地镜像
docker ps 查看正在运行的容器
docker ps -a 查看所有容器(包括已停止的)
docker run -it <image_id> 启动一个新的容器并进入交互模式
docker start <container_id> 启动已停止的容器
docker stop <container_id> 停止正在运行的容器
docker rm <container_id> 删除容器
docker restart <container_id> 重启容器
docker exec -it <container_id> /bin/bash [-c '执行的命令'] 进入正在运行的容器内部并执行命令

启动容器

启动一个新的容器时,可以使用以下命令,并根据需要设置容器名称、运行模式、伪终端分配和端口映射等选项:

bash 复制代码
docker run [OPTIONS] <image_id>
基础设置
  • 指定容器名称--name="name"

    为容器指定一个名称。例如:

    bash 复制代码
    docker run --name=my_container <image_id>
  • 后台运行-d

    后台运行容器,并返回容器 ID。例如:

    bash 复制代码
    docker run -d <image_id>
  • 前台运行-i-t

    前台:-i: 以交互模式运行容器,通常与 -t 一起使用。

    是否分配伪终端:-t: 为容器重新分配一个伪输入终端,通常与-i同时使用

    例如:

    bash 复制代码
    docker run -it <image_id> /bin/bash
网络设置
  • 端口映射-p

    指定主机和容器之间的端口映射关系。例如:

    bash 复制代码
    docker run -p 8000:8000 <image_id>

容器的重启策略

容器的重启策略(RestartPolicy)是一个非常重要的配置项,它决定了容器在退出或宿主机重启时的行为。以下是对不同重启策略的详细说明:

重启策略对比表
策略名称 行为描述
no 默认值,容器不会自动重启。
on-failure 仅在容器以非零退出码退出时重启。可指定最大重试次数(如 on-failure:5)。
always 无论容器因何种原因停止,都会自动重启。
unless-stopped 总是重启容器,除非容器被手动停止。
设置容器的重启策略
  1. 创建容器时设置重启策略

    在运行容器时,可以通过 --restart 参数设置重启策略。例如:

    bash 复制代码
    docker run -d --name my_container --restart always my_image

    上述命令将容器的重启策略设置为 always,即无论容器因何种原因停止,都会自动重启。

  2. 修改现有容器的重启策略

    如果容器已经创建,可以通过 docker update 命令修改其重启策略。例如:

    bash 复制代码
    docker update --restart always my_container
  3. 验证容器的重启策略

    使用以下命令查看容器的重启策略:

    bash 复制代码
    docker inspect my_container | grep -A 5 RestartPolicy

    输出示例:

    json 复制代码
    "RestartPolicy": {
        "Name": "always",
        "MaximumRetryCount": 0
    },

💾 镜像与容器管理

1. 查询镜像

查看本地所有镜像:

bash 复制代码
docker images

2. 拉取镜像

从 Docker Hub 拉取指定镜像,例如 hello-world

bash 复制代码
docker pull hello-world

3. 删除镜像

删除本地镜像(需要先停止并删除相关容器):

bash 复制代码
docker rmi <image_id>

4. 启动容器

启动一个新的容器,并指定名称和端口映射:

bash 复制代码
docker run -it -p 8000:8000 --name my_container <image_id> /bin/bash

5. 进入容器

进入正在运行的容器并执行命令:

bash 复制代码
docker exec -it <container_id> /bin/bash

6. 复制文件

在容器和主机之间复制文件或目录:

bash 复制代码
# 将容器内的文件复制到主机
docker cp <container_id>:/path/to/file /host/path/
# 将主机上的文件复制到容器内
docker cp /host/path/file <container_id>:/path/to/

7. 加载镜像

在目标计算机上加载镜像:

bash 复制代码
docker load -i <镜像文件>.tar

8. 创建新镜像

将现有容器保存为一个新的镜像:

bash 复制代码
docker commit -m "<提交信息>" -a "<作者>" <容器ID> <新镜像名称>

9. 保存镜像

将镜像保存为 .tar 文件:

bash 复制代码
docker save -o <输出文件名>.tar <镜像名称>

10. 挂载目录

通过 -v 参数挂载本地目录到容器中:

bash 复制代码
docker run [OPTIONS] -v [本地目录]:[容器目录] IMAGE[:TAG] /bin/bash

例如:

bash 复制代码
docker run -v /home/user/data:/app/data my_image:latest /bin/bash

11. 重命名镜像

将镜像重新命名:

bash 复制代码
docker tag IMAGE[:TAG] TARGET[:TAG]

例如:

bash 复制代码
docker tag my_image:latest my_image:v1.0

12. 退出容器

退出容器时,可以使用以下命令:

bash 复制代码
exit

⚙️ 解决常见问题

1. 网络超时问题

如果你在拉取镜像时遇到网络超时问题(如下所示),可以尝试配置 DNS 或使用国内镜像源。

docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
配置 DNS

编辑 /etc/resolv.conf 文件,添加以下内容以使用公共 DNS 服务器:

bash 复制代码
nameserver 114.114.114.114  # 国内常用 DNS
nameserver 8.8.8.8          # Google 公共 DNS

注意 :某些系统可能会自动覆盖 /etc/resolv.conf 文件的更改。如果发现配置被重置,请检查网络管理工具或相关服务配置。

修改 Docker 配置

编辑 /etc/docker/daemon.json 文件,添加国内镜像源以加速镜像拉取:

json 复制代码
{
    "registry-mirrors": [
        "https://x9r52uz5.mirror.aliyuncs.com",  
        "https://dockerhub.icu",                
        "https://docker.chenby.cn",             
        "https://docker.1panel.live",           
        "https://docker.awsl9527.cn",         
        "https://docker.anyhub.us.kg",      
        "https://dhub.kubesre.xyz"         
    ],
    "max-concurrent-downloads": 10,        
    "max-concurrent-uploads": 5,          
    "default-shm-size": "1G",              
    "debug": true,                       
    "experimental": false                    
}

注释问题 :

JSON 文件本身不支持注释(如 // 或 /* */)。虽然某些工具可能允许注释,但 Docker 不会解析带有注释的 daemon.json 文件。

并且在 JSON 中,最后一个键值对后面不能有逗号。

Docker 配置文件解释
配置项 说明
registry-mirrors ["https://vy2wneyx.mirror.aliyuncs.com", "https://dockerhub.icu", ...] 镜像加速地址列表,用于加速 Docker Hub 的镜像拉取。
max-concurrent-downloads 10 最大并发下载数,控制同时下载的层数量。
max-concurrent-uploads 5 最大并发上传数,控制同时上传的层数量。
default-shm-size "1G" 容器默认共享内存大小,建议设置为较大的值以避免内存不足问题。
debug true 是否启用调试模式,启用后会输出更详细的日志信息。
experimental false 是否启用实验性功能,建议保持禁用状态以确保稳定性。
Docker 镜像源列表
镜像源地址 说明
https://<阿里云加速器ID>.mirror.aliyuncs.com 阿里云官方镜像,稳定且速度快
https://dockerhub.icu 第三方镜像,适合国内用户
https://docker.chenby.cn 社区维护镜像,更新频率较高
https://docker.1panel.live 开源项目提供的镜像服务
https://docker.awsl9527.cn AWS 相关镜像,适合 AWS 用户
https://docker.anyhub.us.kg 多地区镜像,支持全球访问
https://dhub.kubesre.xyz Kubernetes 社区推荐镜像

重启 Docker 服务以应用更改:

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

2. 解决 GPG 公钥缺失问题

即使更换了国内镜像源,仍可能遇到以下错误:

由于没有公钥,无法验证下列签名

这种问题通常是由于系统缺少用于验证软件包签名的 GPG 公钥导致的。此时可以尝试手动导入缺失的 GPG 公钥:

bash 复制代码
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 7EA0A9C3F273FCD8

说明

  • hkp://keyserver.ubuntu.com:80:指定密钥服务器地址。
  • 7EA0A9C3F273FCD8:需要导入的 GPG 公钥 ID(根据实际错误信息替换为对应的公钥 ID)。
适用场景

该命令通常用于解决因缺少公钥导致的软件包验证失败问题。例如,在安装 Docker 或其他软件时,可能会因为公钥缺失而无法完成安装。

如果问题仍未解决
  • 确保网络连接正常,并能够访问密钥服务器。
  • 如果仍然无法解决问题,可以尝试跳过此步骤或参考其他解决方案(如手动下载并安装相关软件包)。

3. 解决 Docker 权限问题

默认情况下,Docker 命令需要 root 权限才能运行。为了避免每次使用 Docker 命令时都需要加 sudo,可以将当前用户添加到 docker 用户组中。以下是具体步骤:


步骤 1:创建 docker

如果系统中尚未创建 docker 组,可以通过以下命令创建:

bash 复制代码
sudo groupadd docker

注意 :大多数情况下,安装 Docker 时会自动创建 docker 组。如果已经存在,此命令不会产生任何影响。


步骤 2:将当前用户添加到 docker

将当前用户添加到 docker 组中,以便无需 sudo 即可运行 Docker 命令:

bash 复制代码
sudo usermod -aG docker $USER
  • $USER 是当前登录用户的环境变量。如果你希望为其他用户添加权限,请将 $USER 替换为实际的用户名。

步骤 3:注销并重新登录

为了使组更改生效,需要注销并重新登录系统。在注销之前,请确保保存并关闭所有打开的应用程序,然后执行以下命令:

bash 复制代码
logout   或   exit

重新登录后,组成员身份将更新。


步骤 4(可选):立即激活组更改

如果你不想注销并重新登录,可以通过以下命令在当前会话中立即激活组更改:

bash 复制代码
newgrp docker

步骤 5:验证权限配置

运行以下命令验证是否成功将用户添加到 docker 组,并确认无需 sudo 即可运行 Docker 命令:

bash 复制代码
docker run hello-world

如果一切正常,你将看到类似以下的输出:

Hello from Docker!
This message shows that your installation appears to be working correctly.
注意事项
  • 虚拟机环境 :如果你在虚拟机中运行 Linux,可能需要重启虚拟机以使组更改完全生效。
  • 安全性 :将用户添加到 docker 组相当于赋予了该用户 root 权限,因为 Docker 容器可以访问主机的资源。请谨慎操作,尤其是在多用户环境中。


4. 配置 Docker 代理以登录 Docker Hub

在某些情况下,Docker 的网络连接可能会受到防火墙或代理限制的影响,尤其是在需要登录 Docker Hub 时(如下所示)。

docker login
USING WEB-BASED LOGIN
To sign in with credentials on the command line, use 'docker login -u <username>'
Your one-time device confirmation code is: VGDP-KMZS
Press ENTER to open your browser or submit your device code here: https://login.docker.com/activate
Waiting for authentication in the browser...


Error response from daemon: Get "https://registry-1.docker.io/v2/ ": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

为了解决这些问题,可以通过配置 Docker 的代理设置来确保网络请求能够正常通过。以下是具体操作步骤:


1. 创建 Docker 服务目录和代理配置文件

首先,我们需要创建一个专门用于存放 Docker 服务配置的目录,并在其中添加代理配置文件。

bash 复制代码
sudo mkdir -p /etc/systemd/system/docker.service.d/
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

2. 配置代理环境变量

在打开的 http-proxy.conf 文件中,添加以下内容(请根据实际代理地址和端口进行修改):

ini 复制代码
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"

说明

  • HTTP_PROXYHTTPS_PROXY 分别用于指定 HTTP 和 HTTPS 请求的代理地址。
  • 如果你的代理需要身份验证,可以在地址中包含用户名和密码,例如:http://username:password@proxy-server:port

3. 重新加载配置并重启 Docker 服务

完成代理配置后,需要重新加载 systemd 配置并重启 Docker 服务以使更改生效。

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

4. 验证代理配置是否生效

为了确保代理配置已正确应用,可以尝试登录 Docker Hub 或拉取镜像进行测试。

测试 1:登录 Docker Hub
bash 复制代码
docker login -u your_username

如果代理配置正确,您应该能够成功登录,而不会遇到网络超时或连接失败的问题。

测试 2:拉取镜像
bash 复制代码
docker pull hello-world

如果镜像能够顺利下载,则说明代理配置已生效。


5. (可选):排除特定地址的代理

如果您希望某些地址(如本地镜像仓库或内网服务)不通过代理访问,可以在配置文件中添加 NO_PROXY 环境变量。例如:

ini 复制代码
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com"

说明

  • NO_PROXY 用于指定不需要通过代理访问的地址列表。
  • 地址可以是域名、IP 地址或通配符(如 .example.com)。

注意事项
  • 代理地址的有效性:确保代理地址和端口正确无误,并且代理服务正在运行。
  • 安全性:如果代理需要身份验证,请确保用户名和密码的安全性,避免泄露敏感信息。
  • 多用户环境:在多用户环境中使用代理时,请确保所有用户都能正确访问代理服务。

5. 解决 Docker 容器无法启动时的调试与修复方法

在使用 Docker 的过程中,可能会遇到容器因某些错误而无法启动的情况。这种问题可能由配置文件错误、端口冲突、依赖缺失等原因引起 [[1]]。当 docker start 命令失败时,您可能无法直接使用 docker exec 进入容器进行调试。不过,以下几种方法可以帮助您快速定位并解决问题。


1. 查看容器日志

首先,查看容器的日志是定位问题的关键步骤。通过日志,您可以了解容器启动失败的具体原因,例如配置文件错误、依赖服务未启动等。

bash 复制代码
docker logs <container_name_or_id>

示例输出:

Error: Port 8080 is already in use.

如果日志显示端口被占用,可以通过修改端口映射或清理占用端口的进程来解决问题 [[4]]。


2. 检查容器配置

使用 docker inspect 命令可以查看容器的详细配置信息,包括启动命令、挂载的卷、环境变量等。这些信息有助于排查潜在问题。

bash 复制代码
docker inspect <container_name_or_id>

查看启动命令:

bash 复制代码
docker inspect <container_id> | grep Cmd

如果发现启动命令有问题,可以重新创建容器并指定正确的命令。


3. 使用临时容器挂载故障容器的卷

如果您的容器使用了数据卷来存储持久数据,可以通过创建一个新的临时容器来挂载故障容器的数据卷,并在其中进行调试。

bash 复制代码
docker run -it --volumes-from <faulty_container> --entrypoint /bin/bash <image_name>

示例:

bash 复制代码
docker run -it --volumes-from LuyeChat --entrypoint /bin/bash ubuntu
  • --volumes-from 参数允许新容器挂载故障容器的数据卷。
  • <image_name> 是与原容器相同或兼容的镜像(例如 ubuntu)。
  • /bin/bash 是指定的入口点,用于启动交互式终端。

在新容器中,您可以访问和修改故障容器的文件系统。


4. 直接编辑容器文件系统

对于普通存储,可以直接找到容器存储的文件系统(通常位于 /var/lib/docker/overlay2/<container_id>/diff),手动更改相关配置。

方法 1:挂载容器的文件系统

通过挂载容器的文件系统路径到一个临时容器中,您可以直接修改文件。

bash 复制代码
docker run -it --rm -v /var/lib/docker/overlay2/<container_id>/diff:/mnt ubuntu bash
  • /var/lib/docker/overlay2/<container_id>/diff 是原容器的文件系统路径。
  • /mnt 是新容器中挂载的目录。
  • ubuntu 是一个基础镜像,用于提供操作环境。

进入后,您可以直接修改挂载的文件。

方法 2:直接修改宿主机上的文件

如果您知道容器的文件存储位置,可以直接在宿主机上修改文件。但请注意,这种方法可能会导致不稳定性或数据丢失,务必在备份的情况下进行操作 [[5]]。


5. 提交容器为镜像并重新启动

如果容器可以短暂启动(即使很快退出),可以将其保存为镜像,然后基于该镜像启动一个新的容器进行调试。

bash 复制代码
docker commit <container_id> temp_image
docker run -it temp_image bash

在新容器中,您可以修改代码或配置文件。


6. 删除并重新创建容器

如果以上方法都无法解决问题,可以考虑删除容器并重新创建。

bash 复制代码
docker rm <container_id>
docker run [options] <image_name>

注意:删除容器会导致容器内的数据丢失,因此在删除前确保重要数据已备份。


避免类似问题的建议

为了避免未来再次出现类似问题,可以采取以下措施:

(1) 挂载代码目录

将代码目录挂载到宿主机上,而不是直接打包到镜像中。这样可以在宿主机上修改代码,而无需重新构建镜像或重启容器。

bash 复制代码
docker run -v /host/path/to/code:/container/path/to/code <image_name>
(2) 分离启动逻辑

在容器的启动脚本中添加检查逻辑,确保即使代码有问题,容器也能进入调试模式。

bash 复制代码
#!/bin/bash
if [ ! -f "/path/to/config" ]; then
    echo "Config file not found, starting shell for debugging..."
    exec /bin/bash
fi
exec your_service_command
(3) 定期提交更改

如果您在容器内进行了大量修改,定期使用 docker commit 将容器保存为镜像,避免意外丢失数据。

bash 复制代码
docker commit <container_id> backup_image

📋 Docker Compose 命令详解

命令 描述
docker compose version 查看 Docker Compose 的版本信息(适用于新版集成到 Docker CLI 的 Compose)
docker compose up 创建并启动所有服务
docker compose down 停止并移除所有容器、网络和卷
docker compose ps 列出所有容器的状态
docker compose logs 查看容器的日志输出
docker compose exec <service_name> <command> 在运行中的容器内执行命令
docker compose build 构建或重新构建服务镜像 如果你想强制重新构建,可以使用 --no-cache 参数: docker compose build --no-cache
docker compose pull 拉取服务所需的镜像
docker compose push 推送服务镜像到镜像仓库
docker compose restart 重启服务容器
docker compose stop 停止服务容器
docker compose start 启动服务容器
docker compose rm 移除已停止的服务容器

Docker Compose 常用选项

选项 描述 示例
--file-f 指定 Compose 文件的路径。默认情况下,Docker Compose 会在当前目录下寻找名为 docker-compose.yml 的文件。 docker compose -f my-compose-file.yml up
--project-name-p 指定项目的名称。默认情况下,项目名称是基于当前目录的名称。 docker compose -p my_project up
--env-file 指定环境变量文件。默认情况下,Docker Compose 会读取 .env 文件中的环境变量。 docker compose --env-file .myenv up
--profile 启用特定的配置文件(profiles)。Compose 文件中可以通过 profiles 定义不同的服务组。 docker compose --profile dev up
--progress 设置进度输出的格式。支持的值包括 autottyplainjsonquiet docker compose --progress plain up

🌟 实战案例:运行 Flask 应用

1. 启动容器

假设我们有一个 Flask 应用的镜像 edu/web_flask_server:V2,我们可以使用以下命令启动容器:

bash 复制代码
sudo docker run -it -p 8080:8080 --name web_flask edu/web_flask_server:V2 /bin/bash

说明

  • -p 8080:8080:将主机的 8080 端口映射到容器的 8080 端口。
  • --name web_flask:为容器指定名称。
  • /bin/bash:启动一个交互式终端。
重启策略

容器设置 always 策略,确保应用在意外退出后能够自动恢复:

bash 复制代码
sudo docker run -d -p 8080:8080 --name web_flask --restart always edu/web_flask_server:V2

说明

  • --restart always:确保容器在任何情况下都会自动重启。
  • -d:后台运行容器。

2. 进入容器

进入容器内部并启动 Flask 应用:

bash 复制代码
docker exec -it web_flask /bin/bash -c 'python /work/web_flask/app.py'

说明

  • docker exec -it:在运行中的容器内执行命令。
  • /bin/bash -c 'python /work/web_flask/app.py':启动 Flask 应用。

3. 制作启动脚本

为了方便操作,可以创建脚本 start_webflask.sh

bash 复制代码
# start_webflask.sh
docker restart web_flask
docker exec -it web_flask /bin/bash -c 'python /work/web_flask/app.py'

4. 保存和加载镜像

在实际开发中,可能需要将容器的状态保存为镜像,或者将镜像导出为 .tar 文件进行备份或传输。

保存镜像

将镜像保存为 .tar 文件:

bash 复制代码
docker save -o web_flask_server_V3.tar edu/web_flask_server:V2

说明

  • -o:指定输出文件名。
  • edu/web_flask_server:V2:要保存的镜像名称。

执行此命令后,Docker 将会在当前工作目录下生成一个名为 web_flask_server_V3.tar 的文件。这个文件可以用于备份、传输或在其他计算机上加载为 Docker 镜像。


加载镜像

在目标计算机上加载 .tar 文件中的镜像:

bash 复制代码
docker load -i web_flask_server_V3.tar

说明

  • -i:指定输入文件。
  • 加载完成后,该镜像将出现在本地的 Docker 镜像列表中。

从容器创建新镜像

如果需要将容器的当前状态保存为一个新的镜像,可以使用以下命令:

bash 复制代码
docker commit -m "提交信息" -a "作者" web_flask edu/web_flask_server:V2

说明

  • -m:添加提交信息。
  • -a:指定作者信息。
  • web_flask:容器 ID 或名称。
  • edu/web_flask_server:V2:新生成的镜像名称。

执行此命令后,Docker 会将容器的当前状态保存为一个新的镜像。这个镜像可以用于创建新的容器或分享给其他人使用。


5. 挂载目录

在运行容器时,可以通过 -v 参数挂载本地目录到容器中,以便实现数据持久化或共享文件:

bash 复制代码
docker run -it -p 8080:8080 -v /host/path:/container/path --name web_flask edu/web_flask_server:V2 /bin/bash

说明

  • -v /host/path:/container/path:将主机的 /host/path 目录挂载到容器的 /container/path 目录。

6. 退出容器

完成操作后,可以通过以下命令退出容器:

bash 复制代码
exit

📚 参考链接

本文的内容参考了以下优质资源,推荐读者进一步阅读以深入了解 Docker 的使用技巧和高级功能:

🎉 总结

通过本文的学习,你应该已经掌握了 Docker 的基本安装、配置和使用方法。无论是管理镜像、启动容器,还是解决常见问题,Docker 都提供了强大的工具集来帮助我们简化开发流程。希望这篇指南能够为你的 Docker 之旅提供帮助!🚀

如果你有任何问题或建议,欢迎在评论区留言交流!💬

相关推荐
最数据12 分钟前
收集了一些docker修改镜像源地址
docker·容器·镜像源·国内源地址
云上艺旅1 小时前
K8S学习之基础二十四:k8s的持久化存储之pv和pvc
学习·云原生·容器·kubernetes
人间凡尔赛1 小时前
VSCode-Server 在 Linux 容器中的手动安装指南
linux·运维·服务器·docker
Sans_2 小时前
初识Docker-Compose(包含示例)
后端·docker·容器
Java程序之猿2 小时前
Centos 安装docker,docker-compose
linux·docker·centos
TechStack 创行者3 小时前
Docker+Flask 实战:打造高并发微服务架构
运维·docker·微服务·容器·架构
Sirius Wu3 小时前
三级缓存架构
容器·kubernetes·embedding
容器魔方3 小时前
KubeEdge边缘设备管理系列(四):Mapper-Framework视频流处理
云原生·容器·云计算
SaebaRyo3 小时前
MySQL常见写法
后端·mysql·docker
a_j584 小时前
k8s面试题总结(十四)
docker·容器·kubernetes