I am trying to do something strange but it should be possible - easy even.
All I want to do is start a linux container straight into the shell in interactive mode.
The compose file is:
services:
All that happens when I use compose up is that it attaches and I can type return but all I see is new lines. Detach works.
I’ve tried other versions of linux, /bin/bash in place of sh, separate dockerfile, with -i, without -i and so on. If I detach from the container and use an attach then I get what I want i.e. a running bash shell in interactive mode - I just want it without having to detach and then attach.
Any thoughts?
PS I don’t want to use exec or run even though they work
docker compose up is for running one or more services and see the logs optionally when running in attached mode. In theory, Docker Compose could detect when there is only one service and allow you to attach to the standard input not just to the output streams, but it seems it doesn’t happen, so you see new lines only because the container never accepts your input and there is no log either. .
Having been thinking about it I realise that perhaps the key question is why when I just use compose up and at the end of the build etc it reports that it is attaching I get a different result from when the container is running and I use compose attach. When I attach it works and I have an interactive shell in a tty but when I just compose up it doesn’t work.
Shouldn’t they give the same result? Is this a bug I should report?
That is the difference. It doesn’t make sense to attach to standard inputs when running multiple services. You have one, but compose up still cares about logs, not the standard input. When you run docker attach, you get all the input and output streams since then you attach to only a single container.
You asked us to accept that you didn’t want to use docker compose run, and I did, but since I don’t see why this behaviour would change soon, can you share a little bit about why you want to use only compsoe up? Maybe we can recommend an alternative way to what you wanted to solve with only compose up.
I admit that its subtle and I have been thinking about it but surely compose should do a full attach to a compose up that has just one service? In the case of more services there should be a command that lets you specify the service to attach to for input. Something like input:service.
My use case is just that I want to use compose to organize a single service. That service will change regularly and need to be rebuilt and run - I just want to built it and run it in one step and have in interactive session.
If it is something that many users think could be useful, developers could implement it. For now, compose up is not for interactive terminals. If I understand correctly, you would like to use a single command that you can run regardless of the current state of the container and just open a terminal and also optionally start the container if it is not running. Every new feature makes a software more complex and gives more chance to make mistakes that lead to bugs, but if it is something that many people need, I’m sure it could be done.
Would you also run something in the container in the background while not using it interactively? This might not be for you, but if you only want to avoid running multiple commands to start a container and run a shell in it, but you don’t need the container when you are not working with it interactively, you could use the --rm flag of docker composse run. That makes sure the container is deleted when you exit the shell, so next time you can run the exact same docker compose run command.
I know the downside is still that you need to know the name of the service but creating a script for it becomes much easier.
After reflecting on the problem I decided that your idea of using docker compose run with perhaps --build added to make sure its up to date was the best solution for my particular problem but I still think a compose file attribute that specified which service was to be interactive is a good idea. I can think of situations where a number of containers need to be spun up an one of them is interactive. The reason that this is better than using up followed by attach say is that it would be coded into the compose file and that would provide the default behavior.
I think it is not a very frequent use-case, but let the developers and other users decide that, not me Please, open a roadmap ticket in the linked GitHub repo if you want to make sure it is not lost in this topic.
Replace echo "hello world" with the actual command and arguments that start your app.
You could even orchestrate tmux to split the pane horizontal or vertically, and run independent commends in each segment, which could look like this (the example is not from inside a container!):
If you are trying to use a container as development environment than please ignore the tmux suggestion, and have a look at devcontainers instead: https://containers.dev. IDE’s like VSCode and JetBrain IDEs have a good integration.