首页 > 解决方案 > 将 docker container exec 命令转换为 docker-compose yml 使用

问题描述

我想在docker container exec我的 docker-compose.yml 文件中执行一个命令。我想在docker container exec运行 docker-compose.yml 文件后避免运行命令。任何人都可以通过修改或更新 docker-compose.yml 文件来建议如何做到这一点?

docker conainter exec我想避免运行的命令是:

docker exec yacserver YACReaderLibraryServer add-library "My Comic Library" /comics

我的 docker-compose.yml 文件是:

version: "3.8"

services:
  yacserver:
    container_name: yacserver
    image: xthursdayx/yacreaderlibrary-server-docker:latest
    restart: unless-stopped

    environment:
      TZ: 'Europe/London' # Put your own timezone here

    # We'll use host networking simply because it is way easier to setup.
    #network_mode: host
    
    # Volumes store your data between container upgrades
    volumes:
      - '/mnt/hgfs/Comics/yaclibrary:/comics:rw'
    
    ports:
      - '8080:8080'

我在解决我的问题时尝试了以下方法:

  1. 进入容器docker container exec -it yacserver sh并运行YACReaderLibraryServer add-library "My Comic Library" /comics。这确实在容器上添加了“我的漫画库”,并验证 sh 作为容器图像的一部分存在。

  2. 根据上面的命令参数创建替代 docker-compose.yml 文件,如下所示command: sh "YACReaderLibraryServer add-library 'Meerkat Comic Library' /comics"

或者

command: sh -c "YACReaderLibraryServer add-library 'My Comic Library' /comics"

或者

command: sh -c 'YACReaderLibraryServer add-library "My Comic Library" /comics'

然而,这些都不能将 My Comic Library 添加到容器中,所有这些都作为单个 docker-compose.yml 文件的一部分。

以下不作为已完成 docker-compose.yml 文件的示例:

version: "3.8"

services:
  yacserver:
    container_name: yacserver
    image: xthursdayx/yacreaderlibrary-server-docker:latest
    restart: unless-stopped

    environment:
      TZ: 'Europe/London' # Put your own timezone here

    # We'll use host networking simply because it is way easier to setup.
    #network_mode: host
    
    # Volumes store your data between container upgrades
    volumes:
      - '/mnt/hgfs/Comics/yaclibrary:/comics:rw'
    
    ports:
      - '8080:8080'

    command: sh -c 'YACReaderLibraryServer add-library "My Comic Library" /comics'

感激地收到任何帮助。

标签: dockerdocker-composeexec

解决方案


如果您需要在容器启动之后,但在主容器命令运行之前运行命令,您可以使用入口点包装脚本来执行此操作。如果 Dockerfile 同时具有 anENTRYPOINT和 a CMD,则CMD作为参数传递给ENTRYPOINT,然后如果ENTRYPOINT是 shell 脚本,它可以使用exec "$@"命令将自身替换为CMD.

例如:

#!/bin/sh
# entrypoint.sh

# Load the externally-provided database
YACReaderLibraryServer add-library "My Comic Library" /comics

# Run the main container command
exec "$@"

在您的 Dockerfile 中,确保COPY将此脚本放入并将其设置为ENTRYPOINT. (如果你之前拆分ENTRYPOINTCMD——我看到几个 SO 问题设置ENTRYPOINT ["python"],例如——将两个部分组合成一个CMD。)

# If a previous COPY command doesn't already include it
COPY entrypoint.sh .
# Must use JSON-array syntax
ENTRYPOINT ["./entrypoint.sh"]
# Unchanged from before
CMD ./my_app

请注意,此方法仅在您的设置命令不涉及与正在运行的服务器交互时才有效。cpsed和之类的东西export很棒。如果您的add-library命令只涉及复制文件,或者如果它是一个独立的程序,直接调用 SQLite 等本地数据库系统,那很好;exec "$@"如果它向服务器发出 HTTP 请求,那将不起作用(并且您将收到“连接被拒绝”错误),因为服务器直到最后一步才会运行。


推荐阅读