Docker Compose Bash命令在YAML中不起作用,但在容器中起作用

Docker Compose Bash命令在YAML中不起作用,但在容器中起作用,docker,docker-compose,Docker,Docker Compose,下面是我的docker撰写文件 version: '3' services: redis: image: "redis" volumes: - ./redis.conf:/usr/local/etc/redis/redis.conf - ./redis-volume:/data:rw command: redis-server /usr/local/etc/redis/redis.conf service1:

下面是我的docker撰写文件

version: '3'
services:
  redis:
    image: "redis"
    volumes:
      - ./redis.conf:/usr/local/etc/redis/redis.conf
      - ./redis-volume:/data:rw
    command: redis-server /usr/local/etc/redis/redis.conf
    
  service1:
    build: .
    image: 'myregistry.azurecr.io/myapp:latest'
    ports:
      - '5500:80'
    volumes:
      - ./appsettings.json:/app/appsettings.json
    command: bash -c 'for file in /app/ClientApp/dist/myapp/main*.js; do sed -i "s|original-text|replaced-text|" $$file; done'
正如您所看到的,有一个bash命令来替换某些js文件中的特定字符串。当我执行
docker compose up
时,此命令不生效。也没有错误。但是,如果我将CLI插入正在运行的容器中并执行相同的命令(当然,我使用$file而不是$$file,因为这里没有可以转义的内容),则效果很好


请说明我在这里做错了什么。

也许可以为redis试试这个

command:>
   sh -c "redis-server /usr/local/etc/redis/redis.conf"
和服务1

command:>
   sh -c "for file in /app/ClientApp/dist/myapp/main*.js; do sed -i "s|original-text|replaced-text|" $$file; done"

您在评论中提到Dockerfile设置

ENTRYPOINT[“dotnet”,“MyWeb.dll”]
这是使用
命令:
docker compose.yml
文件中生成一个要执行的命令;
bash-c…
指令只是作为附加参数传递给.Net应用程序

如果要保持这种总体方法,最简单的解决方法是覆盖
docker compose.yml
文件中的
entrypoint:
,并确保在文件末尾调用原始命令:

entrypoint:sh-c'用于…中的文件。。。;做sed。。。;完成;dotnet MyWeb.dll'
更好的方法是同时使用入口点部分和命令部分。这里一个有用的模式是编写一个shell脚本进行首次设置,然后启动作为命令行参数给定的主容器进程。这个包装器本身就是您的
入口点
,命令(您的
dotnet MyWeb.dll
)变成
CMD

COPY entrypoint.sh。
#如果chmod+x entrypoint.sh尚未执行,请运行它
ENTRYPOINT[“/”ENTRYPOINT.sh“]#必须是JSON数组语法
CMD[“僵尸网络”,“MyWeb.dll”]
脚本可以执行任何操作,但必须以
exec“$@”
结束才能启动主容器进程。因为它是一个完全正常的shell脚本,所以您可以在Docker之外运行它,并且不需要担心YAML或
sh-c
或编写转义需求

#/垃圾箱/垃圾箱
#将受影响文件中的“原始文本”替换为“替换文本”
对于/app/ClientApp/dist/myapp/main*.js中的文件;做
sed-i“s |原始文本|替换文本|”“$file”
完成
#现在启动主容器进程
执行官“$@”

也许这不是问题所在,但您不需要for循环,sed-i“s|original text | replaced text |”/app/ClientApp/dist/myapp/main*。js只是尝试了这个方法,但不起作用;它是否有
入口点
?或者,该命令是否执行,并且主容器命令执行后,容器立即退出?下面是我的入口点
ENTRYPOINT[“dotnet”,“MyWeb.dll”]
@DavidMaze-好的点。它指引我找到了解决办法。现在,我在docker compose yaml文件中使用了
entrypoint
,而不是
command
,并提供了docker文件中的命令。现在工作正常了。简而言之,对于/app/ClientApp/dist/myapp/main*.js中的文件,
bash-c';do sed-i“s |原始文本|替换文本|”$$文件;完成;dotnet MyWeb.dll“
。你也许可以把这个作为一个答案。我会标记的。对于redis,我没有问题。工作正常。我已尝试使用sh而不是bash,但存在相同问题。请使用build:context:。这里是[link](),如果我理解正确,上下文就是我可以指定dockerfile路径的地方。我不知道这有什么关系。你能解释一下你的建议吗?
command:>
   sh -c "for file in /app/ClientApp/dist/myapp/main*.js; do sed -i "s|original-text|replaced-text|" $$file; done"