Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Compose and execute command on starting container

I am trying to get my head around the COMMAND option in docker compose. In my current docker-compose.yml i start the prosody docker image (https://github.com/prosody/prosody-docker) and i want to create a list of users when the container is actually started.

The documentation of the container states that a user can be made using environment options LOCAL, DOMAIN, and PASSWORD, but this is a single user. I need a list of users.

When reading some stuff around the internet it seemed that using the command option i should be able to execute commands in a starting or running container.

xmpp:
    image: prosody/prosody
    command: prosodyctl register testuser localhost testpassword
    ports:
        - "5222:5222"
        - "127.0.0.1:5347:5347"

But this seems not to work, i checked to running container using docker exec -it <imageid> bash but the user is not created.

Is it possible to execute a command on a started container using docker-compose or are there other options?

like image 284
Marco Avatar asked May 01 '15 06:05

Marco


People also ask

Does docker compose start container?

Using the Compose command line tool you can create and start one or more containers for each dependency with a single command ( docker-compose up ). Together, these features provide a convenient way for developers to get started on a project.

How do I run docker compose up at startup?

Use restart: always in your docker compose file. Docker-compose up -d will launch container from images again. Use docker-compose start to start the stopped containers, it never launches new containers from images. You may not want to use always , but maybe unless-stopped .

What does docker compose start do?

The docker compose start command is useful only to restart containers that were previously created, but were stopped. It never creates new containers.


2 Answers

The COMMAND instruction is exactly the same as what is passed at the end of a docker run command, for example echo "hello world" in:

docker run debian echo "hello world"

The command is interpreted as arguments to the ENTRYPOINT of the image, which in debian's case is /bin/bash. In the case of your image, it gets passed to this script. Looking at that script, your command will just get passed to the shell. I would have expected any command you pass to run successfully, but the container will exit once your command completes. Note that the default command is set in the Dockerfile to CMD ["prosodyctl", "start"] which is presumably a long-running process which starts the server.

I'm not sure how Prosody works (or even what it is), but I think you probably want to either map in a config file which holds your users, or set up a data container to persist your configuration. The first solution would mean adding something like:

volumes:
  - my_prosodoy_config:/etc/prosody

To the docker-compose file, where my_prosody_config is a directory holding the config files.

The second solution could involve first creating a data container like:

docker run -v /etc/prosody -v /var/log/prosody --name prosody-data prosody-docker echo "Prosody Data Container"

(The echo should complete, leaving you with a stopped container which has volumes set up for the config and logs. Just make sure you don't docker rm this container by accident!)

Then in the docker-compose file add:

volumes_from:
   - prosody-data

Hopefully you can then add users by running docker exec as you did before, then running prosodyctl register at the command line. But this is dependent on how prosody and the image behave.

like image 102
Adrian Mouat Avatar answered Oct 10 '22 19:10

Adrian Mouat


CMD is directly related to ENTRYPOINT in Docker (see this question for an explanation). So when changing one of them, you also have to check how this affects the other. If you look at the Dockerfile, you will see that the default command is to start prosody through CMD ["prosodyctl", "start"]. entrypoint.sh just passes this command through as Adrian mentioned. However, your command overrides the default command, so your prosody demon is never started. Maybe you want to try something like

xmpp:
    image: prosody/prosody
    command: sh -c prosodyctl register testuser localhost testpassword && prosodyctl start
    ports:
        - "5222:5222"
        - "127.0.0.1:5347:5347"

instead. More elegant and somehow what the creator seems to have intended (judging from the entrypoint.sh script) would be something like

xmpp:
    image: prosody/prosody
    environment:
        - LOCAL=testuser
        - DOMAIN=localhost
        - PASSWORD=testpassword
    ports:
        - "5222:5222"
        - "127.0.0.1:5347:5347"

To answer your final question: no, it is not possible (as of now) to execute commands on a running container via docker-compose. However, you can easily do this with docker:

docker exec -i prosody_container_name prosodyctl register testuser localhost testpassword

where prosody_container_name is the name of your running container (use docker ps to list running containers).

like image 33
f0xdx Avatar answered Oct 10 '22 19:10

f0xdx