Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Compose Bash Command Not Working In YAML but Works Inside Container

Following is my docker compose file.

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'

As you can see there is a bash command to replace certain string in some js files. This command is not take effect when I do docker-compose up. There is no error as well. However it works fine if I CLI into the running container and execute the same command (except that off course, I use $file instead of $$file as there is nothing to escape here).

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

Please suggest what I am doing wrong here.

like image 689
NaveenBhat Avatar asked Nov 20 '25 04:11

NaveenBhat


1 Answers

You mention in a comment that your Dockerfile sets

ENTRYPOINT ["dotnet", "MyWeb.dll"]

This is combined with the command: from the docker-compose.yml file to form a single command to execute; the bash -c ... instruction just gets passed as additional parameters to your .Net application.

If you want to keep this overall approach, the simplest workaround is to override entrypoint: in your docker-compose.yml file, and make sure to invoke the original command at the end of it:

entrypoint: sh -c 'for file in ...; do sed ...; done; dotnet MyWeb.dll'

A better approach could be to use both an entrypoint part and a command part. A useful pattern here is to write a shell script that does the first-time setup, then launches the main container process given as command-line parameters. This wrapper itself is your ENTRYPOINT and the command (your dotnet MyWeb.dll) becomes CMD.

COPY entrypoint.sh .
# RUN chmod +x entrypoint.sh   # if it's not already executable
ENTRYPOINT ["./entrypoint.sh"] # must be JSON-array syntax
CMD ["botnet", "MyWeb.dll"]

The script can do anything, but must end with exec "$@" to launch the main container process. Since it is a totally normal shell script, you can run it outside of Docker, and you don't need to worry about YAML or sh -c or Compose escaping requirements.

#!/bin/sh

# Replace "original-text" with "replaced-text" in the affected files
for file in /app/ClientApp/dist/myapp/main*.js; do
  sed -i "s|original-text|replaced-text|" "$file"
done

# Now launch the main container process
exec "$@"
like image 66
David Maze Avatar answered Nov 22 '25 03:11

David Maze