macOS中使用Docker发布一个python项目的小纸条

Photo by Muha Ajjan on Unsplash

macOS中使用Docker发布一个python项目的小纸条

·

3 min read

最近写了一个Telegram Bot,它可以使用语音和文字与GPT进行交互,成为了我日常重度使用的工具。从练习英语的听说读,到日常的搜索使用上都让我有了不少收获。终于,日常跑在我笔记本上的日子就要过去了,我需要它能日常跑在我的服务器上,所以准备使用Docker整个image,使得我日常的更新和服务器的迁移更为简单些。所以写下这个小纸条,方便以后自己回来查看。

安装Docker

使用Homebrew安装简单方便:

brew install --cask docker

Homebrew会视你的机器安装Intel或Arm版本的Docker。然后让我们启动Docker

open /Applications/Docker.app

一路Next之类,这就安装好了。记得在你的配置中配置好Docker的虚拟机所使用的资源:

最后,点右上角的Sign in登录到你的dockerhub上。

本地编译image

准备好你的Dockerfile,以下是我常使用的一个为Python项目准备的Dockerfile

FROM python:latest

RUN apt-get update && apt upgrade -y
RUN cd /
COPY . /bot/
RUN cd bot
WORKDIR /bot
RUN pip install -r requirements.txt
CMD [ "python", "bot.py" ,"-c","/conf"]

在Dockerfile所在的文件夹中,打开终端,并构建Docker镜像。在终端中执行以下命令:

docker build -t edgebot .

这将使用名为“bot”的标记构建一个Docker镜像。注意,“.”代表当前目录,因此Docker将在当前目录中查找Dockerfile文件并使用它来构建镜像。此过程可能需要几分钟,具体取决于您的计算机性能和您的网络速度。

当编译好之后,你就可以在本机的镜像列表中看到edgebot了

docker image ls

运行你的image

从image运行

一但在docker镜像列表中看到你编译好的image,你就可以运行它了,接下来让我们尝试运行。你可以发现在Dockerfile中我们运行这个程序时有一个参数-c,它指定了一个配置文件的目录,我们希望运行镜像时的配置文件都从这个目录中来取得。在容器里,它的路径是/conf,在你的Host里,我希望它被mount指向当前目录下的conf目录。

docker run -v "$(pwd)/conf:/conf" edgebot

其中,-v 参数用于挂载卷。$(pwd) 返回当前目录的完整路径,因此 $(pwd)/conf 将是当前目录下的 conf 目录的完整路径。edgebot 是要运行的 Docker 镜像的名称。

使用这个命令,Docker 将运行指定的镜像,并将容器内的 /conf 目录映射到当前目录下的 conf 目录。这意味着您可以在当前目录下编辑配置文件,并且它们将在容器内部可见。

有时我们会遇到程序运行时出现问题,我们希望进入容器查看环境,这样就需要运行容器并起动容器内的shell了。

docker run -it -v "$(pwd)/conf:/conf" edgebot /bin/bash

其中,-it 参数用于分配一个伪终端并启用交互模式,edgebot 是要运行的 Docker 镜像的名称,/bin/bash 是要运行的 shell。

使用这个命令,Docker 将启动指定的镜像并进入容器的 shell。您现在可以在 shell 中执行命令并与容器交互。要退出 shell 并停止容器,请使用 exit 命令。

查看容器列表

一但你运行一个镜像后,Docker就会在本机自动创建一个容器。如果我们运行了上面两个命令,哪么我们可以使用以下命令查看

docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS                     PORTS     NAMES
7521819b97ba   edgebot   "python edge.py -c /…"   6 minutes ago   Exited (0) 5 minutes ago             vigorous_chaplygin
fe3e828f24bd   edgebot   "python edge.py -c /…"   6 minutes ago   Exited (0) 6 minutes ago             focused_driscoll

docker ps将显示所有容器的列表,包括正在运行的容器和已经停止的容器,同样包括容器的 ID、镜像名称、状态、端口映射、创建时间等信息。如果没有-a参数,将只会显示正在运行的容器。

运行容器

要运行指定的容器,可以使用以下命令:

docker start <container_id_or_name>

其中,<container_id_or_name> 是要启动的容器的 ID 或名称。

使用这个命令,Docker 将启动指定的容器并使其处于运行状态。注意,如果容器已经在运行中,则此命令不会产生任何效果。

如果要同时进入已经在运行的容器的 shell,可以使用以下命令:

docker exec -it <container_id_or_name> /bin/bash

其中,-it 参数用于分配一个伪终端并启用交互模式,<container_id_or_name> 是要进入的容器的 ID 或名称,/bin/bash 是要运行的 shell。

使用这个命令,Docker 将进入指定的容器并进入容器的 shell。您现在可以在 shell 中执行命令并与容器交互。要退出 shell,请使用 exit 命令。

容器管理

容器名称管理

要修改容器的名称,可以使用以下命令:

docker rename <old_name> <new_name>

其中,<old_name> 是原始的容器名称,<new_name> 是要修改的新容器名称。

使用这个命令,Docker 将重命名指定的容器。请注意,容器名称必须是唯一的。

如果要查看已命名的容器的列表,可以运行以下命令:

docker ps --format "table {{.ID}}\t{{.Names}}"

这将显示当前计算机上所有容器的 ID 和名称列表。您可以在该列表中查找容器的名称并使用上述 docker rename 命令将其重命名。同样也可以加入-a参数也列出没有在运行的容器。

首次运行镜像时指定容器名称

如果要在运行镜像时指定容器的名称,可以使用以下命令:

docker run --name <container_name> <image_name>

其中,--name 参数用于指定容器的名称,<container_name> 是您要为容器指定的名称,<image_name> 是要运行的 Docker 镜像的名称。

使用这个命令,Docker 将启动指定的镜像,并使用指定的容器名称创建一个新容器。如果未指定容器名称,则 Docker 将自动生成一个随机的容器名称。

注意,容器名称必须是唯一的。如果您尝试为已经存在的容器分配一个重复的名称,则会收到一个错误消息。为了避免这种情况,请在创建容器时始终指定唯一的名称。

发布镜像

一般我们会要构建并将一个 Docker 镜像推送到 Docker Hub 上,可以按照以下步骤进行操作:

  1. 在本地计算机上构建 Docker 镜像:

     docker build -t <username>/<image_name>:<tag> .
    

    其中,<username> 是您的 Docker Hub 用户名,<image_name> 是您要构建的镜像名称,<tag> 是您要为镜像指定的标签(例如版本号)。. 表示使用当前目录中的 Dockerfile 构建镜像。

  2. 运行以下命令以验证构建的镜像已经创建:

     docker images
    

    这将显示本地计算机上的所有 Docker 镜像列表,包括刚刚构建的镜像。

  3. 使用以下命令将镜像推送到 Docker Hub:

     docker push <username>/<image_name>:<tag>
    

    其中,<username> 是您的 Docker Hub 用户名,<image_name> 是您要推送的镜像名称,<tag> 是您要推送的标签。

    注意,您需要先登录到 Docker Hub 才能将镜像推送到您的账户。您也可以使用以下命令登录:

     docker login
    

    运行这个命令后,您需要输入您的 Docker Hub 用户名和密码。

  4. 使用以下命令检查您刚刚推送的镜像是否已经上传到 Docker Hub:

     docker search <image_name>
    

    这将显示 Docker Hub 上所有具有指定名称的镜像列表。如果您可以看到您刚刚推送的镜像,则表示您已成功将镜像推送到 Docker Hub。

清除容器和镜像

要清除不使用的 Docker 镜像和容器,可以使用以下命令:

  1. 清除所有停止的容器:

     docker container prune
    

    这将删除所有已停止的容器,这些容器不会影响任何运行中的应用程序。

  2. 清除所有未使用的镜像和悬空的构建缓存:

     docker image prune -a
    

    这将删除所有未被任何容器使用的镜像以及悬空的构建缓存。

  3. 清除所有未使用的卷:

     docker volume prune
    

    这将删除所有未被任何容器使用的卷。

注意:在执行这些命令之前,请确保您已经备份了需要保留的数据。这些命令将清除您计算机上所有未使用的容器、镜像和卷。如果您不小心清除了某些内容,可能会导致数据丢失或不可恢复。

如果您想要清除指定的 Docker 容器和镜像,可以使用以下命令:

  1. 清除指定的容器:

     docker rm <container_id>
    

    其中,<container_id> 是您要删除的容器的 ID。您可以使用 docker ps -a 命令查看所有容器的 ID。

    如果要删除多个容器,请使用以下命令:

     docker rm <container_id_1> <container_id_2> ...
    
  2. 清除指定的镜像:

     docker rmi <image_id>
    

    其中,<image_id> 是您要删除的镜像的 ID。您可以使用 docker images 命令查看所有镜像的 ID。

    如果要删除多个镜像,请使用以下命令:

     docker rmi <image_id_1> <image_id_2> ...
    

支持不同平台

如果要同时支持ARM64和x64架构的Docker镜像,需要在构建Dockerfile时使用多架构支持(Multi-Architecture Support)功能。

  1. 在Dockerfile中包含适用于两个架构的指令和指令参数。

例如,下面是一个使用Alpine作为基础映像的Dockerfile示例,其中包括适用于ARM64和x64架构的指令:

# syntax = docker/dockerfile:1.2
FROM --platform=linux/amd64,linux/arm64/python:latest
WORKDIR /app
COPY . .
RUN apk add --no-cache gcc musl-dev
CMD ["./myapp"]

这个Dockerfile中的 --platform=linux/amd64,linux/arm64 参数指示Docker同时支持x64和ARM64架构。

  1. 构建Docker镜像

使用以下命令构建Docker镜像:

docker buildx build --platform linux/amd64,linux/arm64 -t myimage:latest .

这个命令中的 --platform=linux/amd64,linux/arm64 参数告诉Docker同时构建x64和ARM64架构的镜像。

  1. 验证Docker镜像

可以使用以下命令验证Docker镜像是否同时支持ARM64和x64架构:

docker run --rm --platform=linux/amd64,linux/arm64 myimage:latest uname -m

这个命令将会在容器内运行 uname -m 命令并输出容器的架构,如果输出中同时包含 x86_64aarch64,则表示Docker镜像同时支持ARM64和x64架构。

通过使用多架构支持功能,可以轻松地在Docker容器中同时支持多种架构,并在需要时运行合适的容器。

运行docker buildx时有可能你会看到如下的错误信息

ERROR: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")

这个错误信息是因为Docker目前的默认构建驱动程序(docker driver)不支持多架构构建。

多架构构建(Multi-Architecture Support)是Docker的一个新功能,允许构建同时支持不同架构的Docker镜像,例如x86_64、ARM64等。

要使用多架构构建功能,需要使用Buildx驱动程序,而不是默认的Docker驱动程序。Buildx是一个构建工具,它可以在Docker中同时构建多个架构的镜像,并且可以在不同的构建平台上运行。

要解决这个错误,需要使用Buildx驱动程序。可以按照以下步骤来使用Buildx:

  1. 安装Buildx插件
docker buildx install
  1. 创建一个Buildx构建器
docker buildx create --name mybuilder
  1. 切换到Buildx构建器
docker buildx use mybuilder
  1. 构建Docker镜像
docker buildx build --platform linux/amd64,linux/arm64 -t myimage:latest .

这些命令中的 --platform=linux/amd64,linux/arm64 参数告诉Buildx同时构建x64和ARM64架构的镜像。

通过使用Buildx构建器,可以轻松地构建同时支持多种架构的Docker镜像,并在需要时运行合适的容器。

Did you find this article valuable?

Support 老房东 by becoming a sponsor. Any amount is appreciated!