skip to Main Content

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.

2

Answers


  1. Maybe try this for redis

    command:>
       sh -c "redis-server /usr/local/etc/redis/redis.conf"
    

    and for service1

    command:>
       sh -c "for file in /app/ClientApp/dist/myapp/main*.js; do sed -i "s|original-text|replaced-text|" $$file; done"
    
    Login or Signup to reply.
  2. 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 "$@"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search