Featured image of post docker使用教程

docker使用教程

# Docker 常用命令汇总

# 将容器的当前状态保存为新的镜像
docker commit <my-container> <my-new-image>:[tag]   

镜像 (Image) 相关命令

镜像是创建容器的基础,包含了应用程序及其依赖的环境。

命令描述
docker images列出本地所有镜像。
docker pull [镜像名]:[标签]从 Docker Hub 或其他镜像仓库拉取镜像 (例如: docker pull ubuntu:22.04)。
docker push [用户名]/[镜像名]:[标签]将本地镜像推送到 Docker Hub 或其他镜像仓库。
docker build -t [镜像名]:[标签] .根据当前目录下的 Dockerfile 构建镜像 (例如: docker build -t my-app:1.0 .)。
docker rmi [镜像ID或镜像名]删除一个或多个镜像 (例如: docker rmi ubuntu:22.04)。
docker tag [源镜像] [新镜像名]为本地镜像添加一个新的标签 (例如: docker tag my-app:1.0 my-app:latest)。
docker history [镜像名]查看镜像的构建历史。
docker save -o [文件名.tar] [镜像名]将镜像保存为一个 tar 归档文件。
docker load -i [文件名.tar]从一个 tar 归档文件加载镜像。
docker rmi $(docker images -qf "dangling=true")删除所有悬空的(dangling)镜像。

容器 (Container) 相关命令

容器是镜像的运行实例,是真正运行应用程序的地方。

命令描述
docker run [选项] [镜像名] [命令]创建并启动一个新的容器。
docker ps列出所有正在运行的容器。
docker ps -a列出所有容器(包括已停止的)。
docker start [容器ID或容器名]启动一个或多个已停止的容器。
docker stop [容器ID或容器名]停止一个或多个正在运行的容器。
docker restart [容器ID或容器名]重启一个容器。
docker rm [容器ID或容器名]删除一个或多个容器。
docker rm -f $(docker ps -aq)强制删除所有容器(无论运行中还是已停止)。
docker logs [容器ID或容器名]查看容器的日志输出 (-f 选项可以持续跟踪日志)。
docker exec -it [容器ID] [命令]在正在运行的容器中执行一个交互式命令 (例如: docker exec -it my-nginx /bin/bash)。
docker cp [本地路径] [容器ID]:[容器内路径]在宿主机和容器之间复制文件/文件夹。
docker stats实时显示容器的资源使用情况。
docker top [容器ID]查看容器内运行的进程。
docker inspect [容器ID或镜像ID]查看容器或镜像的详细信息(元数据)。

docker run 常用选项

  • -d: 后台运行容器(detached mode)。
  • -p [宿主机端口]:[容器端口]: 端口映射。
  • -v [宿主机路径]:[容器内路径]: 数据卷挂载。
  • --name [容器名]: 为容器指定一个名称。
  • -it: 启动交互式会话 (-i 交互, -t 分配一个伪终端)。
  • --rm: 容器停止后自动删除。
  • -e [环境变量名]=[值]: 设置环境变量。
  • --network [网络名]: 将容器连接到指定网络。

示例: docker run -d -p 8080:80 --name my-web-server -v /webapp:/usr/share/nginx/html nginx

Docker Compose 相关命令

用于定义和运行多容器 Docker 应用程序的工具。

命令描述
docker-compose up根据 docker-compose.yml 创建并启动所有服务。
docker-compose up -d在后台创建并启动所有服务。
docker-compose down停止并移除由 up 创建的容器、网络、卷。
docker-compose ps列出 docker-compose.yml 文件中定义的所有容器的状态。
docker-compose logs查看所有服务的日志。
docker-compose logs -f [服务名]实时跟踪特定服务的日志。
docker-compose build构建或重新构建服务。
docker-compose pull拉取服务依赖的镜像。
docker-compose exec [服务名] [命令]在指定的服务容器中执行命令。
docker-compose stop停止服务,但不删除容器。
docker-compose start启动已停止的服务。

系统与资源管理命令

命令描述
docker system prune清理系统中未使用的 Docker 资源(容器、镜像、网络、卷)。
docker system prune -a --volumes更彻底的清理,会删除所有未使用的镜像和数据卷。 请谨慎使用!
docker system df查看 Docker 的磁盘使用情况。
docker volume ls列出所有的数据卷。
docker volume rm [卷名]删除一个或多个数据卷。
docker network ls列出所有的网络。
docker network rm [网络名]删除一个或多个网络。
docker login登录到 Docker Hub 或其他镜像仓库。
docker logout登出 Docker Hub 或其他镜像仓库。
docker info显示 Docker 系统范围的信息。
docker version显示 Docker 的版本信息。

docker容器相关命令

1. 拉取镜像

docker pull ubuntu

2.查看镜像是否拉取成功

docker images

3. 运行容器

docker run -itd --name <容器名称>  -p <主机端口>:<容器端口> --cpus=30  ubuntu
# -p设置端口   --cpus/-c 设置核心 

4. 通过 exec 命令进入 ubuntu 容器

docker exec -it <容器名>  /bin/bash

5. 安装ssh

apt-get updata

apt-get install openssh-client
apt-get install openssh-server

6. 安装vim

apt-get install vim

7. 安装conda

https://zhuanlan.zhihu.com/p/307923089 注意,可能要手动配置环境变量

8. 安装zip、unzip

apt-get install zip 
apt-get install unzip 

9. 解决中文乱码问题

export LC_ALL="C.UTF-8"
source /etc/bash.bashrc

10. 安装sudo

apt-get install sudo




Docker使用技巧

使用已有容器创建镜像

docker commit container-name  new-image-name

开启/重启ssh服务

service ssh start 
service ssh restart 

docker 文件传输

宿主机到容器

# docker cp 宿主机文件/路径 容器名:容器内路径
docker cp /home/Download/index.html wordpress-lee:/var/www/html

容器到宿主机

# docker cp 容器名:文件/路径 宿主机路径 
docker cp wordpress-lee:/root/example.sh /root

修改服务器配置允许通过此服务器进行ssh转发

进入配置文件,不要cd..然后在vim,直接vim …

vim /etc/ssh/sshd_config

配置文件内容

修改其中的:

重启ssh服务

 service ssh restart

docker容器添加对外映射端口

最简单省事方法:将现有的容器打包成镜像,然后在使用新的镜像运行容器时重新指定要映射的端口

打包镜像重新运行容器

docker设置可用CPU核心数量

CPU数量

指定CPU

docker实战

Docker 服务部署教程

在开始之前,我们先快速理解三个最重要的概念:

  • Docker:一个开源平台,用于开发、发布和运行应用程序。它允许你将应用程序及其所有依赖(库、环境变量、配置文件等)打包到一个标准化的单元中,这个单元被称为“容器”。
  • 镜像 (Image):一个只读的模板,包含了运行应用程序所需的所有内容——代码、运行时、库、环境变量和配置文件。你可以把镜像理解为安装程序或一个“蓝图”。
  • 容器 (Container):镜像的运行实例。当你运行一个镜像,你就启动了一个容器。容器是独立的、轻量级的,并且在你的主机操作系统上运行,但与主机和其他容器隔离。你可以同时运行同一个镜像的多个容器。

简单比喻

  • Dockerfile 是菜谱。
  • 镜像 (Image) 是做好的、打包在盒子里的预制菜。
  • 容器 (Container) 是你把预制菜放进微波炉加热后,正在运行、可以享用的那份饭菜。

环境准备

在开始之前,你需要在你的机器上安装 Docker。

  • Windows / macOS: 下载并安装 Docker Desktop。它提供了一个图形化界面和命令行工具。
    • 官方下载地址: https://www.docker.com/products/docker-desktop/
  • Linux: 根据你的发行版(如 Ubuntu, CentOS)按照官方文档进行安装。
    • 官方安装指南: https://docs.docker.com/engine/install/

安装完成后,打开你的终端(在 Windows 上是 PowerShell 或 WSL2,macOS 上是 Terminal),运行以下命令来验证 Docker 是否安装成功:

docker --version
docker ps

如果命令能够成功执行并显示版本信息和一个空的容器列表,说明 Docker 已经准备就绪。


实战演练:部署一个 Python Web 应用

我们将部署一个简单的 Python Flask Web 应用,它会在访问时返回 “Hello, Docker!"。

步骤一:准备应用程序

首先,在你喜欢的位置创建一个新的项目文件夹,例如 my-docker-app

mkdir my-docker-app
cd my-docker-app

在该文件夹中,创建以下两个文件:

  1. app.py (我们的 Web 应用程序代码)

    from flask import Flask
    
    # 创建 Flask 应用实例
    app = Flask(__name__)
    
    # 定义根路由
    @app.route('/')
    def hello():
        return "Hello, Docker! This is a simple web service."
    
    # 启动服务
    # host='0.0.0.0' 让容器外部可以访问
    # port=5000 是应用监听的端口
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000)
    
  2. requirements.txt (列出 Python 依赖)

    Flask==2.2.2
    

现在你的文件夹结构应该是:

my-docker-app/
├── app.py
└── requirements.txt
步骤二:编写 Dockerfile

Dockerfile 是一个文本文件,它包含了构建 Docker 镜像所需的所有指令。在 my-docker-app 文件夹中创建名为 Dockerfile (没有文件扩展名) 的文件。

# 步骤 1: 选择一个基础镜像
# 我们选择一个官方的、轻量级的 Python 3.9 镜像
FROM python:3.9-slim

# 步骤 2: 在镜像中设置工作目录
# 之后的所有命令都会在这个目录下执行
WORKDIR /app

# 步骤 3: 复制依赖文件到工作目录
# 将 requirements.txt 复制到镜像的 /app 目录中
COPY requirements.txt .

# 步骤 4: 安装应用程序的依赖
# 在镜像中运行 pip 命令来安装 Flask
RUN pip install --no-cache-dir -r requirements.txt

# 步骤 5: 复制应用程序代码到工作目录
# 将当前目录下的所有文件 (app.py) 复制到镜像的 /app 目录
COPY . .

# 步骤 6: 声明容器将监听的端口
# 这只是一个元数据声明,告诉用户这个容器内部的应用会使用 5000 端口
EXPOSE 5000

# 步骤 7: 定义启动容器时要执行的命令
# 运行我们的 Python 应用
CMD ["python", "app.py"]
步骤三:构建 Docker 镜像

现在我们有了应用程序和 Dockerfile,可以构建我们的镜像了。确保你的终端当前路径在 my-docker-app 文件夹下。

运行 docker build 命令:

# -t my-web-app:v1  给镜像起一个名字 (tag),格式是 <name>:<version>
# .                 表示使用当前目录下的 Dockerfile
docker build -t my-web-app:v1 .

构建

你会看到 Docker 按照 Dockerfile 中的步骤逐一执行。构建成功后,你可以用以下命令查看你刚刚创建的镜像:

docker images

你应该能在列表中看到 my-web-app 这个镜像。

步骤四:运行 Docker 容器

镜像已经构建好了,现在让我们用它来启动一个容器。

运行 docker run 命令:

docker run -d -p 8888:5000 --name my-first-container my-web-app:v1

让我们分解一下这个命令:

  • docker run: 运行一个容器的命令。
  • -d (detached): 后台运行模式。容器将在后台启动并持续运行。
  • -p 8888:5000 (port mapping): 端口映射。这是非常重要的一步。
    • 它将宿主机 (你的电脑)8888 端口映射到容器5000 端口。
    • 5000 是我们在 app.pyDockerfile 中指定的应用端口。
    • 8888 是我们希望通过外部访问的端口。你可以换成其他未被占用的端口,如 80
  • --name my-first-container: 给这个正在运行的容器起一个友好的名字,方便管理。
  • my-web-app:v1: 指定要运行的镜像。
步骤五:验证和管理
  1. 验证服务 打开你的浏览器,访问 http://localhost:8888。 你应该能看到页面上显示 “Hello, Docker! This is a simple web service."。

    你也可以使用 curl 命令在终端验证:

    curl http://localhost:8888
    
  2. 管理容器 以下是一些常用的容器管理命令:

    • 查看正在运行的容器

      docker ps
      
    • 查看容器日志 (非常适合排查问题)

      docker logs my-first-container
      
    • 停止容器

      docker stop my-first-container
      
    • 重新启动已停止的容器

      docker start my-first-container
      
    • 删除容器 (必须先停止容器才能删除)

      docker rm my-first-container
      
    • 删除镜像 (必须先删除所有使用该镜像的容器才能删除)

      docker rmi my-web-app:v1
      

进阶:使用 Docker Compose 编排服务

当你的应用变得复杂,比如需要一个 Web 服务和一个数据库服务时,手动管理多个容器会很麻烦。Docker Compose 就是解决这个问题的工具。它允许你使用一个 YAML 文件来定义和运行多容器的 Docker 应用程序。

步骤一:安装 Docker Compose

如果你安装的是 Docker Desktop (Windows/macOS),那么 Docker Compose 已经包含在内了。你可以通过 docker-compose --versiondocker compose version 来验证。

步骤二:创建 docker-compose.yml 文件

在你的 my-docker-app 文件夹中,创建一个名为 docker-compose.yml 的文件。

# docker-compose.yml

# 定义 Compose 文件的版本
version: '3.8'

# 定义服务
services:
  # 我们的 Web 应用服务
  web:
    # 构建指令
    build:
      # 使用当前目录下的 Dockerfile
      context: .
    # 镜像名称
    image: my-web-app-compose:latest
    # 容器名称
    container_name: my-web-app-container
    # 端口映射
    ports:
      - "8888:5000"
    # 卷挂载 (可选,用于代码热更新)
    # 将本地代码目录挂载到容器的 /app 目录
    # 这样修改本地代码后,服务会自动重启(需要 Flask 开启 debug 模式)
    volumes:
      - .:/app
    # 环境变量
    environment:
      - FLASK_ENV=development # 开启 Flask 调试模式

  # 假设我们还需要一个 Redis 服务
  redis:
    # 直接使用官方 Redis 镜像
    image: "redis:alpine"
    container_name: my-redis-cache
步骤三:使用 Docker Compose 启动服务

my-docker-app 目录下,运行以下命令:

# 启动所有服务 (-d 表示后台运行)
docker-compose up -d
# 或者新版本命令
# docker compose up -d

Compose 会自动帮你:

  1. 构建 web 服务的镜像(如果尚未构建)。
  2. 拉取 redis 镜像。
  3. 创建并启动 webredis 两个容器,并根据配置建立网络连接。
步骤四:管理 Compose 服务
  • 查看服务状态
    docker-compose ps
    
  • 查看日志
    docker-compose logs -f web  # 查看 web 服务的日志
    
  • 停止并删除所有服务
    docker-compose down
    

总结

恭喜你!你已经学会了如何使用 Docker 部署一个单服务的 Web 应用,并了解了如何使用 Docker Compose 管理更复杂的应用场景。

核心流程回顾

  1. 写代码 (app.py, requirements.txt)
  2. 写配置 (Dockerfile)
  3. 构建镜像 (docker build)
  4. 运行容器 (docker rundocker-compose up)

Docker 的世界非常广阔,接下来你可以继续探索数据持久化(Volumes)、网络(Networking)、以及如何将你的镜像推送到 Docker Hub 与他人共享。

Docker服务部署教程2-使用uv替代pip

好的,当然可以。使用 uv 来替代 pip 进行包管理是一个非常棒的选择,尤其是在 Docker 构建环境中,因为 uv 的速度极快,可以显著缩短镜像构建的时间。

改动主要集中在 Dockerfile 文件中。你需要添加安装 uv 的步骤,并用 uv pip install 替换 pip install。你的应用程序代码 (app.py) 和依赖列表 (requirements.txt) 完全不需要改变

下面是详细的说明和更新后的代码。

使用 UV 的核心改动

uv 是一个独立的二进制文件,我们需要在 Docker 镜像中先安装它。最直接的方法是使用官方提供的安装脚本。

更新后的 Dockerfile 会包含以下几个新步骤:

  1. 安装 curl 工具,以便下载 uv 安装脚本。
  2. 运行 uv 的安装脚本。
  3. uv 的路径添加到环境变量 PATH 中,以便后续命令可以找到它。
  4. 使用 uv 来安装依赖。

更新后的 Dockerfile (使用 uv)

这是修改后的 Dockerfile。你可以直接用它替换掉原来项目中的 Dockerfile

# Use a Python image with uv pre-installed
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim

# Set working directory
WORKDIR /app

# Enable bytecode compilation
ENV UV_COMPILE_BYTECODE=1

# Copy from the cache instead of linking since it's a mounted volume
ENV UV_LINK_MODE=copy

# Copy requirements file first for better layer caching
COPY requirements.txt .

# Install dependencies using uv with requirements.txt
RUN --mount=type=cache,target=/root/.cache/uv \
    uv pip install --system -r requirements.txt

# Copy application code
COPY . .

# Expose port 5000 (Flask default)
EXPOSE 5000

# Reset the entrypoint, don't invoke `uv`
ENTRYPOINT []

# Run the Flask application
CMD ["python", "app.py"]

你的整体工作流程几乎不变,只是替换了 Dockerfile 的内容。 之前使用gemini的教程但是报错了 报错信息 所以最好使用uv官方提供的镜像,具体使用教程可见

在 Docker 中使用 uv

使用 UV 的完整流程

```bash
docker build -t my-web-app:uv-latest .
```
(我们用了 `uv-latest` 这个新标签来区分版本)

在这一步,你会注意到 `RUN uv pip install` 这一层会比之前使用 `pip` 快非常多,尤其是在依赖项很多的情况下。

  1. 运行容器(命令不变) 使用新的镜像标签来运行容器:

    docker run -d -p 8888:5000 --name my-uv-container my-web-app:uv-latest
    

    结果

  2. 验证(方式不变) 访问 http://localhost:8888,一切应该和之前一样正常工作。

对于 Docker Compose 呢?

你的 docker-compose.yml 文件完全不需要任何改动。

# docker-compose.yml (无需改动)
version: '3.8'
services:
  web:
    build:
      context: .
    ports:
      - "8888:5000"
    # ... 其他配置

这就是 Docker 的强大之处。docker-compose.yml 只关心“做什么”(比如,从当前目录 . 构建一个镜像),而不关心“怎么做”(具体是使用 pip 还是 uv 来安装依赖)。所有的实现细节都被封装在 Dockerfile 里了。当你运行 docker-compose up 时,Compose 会自动使用你更新后的 Dockerfile 来构建镜像。

总结

将包管理器从 pip 切换到 uv,你只需要:

  1. 更新 Dockerfile 以包含安装和使用 uv 的指令。
  2. 重新 build 你的镜像。

其他所有代码、文件和部署命令都保持原样,流程无缝衔接,同时还能享受到 uv 带来的极致构建速度。

docker容器的部署教程3-将容器部署到服务器上

当你创建完 Dockerfile 之后,部署一个应用通常遵循一个标准化的流程:构建镜像 -> 推送镜像 -> 在目标环境运行容器

下面我将为你分解这个过程,并介绍从简单到复杂的不同部署方案。

核心流程

第一步:构建 Docker 镜像 (Build)

这是将你的 Dockerfile 和应用程序代码打包成一个标准化的、不可变的“Docker 镜像”的过程。

在你的 Dockerfile 所在的目录下,打开终端并运行以下命令:

# docker build -t <你的镜像名称>:<标签> .
# 示例:
docker build -t my-awesome-app:v1.0 .
  • docker build: 构建命令。
  • -t my-awesome-app:v1.0: -t 参数用来给镜像打上“标签”(tag),格式通常是 image_name:version。这非常重要,便于版本管理。
  • .: 这个点表示 Dockerfile 的上下文路径(Context Path)是当前目录。Docker 会把这个目录下的所有文件发送给 Docker 守护进程来帮助构建。

构建成功后,你可以通过 docker images 命令查看你本地的所有镜像。

第二步:在本地运行和测试 (Run Locally)

在推送到服务器之前,首先在本地运行容器以确保它能正常工作。

# docker run --rm -p <本地端口>:<容器端口> <你的镜像名称>:<标签>
# 示例: 假设你的应用在容器内监听 8080 端口
docker run --rm -p 3000:8080 my-awesome-app:v1.0
  • docker run: 运行命令。
  • --rm: 容器停止后自动删除,适合测试。
  • -p 3000:8080: -p 参数用来做端口映射(Port Mapping),将你本机的 3000 端口映射到容器的 8080 端口。这样你就可以通过访问 http://localhost:3000 来访问你的应用了。
  • my-awesome-app:v1.0: 指定要运行的镜像。
第三步:推送镜像到镜像仓库 (Push to Registry)

为了在其他机器(例如你的云服务器)上使用这个镜像,你需要将它推送到一个中央存储库,这被称为“镜像仓库”(Image Registry)。

最常用的公共仓库是 Docker Hub。各大云服务商也提供私有仓库,如 Google Artifact Registry (GCR), Amazon Elastic Container Registry (ECR), Azure Container Registry (ACR) 等。

  1. 为镜像打上符合仓库要求的标签: 推送前,你需要将镜像重命名为 <你的仓库用户名>/<镜像名称>:<标签> 的格式。

    # 格式: docker tag <本地镜像> <仓库用户名>/<新镜像名>:<标签>
    # 示例 (以 Docker Hub 为例):
    docker tag my-awesome-app:v1.0 your-dockerhub-username/my-awesome-app:v1.0
    
  2. 登录你的镜像仓库

    # 登录 Docker Hub
    docker login
    # 按照提示输入你的 Docker Hub 用户名和密码
    # 然后这个页面不要关,下面推送的时候打开一个新的终端
    

    保持这个界面

  3. 推送镜像

    
    # 格式: docker push <仓库用户名>/<镜像名>:<标签>
    # 示例:
    docker push your-dockerhub-username/my-awesome-app:v1.0
    

    推送好的镜像

第四步:选择部署方案 (Deploy)

现在你的镜像已经准备就绪,可以部署了。以下是几种常见的部署方案,从易到难:


方案一:在单台云服务器上手动部署 (最简单)

这种方式适合个人项目、测试环境或小型应用。

  1. 准备服务器:购买一台云服务器(如 GCP, AWS, Azure, 阿里云等),并确保已安装 Docker。
  2. SSH 登录服务器:通过 SSH 客户端连接到你的服务器。
  3. 拉取镜像:在服务器上,从你之前推送的仓库中拉取镜像。
    docker pull your-dockerhub-username/my-awesome-app:v1.0
    
  4. 运行容器:与在本地运行类似,但在服务器上通常使用 -d 参数让容器在后台运行。
    # -d (detached mode) 表示在后台运行容器
    docker run -d -p 80:8080 --name my-running-app your-dockerhub-username/my-awesome-app:v1.0
    
    这里我们将服务器的 80 端口(HTTP 默认端口)映射到容器的 8080 端口。现在,你可以通过服务器的 IP 地址直接访问你的应用。

方案二:使用 Docker Compose 部署 (推荐用于多容器应用)

如果你的应用包含多个服务(例如一个 Web 应用 +一个数据库),使用 Docker Compose 会让管理变得非常简单。

  1. 创建 docker-compose.yml 文件:在你的项目中创建一个 docker-compose.yml 文件。
    version: '3.8'
    
    services:
      app:
        image: your-dockerhub-username/my-awesome-app:v1.0
        ports:
          - "80:8080"
        restart: always # 容器挂掉后自动重启
    
      # 如果有数据库,可以这样添加
      # db:
      #   image: postgres:13
      #   environment:
      #     - POSTGRES_PASSWORD=mysecretpassword
    
  2. 部署:将 docker-compose.yml 文件上传到你的服务器,然后在该文件所在的目录运行:
    # 以后台模式启动所有服务
    docker-compose up -d
    
    # 如果需要更新镜像并重新部署
    docker-compose pull  # 拉取 yml 文件中定义的所有镜像的最新版
    docker-compose up -d --force-recreate # 强制重新创建容器
    

方案三:部署到云平台的容器服务 (PaaS/Serverless)

这种方式可以让你不用管理底层服务器,只需提供容器镜像,平台会自动为你扩缩容和管理。

  • Google Cloud Run:非常简单的无服务器平台。你只需将镜像推送到 Google Artifact Registry,然后在 Cloud Run 上创建一个服务,指向这个镜像即可。平台按需计费,没有请求时不收费。
  • AWS App Runner / Azure Container Apps:与 Google Cloud Run 类似的服务。
  • Heroku:传统的 PaaS 平台,也支持通过 Docker 部署。

优点:免运维、自动扩缩容、按需付费。 缺点:平台锁定性较强,自定义程度较低。


方案四:使用容器编排工具 (Kubernetes)

对于大型、复杂、高可用的生产系统,Kubernetes (K8s) 是事实上的标准。

  • 它是什么:一个强大的系统,用于自动化部署、扩展和管理容器化应用程序。
  • 何时使用:当你的应用需要高可用性、自动伸缩、滚动更新、服务发现和负载均衡等高级功能时。
  • 如何使用
    1. 学习 Kubernetes 的基本概念(Pod, Deployment, Service 等)。
    2. 编写 Kubernetes 的 YAML 配置文件来定义你的应用部署。
    3. 使用云服务商提供的托管 Kubernetes 服务,如:
      • Google Kubernetes Engine (GKE)
      • Amazon Elastic Kubernetes Service (EKS)
      • Azure Kubernetes Service (AKS)

优点:极其强大和灵活,是微服务架构的最佳拍档。 缺点:学习曲线非常陡峭,管理复杂。

如何选择?

方案适用场景优点缺点
手动部署个人项目、学习、快速原型简单直接,易于理解手动操作多,不易扩展和管理
Docker Compose多容器的单机应用、开发和测试环境大大简化多容器管理主要面向单机,集群能力弱
云平台容器服务中小型应用、无服务器爱好者极简运维,自动扩缩容平台锁定,不够灵活
Kubernetes生产级、大型复杂系统、微服务架构功能强大,高可用,可移植性好学习曲线陡峭,非常复杂

对于初学者,我强烈建议你从 方案一方案二 开始。 当你对容器化部署有了更深入的理解后,再根据项目需求去探索 方案三方案四

运行容器了但是并没有生效-通过查看日志解决问题

我运行容器了,但是访问localhost:8888并没有生效

好的,这是一个非常常见的问题,别担心,我们一步一步来排查。访问 localhost:8888 不生效通常有以下几个原因。

请打开你的终端,按顺序执行下面的命令来定位问题。

第一步:检查容器是否正在运行

首先,我们需要确认你的容器是否成功启动并且正在运行。

运行这个命令,它会列出所有正在运行的容器:

docker ps

你应该会看到类似这样的输出:

CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS                    NAMES
a1b2c3d4e5f6   my-web-app:v1   "python app.py"          2 minutes ago    Up 2 minutes    0.0.0.0:8888->5000/tcp   my-first-container

请检查几件事:

  1. 你的容器在列表里吗?
    • 如果不在,说明容器启动失败或者已经退出了。请运行 docker ps -a (这会显示所有容器,包括已停止的),找到你的容器 (my-first-container),然后查看它的 STATUS。如果显示 Exited,请直接跳到下面的 第二步
  2. STATUS 是否是 Up
    • 如果状态是 Up,说明容器正在运行,这是个好消息。
  3. PORTS 是否正确?
    • 请仔细检查 PORTS 这一列。它必须显示 0.0.0.0:8888->5000/tcp 或类似的映射关系。这表示主机的 8888 端口已成功映射到容器的 5000 端口。如果这里是空的或者不正确,说明你运行 docker run 命令时 -p 参数可能有误。

第二步:查看容器日志

如果容器没有运行 (状态是 Exited),或者虽然在运行但服务依然无法访问,那么最重要的一步就是查看日志。日志会告诉我们应用程序在容器内部发生了什么。

运行以下命令来获取容器的日志:

docker logs my-first-container

报错日志

我这里看到这个错误,于是去from-werkzeugurls-import-url_quote-问题根源

分析日志输出:

  • 情况A:看到错误信息 (Error)
    • 如果你在日志中看到任何像 SyntaxError, ModuleNotFoundError, ImportError 或其他 Python 错误堆栈信息,说明是你的 app.py 代码有问题。请检查代码是否和教程中的完全一致。最常见的错误是 pip install 失败或者代码缩进错误。
  • 情况B:看到 Flask 正常的启动信息
    • 如果你看到类似下面的信息,说明 Flask 应用本身是正常启动的:
       * Serving Flask app 'app'
       * Running on http://0.0.0.0:5000
       * Press CTRL+C to quit
      
    • 如果日志正常,但你依然无法访问,问题很可能出在 端口映射网络/防火墙 上。

第三步:常见问题和解决方案汇总

根据以上检查,这里是问题排查的清单:

  1. 问题:容器启动后立即退出 (Exited)。

    • 原因:应用代码有错误。
    • 解决:运行 docker logs my-first-container 查看具体错误,修改 app.pyrequirements.txt。修改后,你需要重新构建镜像重新运行容器
      # 1. 停止并删除旧容器
      docker rm my-first-container
      
      # 2. 重新构建镜像
      docker build -t my-web-app:v1 .
      
      # 3. 重新运行容器
      docker run -d -p 8888:5000 --name my-first-container my-web-app:v1
      
  2. 问题:容器在运行 (Up),但 docker psPORTS 列是空的。

    • 原因:运行容器时忘记了 -p 8888:5000 参数。
    • 解决:停止并删除现有容器,然后使用正确的 docker run 命令重新运行。
      docker stop my-first-container
      docker rm my-first-container
      docker run -d -p 8888:5000 --name my-first-container my-web-app:v1
      
  3. 问题:容器在运行,端口映射也正确,日志也正常,但就是无法访问。

    • 原因1:你电脑的 8888 端口可能被其他程序占用了(比如另一个开发服务)。

    • 解决1:尝试换一个主机端口,比如 8889

      docker stop my-first-container
      docker rm my-first-container
      docker run -d -p 8889:5000 --name my-first-container my-web-app:v1
      

      然后访问 http://localhost:8889

    • 原因2:防火墙或安全软件。公司电脑或一些安全软件可能会阻止端口访问。

    • 解决2:暂时关闭防火墙或安全软件进行测试。

    • 原因3 (特别是 Windows 用户):如果你在使用一些旧版本的 Docker 或者网络配置特殊的虚拟机,localhost 可能无法直接映射。

    • 解决3:尝试使用 127.0.0.1:8888 访问。如果还不行,可以找到 Docker 虚拟机的 IP 地址来访问。

请按照这个顺序排查,99% 的问题都能通过检查 容器状态容器日志 来解决。如果你能把 docker psdocker logs my-first-container 的输出结果贴出来,我可以给你更精确的诊断。


from werkzeug.urls import url_quote 问题根源

你遇到的错误是 ImportError: cannot import name 'url_quote' from 'werkzeug.urls'

  • 简单解释:你的应用程序(Flask)依赖于另一个名为 Werkzeug 的底层库。你安装的 Flask 版本 (2.2.2) 需要从 Werkzeug 库中导入一个叫做 url_quote 的函数。然而,pip 在安装依赖时,为你安装了一个非常新Werkzeug 版本(3.0 或更高版本),而在这个新版本中,url_quote 这个函数已经被移除了,从而导致了 ImportError(导入错误)。

  • 为什么会发生?:在你的 requirements.txt 文件中,你只指定了 Flask==2.2.2pip 在安装它时,会去自动安装 Flask 所需的依赖(比如 Werkzeug),并且通常会选择最新的可用版本。这就导致了 Flask (旧) 和 Werkzeug (新) 之间的不兼容。

解决方案

解决方法很简单:我们需要在 requirements.txt 中明确指定一个与 Flask==2.2.2 兼容的 Werkzeug 版本。Werkzeug 2.x 版本是兼容的。

请按照以下步骤操作:

第一步:修改 requirements.txt

打开你的项目文件夹中的 requirements.txt 文件,将其内容修改为:

Flask==2.2.2
Werkzeug==2.2.2

为什么要这样做? 通过“锁定”或“固定”Werkzeug 的版本,我们确保了每次构建 Docker 镜像时,安装的都是经过测试、相互兼容的库版本组合。这正是 Docker 实现环境一致性和可复现性的核心思想之一。


第二步:停止并删除旧的容器

由于之前的容器是基于错误的镜像创建的,我们需要先清理它。

# 停止正在运行的容器(如果它还在尝试运行的话)
docker stop my-first-container

# 删除已停止的容器
docker rm my-first-container

删除容器

如果命令提示 “No such container”,说明容器已经停止并被移除了,这没关系,直接进行下一步即可。


第三步:重新构建 Docker 镜像

由于我们修改了 requirements.txt,镜像的构建指令已经发生了变化,所以必须重新构建镜像。Docker 会很智能地利用缓存,只重新执行发生变化的步骤(即 RUN pip install 之后的步骤)。

在你的项目文件夹中,运行 build 命令:

docker build -t my-web-app:v1 .
![重构Docker镜像](images/index/index-14.png)

第四步:重新运行容器

现在,使用新构建的、包含了正确库版本的镜像来启动容器。

docker run -d -p 8888:5000 --name my-first-container my-web-app:v1

启动容器

第五步:再次验证

等待几秒钟让容器启动,然后再次访问 http://localhost:8888

问题解决

这次,你应该就能成功看到 “Hello, Docker! This is a simple web service.” 的消息了。

这个错误完美地展示了为什么在 requirements.txt 中锁定依赖版本是如此重要,尤其是在使用 Docker 创建可复现、无意外的环境时。

wsl中镜像网络与docker网络冲突,使用netsh winsock reset修改网络设置之后,docker连不上 – 解决

报错信息 alt text

解决方法,将wsl setting的网络调到默认的nat模式,然后重置网络 wsl setting 重置网络

然后就ok了

网络ok

最后修改于 Jul 03, 2025 14:54 +0800
使用 Hugo 构建
主题 StackJimmy 设计