Pipe input to dockerized socat run on socket present on docker host - docker

My goal is to query Haproxy Runtime API using dockerized socat.
Below command returns empty result (/var/run/haproxy.stat is haproxy socket located on the docker host)
echo "-h" | docker run -a stdin -a stderr alpine/socat stdio /var/run/haproxy.stat
I've tried to add haproxy socket via volume, but the result is still empty.
echo "-h" | docker run -a stdin -a stderr -v /var/run/haproxy.stat:/var/run/haproxy.stat alpine/socat stdio /var/run/haproxy.stat

Command that worked is:
echo "-h" | docker run -i -a stdin -a stderr -a stdout -v /var/run/haproxy.stat:/var/run/haproxy.stat alpine/socat stdio /var/run/haproxy.stat
Needed to add -a stdout and -i to docker run
Following suggestion by BMitch" tried below command and it worked as well
echo "-h" | docker run -i -v /var/run/haproxy.stat:/var/run/haproxy.stat alpine/socat stdio /var/run/haproxy.stat

Related

Why does 'docker run -t' redirect stderr to stdout?

From docker run --help:
-t, --tty Allocate a pseudo-TTY
Very nice. I use that to get color output automatically. The problem is, it also redirects stderr to stdout.
Without -t, stderr isn't redirected, which is what I want:
$ docker run ubuntu ls /aaaaaa
ls: cannot access '/aaaaaa': No such file or directory
$ docker run ubuntu ls /aaaaaa 2> /dev/null
With -t, the error messages are redirected to stdout:
$ docker run -t ubuntu ls /aaaaaa
ls: cannot access '/aaaaaa': No such file or directory
$ docker run -t ubuntu ls /aaaaaa 2> /dev/null
ls: cannot access '/aaaaaa': No such file or directory
$ docker run -t ubuntu ls /aaaaaa > /dev/null
Why is that? Is there a way to still allocate a pseudo-TTY and keep stderr separate?
e.g. I want to run something like this in CI:
docker run ... my-command > out.json
while the logger shows warnings and error messages in color.
You need to give your command a shell session so your container can have its own output redirection and not rely on what docker runtime has setup.
This will print error message as usual:
docker run -t --rm busybox sh -c "ls /aaa"
This will not print error message to your allocated tty:
docker run -t --rm busybox sh -c "ls /aaa 2>/dev/null"
This will print the directory listing of /etc:
docker run -t --rm busybox sh -c "ls /etc 2>/dev/null"

how to pass output of a command to another in shell script

I am trying to ssh into server, and into a docker container to run the service. however I am not able to store containerId into a variable to pass it to enter the container.
#!/bin/bash
ssh test_server << EOF
ls
sudo docker ps | grep 'tests_service_image' | colrm 13 # This command works
containerId=$(sudo docker ps | grep 'tests_service_image' | colrm 13) # This doesn't
sudo docker exec -i "$containerId" bash # Throws error since containerId is empty
./run.sh
EOF
exit
The problem is that you are doing variable/function expansions on your own side. You need to escape those so that those expansions happen on the server side.
#!/bin/sh
ssh test_server << EOF
containerId=\$(sudo docker ps | grep 'tests_service_image' | colrm 13)
sudo docker exec -i "\$containerId" bash
./run.sh
EOF
exit
Edit:
Pass it directly to docker exec command like so
sudo docker exec -i $(sudo docker ps | grep 'tests_service_image' | colrm 13) bash
Original Answer:
This is written assuming that the script execution is done post sshing into the server. but modified the answer to above based on the specific query
container ID is stored in variable containerId, you are getting the error Error: No such container: because you are passing a different variable $container instead of $containerId to docker exec command.

Why does "docker start" disallow parameters as "-a stdin -a stdout"?

The Docker Doc says:
docker run = docker create + docker start
Consider the following command:
docker run -a stdin -a stdout image_id bash
I cannot think out the commands using docker create + docker start equivalent to docker run -a stdin -a stdout image_id bash.
docker create -a stdin -a stdout image_id bash is ok.
If I use docker start -a container_id, then all of stdin, stdout, and stderr will be attached. But I just want stdin and stdout to be attached.
If I use docker start container_id, then nothing will be attached.
Both cases are not what docker run -a stdin -a stdout image_id bash exactly did.
I just wonder, is it really true that docker run = docker create + docker start ?

Piped command is failing inside docker container

I'm executing this command from docker host which is finally not giving me any error on stdout. And completes successfully on prompt but doesn't executes what it is supposed to do inside container.
Can someone please help me identify what am i doing wrong?
docker exec -dt SPSSC /bin/bash -c "grep -ril 'LOCALIZATION_ENABLED="false"' /opt/tpa/confd/config/* | grep -v 'diameter' | xargs sed -i 's/LOCALIZATION_ENABLED="false"/LOCALIZATION_ENABLED="true"/g'"

Why exited docker conatiner are not getting removed?

File name: dockerHandler.sh
#!/bin/bash
set -e
to=$1
shift
cont=$(docker run -d "$#")
code=$(timeout "$to" docker wait "$cont" || true)
docker kill $cont &> /dev/null
docker rm $cont
echo -n 'status: '
if [ -z "$code" ]; then
echo timeout
else
echo exited: $code
fi
echo output:
# pipe to sed simply for pretty nice indentation
docker logs $cont | sed 's/^/\t/'
docker rm $cont &> /dev/null
But whenever I check the docker container status after running the the docker image it is giving list of exited docker containers.
command: docker ps -as
Hence to delete those exited containers I am running manually below command
rm $(docker ps -a -f status=exited -q)
You should add the flag --rm to your docker command:
From Docker man:
➜ ~ docker run --help | grep rm
--rm Automatically remove the container when it exits
removed lines
docker kill $cont &> /dev/null
docker rm $cont
docker logs $cont | sed 's/^/\t/'
and used gtimeout instead timeout in Mac, it works fine.
To install gtimeout on Mac:
Installing CoreUtils
brew install coreutils
In line 8 of DockerTimeout.sh change timeout to gtimeout

Resources