Docker: Exec a command on spigot console runnning in a container - shell

To summarize the problem I have:
I want to execute a command on the minecraft console that is running in the container like when I attach to it in interactive mode but without the need to attach to it.
docker attach container_name
command
detach_from_contaienr
Like running docker exec but it puts the command into the stdin of the programm that is running inside the container like in docker attach.
I simply search a oneliner that does the same. Like in this question
Edit:
echo 'say test' | docker attach <container id>
Gives the Error:
the input device is not a TTY
Edit2:
after removing the -t flag on the container linke in this post
echo 'say test' | docker attach <container id>
the command gets to the server as the log reveales but after executing that I am stuck in a blank input because the command doesn't stop somehow
If i now do the double ctrl+c the container stops...
Edit3:
I try to execute these commands on the docker host and execute the command in the running spigot minecraft server

Apparently, you can use a named pipe to do this, as shown here: https://stackoverflow.com/a/26765590/2926055
# in the Docker container
$ mkfifo myfifo
$ java -jar minecraft_server.jar nogui < myfifo
# via your `docker exec`
$ echo 'say test' > myfifo
As noted, be careful you don't accidentally send an EOF character.

Related

How to start docker containers and keep them alive during script execution on MacOS

I have a shell script that tries to start two docker containers in a for loop. The script should not continue the rest of its execution before it has detected the output "Service will run on port" in stdout.
The following code works fine on linux:
for i in "${functionsToStart[#]}"
do
echo "Starting ${i}"
(bash start-server.sh) | grep -q "Service will run on port"
done
#more commands
.
.
.
In MacOs however this will start docker in a virtual environment (docker desktop), and the grep will never match.
When I try to run this as a sub process:
(bash start-server.sh &) | grep -q "Service will run on port"
The grep matches fine but it also kills my sub process and therefore also the container.
I need the containers to keep running for the rest of the script execution, how do I do this in MacOs?
To anyone struggling with this issue for MacOs.
The start-server.sh script mentioned above is the script that starts my docker container. The answer here was using the correct options when executing the docker run command from within the script:
docker run -itd

Send commands directly in running process and indirectly (e. g. with tail)

I am currently building a docker project for running a Minecraft Spigot server.
To achieve this I need to be able to run commands in the running shell (when using docker run -it d3strukt0r/spigot) and indirectly with docker exec <name> console <command>. Unfortunately, I'm not too fond of the bash language.
Currently, I am able to send commands indirectly, which is great when being detached. I got this with:
_console_input="/app/input.buffer"
# Clear console buffers
true >$_console_input
# Start the main application
echo "[....] Starting Minecraft server..."
tail -f $_console_input | tee /dev/console | $(command -v java) $JAVA_OPTIONS -jar /app/spigot.jar --nogui "$#"
And when running the console command, all it does is the following:
echo "$#" >>/app/input.buffer
The code can be found here
Does someone know a way of how to be able to now add the functionality to directly enter commands?
USE CASE ONE: A user may run attached using docker run
docker run -it --name spigot -p 25565:25565 -e EULA=true d3strukt0r/spigot:nightly
In this case, the user should definitely be able to use the console as he is used to (when running java -jar spigot.jar).
If he has a second console open he can also send a command with:
docker exec spigot console "time set day"
USE CASE TWO: A user may run detached using docker run -d
docker run -d --name spigot -p 25565:25565 -e EULA=true d3strukt0r/spigot:nightly
In this case, the user is only able to send commands indirectly.
docker exec spigot console "time set day"
USE CASE THREE AND FOUR: Use docker-compose (look at the use case "two", it's basically the same)
You could make a script that acts like a mini-shell, reading from stdin and writing to /app/input.buffer. Set it as the container's CMD so it runs by default. Put it in the same directory as your Dockerfile and make sure it's executable.
interactive_console
#!/bin/sh
while IFS= read -rp '$ ' command; do
printf '%s\n' "$command"
done >> /app/input.buffer
Dockerfile
COPY interactive_console /usr/bin
CMD interactive_console

Docker exec -it <containerid> dir doesn't work. Why? How to get directory info?

I'm very new to docker.
Also I'm using Docker for Windows (ie Image and Container are for Windows OS).
I'm trying to get a list of all the folders and subfolders to resolve another issue I'm having. I read several post and blogs and seems like I should be able to run
docker exec -it <container id> dir
To get the info as it is suppose to allow me to run commands against the container.
I even ran
docker exec -it f83eb1533b67 help
which gave me a list of commands (because no one tells what are acceptable 'commands'...) and it is listed. however I get the following message when I run DIR command
PS P:\docker\tmp\SqlServerSetup> `docker exec -it f83eb1533b67 dir`
container f83eb1533b671b4462b8a1562da7343185b2dd27e94ff360e0230969d432ec37 encountered an error during CreateProcess: failure in a Windows system call: The system cannot find the file specified. (0x2)
[Event Detail: Provider: 00000000-0000-0000-0000-000000000000] extra info: {"CommandLine":"dir","WorkingDirectory":"C:\\","Environment":{"ACCEPT_EULA":"Y","attach_dbs":"[]","sa_password":"Pass1.4DBAs","sa_password_path":"C:\\ProgramData\\Docker\\secrets\\sa-password"},"EmulateConsole":true,"CreateStdInPipe":true,"CreateStdOutPipe":true,"ConsoleSize":[0,0]}
PS P:\docker\tmp\SqlServerSetup>
Please note: I don't want to persist a volume. Seems like that option is for people that are trying to reuse data.
UPDATE:
This is the statement that i'm using to create the container:
docker run -p 1433:1433 -e sa_password=Pass1.4DBAs -e ACCEPT_EULA=Y -p 11433:1433 --name sqlTraining --cap-add SYS_PTRACE -d microsoft/mssql-server-windows-developer
It works fine. Container is created, but I want to view the filesystem within that container.
For Windows containers, prefix the command with the command shell (cmd) and the /c parameter. For example:
docker exec <container id> cmd /c dir
This will execute the dir command on the specified container and terminate.
Try running:
docker exec -it <container id> sh
to start the interactive shell console. This should help you with debugging.

Entering text into a docker container via ssh from bash file

What I am trying to do is setup a local development database and to prevent everyone having to go through all the steps I thought it would be useful to create a script.
What I have below stop once it is in the terminal, which looks like:
output
./dbSetup.sh
hash of container 0d1b182aa6f1
/ #
At which point I have to manually enter exit.
script
#!/bin/bash
command=$(docker ps | grep personal)
set $command
echo "hash of container ${1}"
docker exec -it ${1} sh
Is there a way I can inject a command via a script into a dockers container terminal?
In order to execute command inside a container, you can use something like this:
docker exec -ti my_container sh -c "echo a && echo b"
More information available at: https://docs.docker.com/engine/reference/commandline/exec/
Your script finds a running Docker container and opens a shell to it. The "-it" makes it interactive and allocates a tty which is why it continues to wait for input, e.g. "exit". If the plan is to execute some commands to initialize a local development database, I'd recommend looking at building an image with a Dockerfile instead. i.e. Once you figure out the commands to run, they would become RUN commands and the container after docker run would expose a local development database.
If you really want some commands to run within the shell after it is started and maintain the session, depending on the base image, you might be able to mount a bash profile that has the required commands, e.g. -v db_profile:/etc/profile.d where db_profile is a folder with the shell scripts you want to run. To get them to run you'd exec sh -l to have the login startup scripts to run.

docker exec bash behaves weirdly

When I do:
docker exec -ti myContainer /bin/bash
I have a new bash terminal on running container myContainer.
Now when I write
docker exec -ti lescompanions /bin/bash -c "echo youpi"
docker only outputs youpi and returns with no interactive terminal created. I was actually expecting docker to create the terminal and run echo youpi within the newly created terminal.
Where am I wrong?
---- EDIT ----
Now how shall I run echo youpi in the new terminal on the existing container and not have the terminal return to the host after the execution of echo youpi?
docker exec takes a command to run a process inside the container while the -it flag attaches an interactive session against that process.
Your session will only live as long as the command given to exec
As others have mentioned the command /bin/bash -c "echo youpi" simply uses bash to run the command echo "echo youpi" and terminates, hence your terminal session terminates also.
You are not doing anything wrong, it's just how bash works. I've checked it on my Ubuntu (without Docker):
$ /bin/bash
(no output, bash instance running)
$ /bin/bash -c "echo youpi"
youpi
(bash finished)
echo youpi is a command that is run inside the container. The echo command prints the arguments given to it, which is youpi in this case, and that is also what you see.

Resources