I can't input after running command in docker, but I can if I execute it manually - docker

I have a docker-compose file for starting a Terraria server, but after starting the server, I can't input any commands. If I start the server directly in my shell, I am able to input commands. How can I get the same result in docker as if I had run the command myself in a shell?
This is the desired behavior, which is what happens when I run it from my shell:
$ TerrariaServerVolume/TerrariaServer -pass xxx -port 7777 -world ~/absolute/path/TerrariaWorldsVolume/testWorldName.wld
Terraria Server v1.4.2.2
Listening on port 7777
Type 'help' for a list of commands.
: Server started
help // my input
Available commands:
... //list of commands
: % //I pressed Ctrl+c
$
This is what actually happens in my docker container:
$ sudo docker-compose up
Terraria Server v1.4.2.2
TerrariaServer_1 |
TerrariaServer_1 | Listening on port 7777
TerrariaServer_1 | Type 'help' for a list of commands.
TerrariaServer_1 |
TerrariaServer_1 | : Server started
^[[6;23
I don't know what ^[[6;23 is, but then here's me trying to input commands:
...
TerrariaServer_1 | : Server started
^[[6;23Rhelp
help
exit
stop
ljadgkljasdgl
^CGracefully stopping... (press Ctrl+C again to force)
Stopping terraria_TerrariaServer_1 ... done
$
This is my setup:
docker-compose.yml
version: "3"
services:
TerrariaServer:
image: "mono:6.8.0.96-slim"
ports:
- 7777:7777
expose:
- 7777
volumes:
- "./TerrariaServerVolume:/Terraria/Server"
- "./TerrariaWorldsVolume:/Terraria/Worlds"
environment:
- WorldName=testWorldName.wld
command: bash -c "/Terraria/Server/TerrariaServer -pass <password> -port 7777 -world /Terraria/Worlds/$WorldName"
stdin_open: true
tty: true

To type other commands after running docker-compose You need to use -d parameter.
Example:
docker-compose up -d
From docs:
-d, --detach Detached mode: Run containers in the background, print new container names.

Related

Docker Compose - give access to docker.sock before running (Telegraf)

UPDATE:
I've tried implementing the accepted answer from here Telegraf can not connect to Docker sock like this in my docker compose file:
telegraf3:
image: telegraf
user: telegraf:$$(stat -c '%g' /var/run/docker.sock)
volumes:
- ./telegraf/telegraf3.conf:/etc/telegraf/telegraf.conf
- /var/run/docker.sock:/var/run/docker.sock
I am getting this error:
Error response from daemon: unable to find group $(stat -c '%g' /var/run/docker.sock): no matching entries in group file
How can i fix this issue? :)
Background:
I'm trying to run Telegraf (https://github.com/influxdata/telegraf) with the docker input. I'm running Telegraf via Docker Compose, and i've configured it roughly like this:
telegraf3:
image: telegraf
volumes:
- ./telegraf/telegraf3.conf:/etc/telegraf/telegraf.conf
- /var/run/docker.sock:/var/run/docker.sock:rw
env_file:
- ./telegraf/telegraf.env
depends_on:
- influxdb
The telegraf configuration uses a docker input plugin to interact with the docker.sock. It doesn't work, i get a permission related error:
test-grafana-telegraf3-1 | 2022-12-29T12:09:10Z E! [inputs.docker] Error in plugin: Got permission denied while trying to connect to the Docker daemon socket at unix:///docker.sock: Get "http://%2Fdocker.sock/v1.24/info": dial unix /docker.sock: connect: permission denied
Basically, the entrypoint.sh script runs telegraf (the application) with the telegraf user, which can't access the docker.sock
There's a fix for this issue described here: Telegraf can not connect to Docker sock
Issue
As i am using docker compose, i would like this fix to be defined in the compose file, and not be dependent on me starting the container with docker run.
I've tried this:
telegraf3:
image: telegraf
volumes:
- ./telegraf/telegraf3.conf:/etc/telegraf/telegraf.conf
- /var/run/docker.sock:/var/run/docker.sock:rw
env_file:
- ./telegraf/telegraf.env
depends_on:
- influxdb
command: ["bash -c -u telegraf $$(stat -c '%g' /var/run/docker.sock)", "/entrypoint.sh"]
But then i get this error:
test-grafana-telegraf3-1 | setpriv: failed to execute bash -c -u telegraf $(stat -c '%g' /var/run/docker.sock): No such file or directory
test-grafana-telegraf3-1 exited with code 127

Included container does't work with docker compose

I have Kafka/Zookeeper container and Divolte container in - https://github.com/divolte/docker-divolte/blob/master/docker-compose.yml, which correctly starts and works by
docker-compose up -d --build
I want to add the hdfs container - https://hub.docker.com/r/mdouchement/hdfs/ which correctly starts and works by
docker run -p 22022:22 -p 8020:8020 -p 50010:50010 -p 50020:50020 -p 50070:50070 -p 50075:50075 -it mdouchement/hdfs
But after adding the code to yml:
hdfs:
image: mdouchement/hdfs
environment:
DIVOLTE_KAFKA_BROKER_LIST: kafka:9092
ports:
- "22022:22"
- "8020:8020"
- "50010:50010"
- "50020:50020"
- "50070:50070"
- "50075:50075"
depends_on:
- kafka
The web http://localhost:50070 and data node http://localhost:8020/ did not answer. Could you help me to add new container? Which of hdfs ports do I have to write as source connection port?
The logs of HDFS container is:
2020-02-21T15:11:47.613270635Z Starting OpenBSD Secure Shell server: sshd.
2020-02-21T15:11:50.440130986Z Starting namenodes on [localhost]
2020-02-21T15:11:54.616344960Z localhost: Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
2020-02-21T15:11:54.616369660Z localhost: starting namenode, logging to /opt/hadoop/logs/hadoop-root-namenode-278b399bc998.out
2020-02-21T15:11:59.328993612Z localhost: Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
2020-02-21T15:11:59.329016212Z localhost: starting datanode, logging to /opt/hadoop/logs/hadoop-root-datanode-278b399bc998.out
2020-02-21T15:12:06.078269195Z Starting secondary namenodes [0.0.0.0]
2020-02-21T15:12:10.837364362Z 0.0.0.0: Warning: Permanently added '0.0.0.0' (ECDSA) to the list of known hosts.
2020-02-21T15:12:10.839375064Z 0.0.0.0: starting secondarynamenode, logging to /opt/hadoop/logs/hadoop-root-secondarynamenode-278b399bc998.out
2020-02-21T15:12:17.249040842Z starting portmap, logging to /opt/hadoop/logs/hadoop--portmap-278b399bc998.out
2020-02-21T15:12:18.253954832Z DEPRECATED: Use of this script to execute hdfs command is deprecated.
2020-02-21T15:12:18.253993233Z Instead use the hdfs command for it.
2020-02-21T15:12:18.254002633Z
2020-02-21T15:12:21.277829129Z starting nfs3, logging to /opt/hadoop/logs/hadoop--nfs3-278b399bc998.out
2020-02-21T15:12:22.284864146Z DEPRECATED: Use of this script to execute hdfs command is deprecated.
2020-02-21T15:12:22.284883446Z Instead use the hdfs command for it.
2020-02-21T15:12:22.284887146Z
Port description:
Ports
Portmap -> 111
NFS -> 2049
HDFS namenode -> 8020 (hdfs://localhost:8020)
HDFS datanode -> 50010
HDFS datanode (ipc) -> 50020
HDFS Web browser -> 50070
HDFS datanode (http) -> 50075
HDFS secondary namenode -> 50090
SSH -> 22
The docker-compose response answer is:
Name Command State Ports
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
divolte-streamsets-quickstart_divolte_1 /opt/divolte/start.sh Up 0.0.0.0:8290->8290/tcp
divolte-streamsets-quickstart_hdfs_1 /bin/sh -c service ssh sta ... Exit 0
divolte-streamsets-quickstart_kafka_1 supervisord -n Up 2181/tcp, 9092/tcp, 9093/tcp, 9094/tcp, 9095/tcp, 9096/tcp, 9097/tcp, 9098/tcp, 9099/tcp
divolte-streamsets-quickstart_streamsets_1 /docker-entrypoint.sh dc -exec Up 0.0.0.0:18630->18630/tcp

Docker-compose does not start containers

I'm new with docker-compose. I have a problem when I use the command "docker-compose up -d" to start a multi-container application what should start the containers with the status "up" but all the time a execute the command the status is "Exit", I'm not sure if I'm doing something wrong, this is my docker-compose.yml file
version: '3'
services: catalog:
image: ciscatalog
hostname: catalogHost
command: hostname
volumes:
- /home/docker:/opt/host
container:
image: dis/ciscontainer
hostname: containerHost
command: hostname
volumes:
- /home/docker:/opt/host
inbound:
image: dsi/cisinbound
hostname: inboundHost
depends_on:
- catalog
links:
- catalog
command: hostname
volumes:
- /home/docker:/opt/host
outbound:
image: dsi/cisoutbound
hostname: outboundHost
depends_on:
- catalog
links:
- catalog
command: hostname
volumes:
- /home/docker:/opt/host
example run:
root#docker1:/home/docker/DSI# docker-compose scale catalog=3 container=4 inbound=1 outbound=1
Creating and starting dsi_catalog_1 ... done
Creating and starting dsi_catalog_2 ... done
Creating and starting dsi_catalog_3 ... done
Creating and starting dsi_container_1 ... done
Creating and starting dsi_container_2 ... done
Creating and starting dsi_container_3 ... done
Creating and starting dsi_container_4 ... done
Creating and starting dsi_inbound_1 ... done
Creating and starting dsi_outbound_1 ... done
root#docker1:/home/docker/DSI# docker-compose up -d
Starting dsi_container_4
Starting dsi_catalog_3
Starting dsi_catalog_1
Starting dsi_container_3
Starting dsi_catalog_2
Starting dsi_container_1
Starting dsi_outbound_1
Starting dsi_inbound_1
Starting dsi_container_2
root#docker1:/home/docker/DSI# docker-compose ps
Name Command State Ports
-------------------------------------------
dsi_catalog_1 hostname Exit 0
dsi_catalog_2 hostname Exit 0
dsi_catalog_3 hostname Exit 0
dsi_container_1 hostname Exit 0
dsi_container_2 hostname Exit 0
dsi_container_3 hostname Exit 0
dsi_container_4 hostname Exit 0
dsi_inbound_1 hostname Exit 0
dsi_outbound_1 hostname Exit 0
Please, can anybody help me? docker-compose version 1.13.
I think I got it: you are overriding the command you give in the dockerfile because you have this line in each of the services
command: hostname
so the only command you give is "hostname", which is actually what is run.
If you run an image with docker, you are probably running a completely different command!
If this is a linux based image, 'hostname' will just print the hostname and then exit. So then the command is stopped which logically will result in a stopped container (exit 0)
Remove the command-override so the containers actually run their respective commands.

HEALTHCHECK of a Docker container running Celery tasks?

I know one of the ways to check health for Docker container is using the commmand
HEALTHCHECK CMD curl --fail http://localhost:3000/ || exit 1
But in case of workers there is no such URL to hit , How to check the container's health in that case ?
The celery inspect ping command comes in handy, as it does a whole trip: it sends a "ping" task on the broker, workers respond and celery fetches the responses.
Assuming your app is named tasks.add, you may ping all your workers:
/app $ celery inspect ping -A tasks.add
-> celery#aa7c21dd0e96: OK
pong
-> celery#57615db15d80: OK
pong
With aa7c21dd0e96 being the Docker hostname, and thus available in $HOSTNAME.
To ping a single node, you would have to run:
celery inspect ping -A tasks.add -d celery#$HOSTNAME
Here, d stands for destination.
The line to add to your Dockerfile:
HEALTHCHECK CMD celery inspect ping -A tasks.add -d celery#$HOSTNAME
Sample outputs:
/app $ celery inspect ping -A tasks.add -d fake_node
Error: No nodes replied within time constraint.
/app $ echo $?
69
Unhealthy if the node does not exist or does not reply
/app $ celery inspect ping -A tasks.add -d celery#$HOSTNAME
-> celery#d39b3d31cc13: OK
pong
/app $ echo $?
0
Healthy when the node replies pong.
/app $ celery inspect ping -d celery#$HOSTNAME
Traceback (most recent call last):
...
raise socket.error(last_err)
OSError: [Errno 111] Connection refused
/app $ echo $?
1
Unhealthy when the broker is not available - I removed the app, so it tries to connect to a local AMPQ and fails
This might not suit your needs, the broker is unhealthy, not the worker.
The below example snippet, derived from that posted by #PunKeel, is applicable for those looking to implement health check in docker-compose.yml which could be used through docker-compose or docker stack deploy.
worker:
build:
context: .
dockerfile: Dockerfile
image: myimage
links:
- rabbitmq
restart: always
command: celery worker --hostname=%h --broker=amqp://rabbitmq:5672
healthcheck:
test: celery -b amqp://rabbitmq:5672 inspect ping -d celery#$$HOSTNAME
interval: 30s
timeout: 10s
retries: 3
Notice the extra $ in the command, so that $HOSTNAME actually gets passed into the container. I also didn't use the -A flag.
Ideally, rabbitmq should also have its own health check, perhaps with curl guest:guest#localhost:15672/api/overview, since docker wouldn't be able to discern if worker is down or the broker is down with celery inspect ping.
For celery 5.2.3 I used celery -A [celery app name] status for the health check. This is how my docker-compose file looks like
worker:
build: .
healthcheck:
test: celery -A app.celery_app status
interval: 10s
timeout: 10s
retries: 10
volumes:
- ./app:/app
depends_on:
- broker
- redis
- database
Landed on this question looking for a health check for Celery workers as part of an Airflow setup (Airflow 2.3.4, Celery 5.2.7), which I eventually figured out. This is a very specific use case of the original question, but might still be useful for some:
# docker-compose.yml
worker:
image: ...
hostname: local-worker
entrypoint: airflow celery worker
...
healthcheck:
test: [ "CMD-SHELL", 'celery --app airflow.executors.celery_executor.app inspect ping -d "celery#$${HOSTNAME}"' ]
interval: 5s
timeout: 10s
retries: 10
restart: always
...
I got inspiration from Airflow's quick-start Docker Compose.

Spring boot app fail to link consul in docker

I am trying to use Consul as discovery service, and another two spring boot app to register with Consul; and put them into docker;
following are my codes:
app:
server:
port: 3333
spring:
application:
name: adder
cloud:
consul:
host: consul
port: 8500
discovery:
preferIpAddress: true
healthCheckPath: /health
healthCheckInterval: 15s
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
2 docker-compose.yml
consul1:
image: "progrium/consul:latest"
container_name: "consul1"
hostname: "consul1"
command: "-server -bootstrap -ui-dir /ui"
adder:
image: wsy/adder
ports:
- "3333:3333"
links:
- consul1
environment:
WAIT_FOR_HOSTS: consul1:8500
There is another similar question Cannot link Consul and Spring Boot app in Docker;
the answer suggests, the app should wait for consul to fully work by using depends_on, which I tried, but didn't work;
the error message is as following:
adder_1 | com.ecwid.consul.transport.TransportException: java.net.ConnectException: Connection refused
adder_1 | at com.ecwid.consul.transport.AbstractHttpTransport.executeRequest(AbstractHttpTransport.java:80) ~[consul-api-1.1.8.jar!/:na]
adder_1 | at com.ecwid.consul.transport.AbstractHttpTransport.makeGetRequest(AbstractHttpTransport.java:39) ~[consul-api-1.1.8.jar!/:na]
besides spring boot application.yml and docker-compose.yml, following is App's Dockerfile
FROM java:8
VOLUME /tmp
ADD adder-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
ADD start.sh start.sh
RUN bash -c 'chmod +x /start.sh'
EXPOSE 3333
ENTRYPOINT ["/start.sh", " java -Djava.security.egd=file:/dev/./urandom -jar /app.jar"]
and the start.sh
#!/bin/bash
set -e
wait_single_host() {
local host=$1
shift
local port=$1
shift
echo "waiting for TCP connection to $host:$port..."
while ! nc ${host} ${port} > /dev/null 2>&1 < /dev/null
do
echo "TCP connection [$host] not ready, will try again..."
sleep 1
done
echo "TCP connection ready. Executing command [$host] now..."
}
wait_all_hosts() {
if [ ! -z "$WAIT_FOR_HOSTS" ]; then
local separator=':'
for _HOST in $WAIT_FOR_HOSTS ; do
IFS="${separator}" read -ra _HOST_PARTS <<< "$_HOST"
wait_single_host "${_HOST_PARTS[0]}" "${_HOST_PARTS[1]}"
done
else
echo "IMPORTANT : Waiting for nothing because no $WAIT_FOR_HOSTS env var defined !!!"
fi
}
wait_all_hosts
exec $1
I can infer that your Consul configuration is located in your application.yml instead of bootstrap.yml, that's the problem.
According to this answer, bootstrap.yml is loaded before application.yml and Consul client has to check its configuration before the application itself and therefore look at the bootstrap.yml.
Example of a working bootstrap.yml :
spring:
cloud:
consul:
host: consul
port: 8500
discovery:
prefer-ip-address: true
Run Consul server and do not forget the name option to match with your configuration:
docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap
Consul server is now running, run your application image (builded previously with your artifact) and link it to the Consul container:
docker run -d -name=my-consul-client-app --link consul:consul acme/spring-app
Your problem is that depends_on does only control the startup order of your services. You have to wait until the consul servers are up and running before starting your spring app. You can do this with this script:
#!/bin/bash
set -e
default_host="database"
default_port="3306"
host="${2:-$default_host}"
port="${3:-$default_port}"
echo "waiting for TCP connection to $host:$port..."
while ! (echo >/dev/tcp/$host/$port) &>/dev/null
do
sleep 1
done
echo "TCP connection ready. Executing command [$1] now..."
exec $1
Usage in you docker file:
COPY wait.sh /wait.sh
RUN chmod +x /wait.sh
CMD ["/wait.sh", "java -jar yourApp-jar" , "consulURL" , "ConsulPort" ]
I just want to clarify that, at last I still don't have a solution, and can't understand the situation here; I tried the suggestion from Ohmen, in APP container, I am able to ping consul1; But the APP still fails to connect consul;
If I only start the consul by following command:
docker-compose -f docker-compose-discovery.yml up discovery
Then I can run the APP directly(through Main), and it is able to connect with spring.cloud.consul.host: discovery;
But if I try to run APP in docker container, like following:
docker run --name adder --link discovery-consul:discovery wsy/adder
It fails again with connection refused;
I am very new to docker & docker-compose; I thought it would be a good example to start, but it seems not that easy for me;

Resources