Docker container immediately exists after loading from compose file (exit code 0) - docker

Perhaps I'm missing something obvious, but I just tried to add the firebase-tools docker image to my docker-compose file:
version: '3.6'
services:
firebase-tools-test:
tty: true
image: andreysenov/firebase-tools
ports:
- 9099:9099
- 4000:4000
- 5000:5000
- 5001:5001
- 9199:9199
- 9005:9005
- 9000:9000
- 8085:8085
- 8080:8080
Howeber when running it immediatly exists with exit code 0. Logs don't show anything at all and I wanted to know if this was a simple misconfiguration and how I could get more verbose logging to see why it's exiting.

Docker does not keep your container running by default. If things done it will exit it. To keep it waiting for input create TTY by using docker run -it for interactive or docker run -dt for detached mode. For compose it would be tty: true, alternatively you overwrite the given CMD by something like
entrypoint: ["tail"]
command: ["-f","/dev/null"]
or command: tail -F anything or another mimic keeping a process running forever..
Remark: This works because the container is just running sh anyways. If there is something different in CMD you have to call that and chain above by command: <command to start container logic> && tail -F anythingor something like that.

Related

Docker keeps restarting without error on logs

I'm trying to create a simple instance using docker-compose with this simple yml(It's a Laravel project, but right now i'm not initializing anything):
version: '3'
services:
api:
image: amazonlinux
container_name: test-backend
restart: unless-stopped
working_dir: /var/www
ports:
- 8000:80
volumes:
- .:/var/www
- ~/.ssh:/root/.ssh
Here i'm just trying to create an AmazonLinux instance to test some libraries i'm installing to let the backend run, but for some reason, when i make docker-compose up, the instance keeps restarting. I tried checking the logs, but they are empty, there is no error message, warning, or anything that tells me what is happening.
I tried running the instance manually with docker run -dit amazonlinux:latest and that works, create an instance with AmazonLinux that doesn't restart, but the compose one keeps doint it. I have also tried wiping everything with
- docker rm $(docker ps -aq) -f
- docker volume rm $(docker volume ls -q) -f
- docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
Yet keeps happening, i restarted Docker, still happens. Other instances of other projects don't have any problem, they can be launched with docker-compose up, it's just this one the one causing a problem, Does someone know what i might be doing wrong? As an aditional detail, i believe this started happening after i made an accidental ctrl+c in the middle of a docker-compose up, but i'm not sure if that might be the cause.
You're not giving your container anything to do.
If you docker image inspect amazonlinux, you can see that the default behavior of the image is to start an interactive bash shell:
[...]
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/bash\"]"
],
[...]
When you start a container via docker-compose up, this is similar to running docker run <containername>: by default, the container is not attached to stdin and does not allocate a tty. When bash is run in this environment, it's default behavior is to exit immediately. You can simulate this yourself by running:
bash < /dev/null
This is why you container keeps restarting: it starts up, bash attempts to run an interactive shell but it can't, so it exits.
The solution here is to run something besides bash. What are you trying to do with this container? You would typically run some sort of service (like a web server, or a database server, or a message broker, or...etc). Set an appropriate command key in the service in your docker-compose.yml.
If you're really just playing around, a good option is sleep inf, which means "do nothing, forever". This will allow the container to start and keep running, and you can then use docker-compose exec to run commands inside wthe container:
version: '3'
services:
api:
image: amazonlinux
container_name: test-backend
restart: unless-stopped
working_dir: /var/www
ports:
- 8000:80
volumes:
- .:/var/www
- ~/.ssh:/root/.ssh
command:
- sleep
- inf

docker-compose working but docker run not

I have a docker-compose with just one image. This is the docker-compose.yml definition:
services:
myNodeApp:
image: "1234567890.dkr.ecr.us-west-1.amazonaws.com/myNodeApp:latest"
container_name: 'myNodeApp'
volumes:
- data:/root/data
But I want to move it to docker run as I am using just one container. Executing a docker run command as the following:
docker run 1234567890.dkr.ecr.us-west-1.amazonaws.com/myNodeApp:latest --name myNodeApp -v "data:/root/data"
But I get this message 1.12.4. However, executing docker-compose up starts the application and shows the log by output.
What is the difference? What is the equivalent of docker-compose up with docker? What am I doing differently?
I think you are looking for this?
docker run -it --name myNodeApp -v "data:/root/data"
1234567890.dkr.ecr.us-west-1.amazonaws.com/myNodeApp:latest
Or maybe this command would help you, because it will build a local image associated with the config in your docker-compose.yml .
docker-compose build
docker images

How do I specify the "model_config_file" variable to tensorflow-serving in docker-compose?

I will preface this by saying that I am inexperienced with docker and docker-compose. I am trying to convert my docker run ... command to a docker-compose.yml file, however, I cannot get the models.config file to be found.
I am able to correctly run a tensorflow-serving docker container using the following docker run ... command:
docker run -t --rm \
tensorflow/serving \
-p 8501:8501 \
-v "$(pwd)/models/:/models/" \
--model_config_file=/models/models.config \
--model_config_file_poll_wait_seconds=60
This works as expected, and the models.config file is found in the container at /models/models.config as expected.
The tensorflow-serving pages do not mention anything about docker-compose, however, I would much rather use this than a docker run ... command. My attempt at a docker-compose file is:
version: '3.3'
services:
server:
image: tensorflow/serving
ports:
- '8501:8501'
volumes:
- './models:/models'
environment:
- 'model_config_file=/models/models.config'
- 'model_config_file_poll_wait_seconds=60'
Using this docker-compose file, the container runs, however, it seems like the environment variables are completely ignored, so I'm not sure if this is how I should set them. The container image looks in the default location for the models.config file, and it doesn't exist there, and so it does not load the configuration defined in models.config.
So, how can I define these values, or run a tensorflow-serving container, using docker-compose?
I appreciate any help.
Thanks
So I have come across a solution elsewhere that I haven't found on any threads/posts/etc that talk about tensorflow/serving, so I will post my answer here.
Adding those options underneath a command section, as follows, works.
version: '3.3'
services:
server:
image: tensorflow/serving
ports:
- '8501:8501'
volumes:
- './models:/models'
command:
- '--model_config_file=/models/models.config'
- '--model_config_file_poll_wait_seconds=60'
I don't know a lot about docker so I don't know if this is an obvious answer, but I didn't find a solution even after a lot of Google'ing.
The problem is that the option --model_config_file is not an environment variable. It is an argument that you can pass to the command that is set as an entrypoint in the image tensorflow/serving.
If we look at the Dockerfile that was used to build the image, we can see :
# Create a script that runs the model server so we can use environment variables
# while also passing in arguments from the docker command line
RUN echo '#!/bin/bash \n\n\
tensorflow_model_server --port=8500 --rest_api_port=8501 \
--model_name=${MODEL_NAME} --model_base_path=${MODEL_BASE_PATH}/${MODEL_NAME} \
"$#"' > /usr/bin/tf_serving_entrypoint.sh \
&& chmod +x /usr/bin/tf_serving_entrypoint.sh
ENTRYPOINT ["/usr/bin/tf_serving_entrypoint.sh"]
This script accept various arguments (you can see them by running docker run -t --rm tensorflow/serving --help)
As far as I know, the only environment variables used by TF serving are MODEL_VERSION and MODEL_NAME. model_config_file and model_config_file_poll_wait_seconds are just arguments to the CLI serving executable.
To achieve the result you are after, you could override the entrypoint of the docker image by setting your own entrypoint in the docker-compose.yml :
version: '3.3'
services:
server:
image: tensorflow/serving
ports:
- '8501:8501'
volumes:
- './models:/models'
entrypoint:
- /usr/bin/tf_serving_entrypoint.sh
- --model_config_file=/models/models.config
- --model_config_file_poll_wait_seconds=60
(Note : I did not test that docker-compose.yml file)

image runs properly using docker run -dit, but exits using docker stack deploy -c

I've been porting a web service to docker recently. As mentioned in the title, I'm encountering a weird scenario where in when I run it using docker run -dit, the service runs in the background, but when I use a docker-compose.yml, the service exits.
To be clearer, I have this entrypoint in my Dockerfile:
ENTRYPOINT ["/data/start-service.sh"]
this is the code of start-service.sh:
#!/bin/bash
/usr/local/bin/uwsgi --emperor=/data/vassals/ --daemonize=/var/log/uwsgi/emperor.log
/etc/init.d/nginx start
exec "$#";
as you can see, I'm just starting uwsgi and nginx here in this shell script. The last line (exec) is just make the script accept a parameter and keep it running. Then I run this using:
docker run -dit -p 8080:8080 --name=web_server webserver /bin/bash
As mentioned, the service runs OK and I can access the webservice.
Now, I tried to deploy this using a docker-compose.yml, but the service keeps on exiting/shutting down. I attempted to retrieve the logs, but I have no success. All I can see from doing docker ps -a is it runs for a second or 2 (or 3), and then exits.
Here's my docker-compose.yml:
version: "3"
services:
web_server:
image: webserver
entrypoint:
- /data/start-service.sh
- /bin/bash
ports:
- "8089:8080"
deploy:
resources:
limits:
cpus: "0.1"
memory: 2048M
restart_policy:
condition: on-failure
networks:
- webnet
networks:
- webnet
The entrypoint entry in the yml file is just to make sure that start-service.sh script will be ran with /bin/bash as its parameter, to keep the service running. But again, the service shuts down.
bash will exit without a proper tty. Since you execute bash via exec it becomes PID 1. Whenever PID 1 exits the container is stopped.
To prevent this add tty: true to the service's description in your compose file. This is basically the same thing as you do with -t with the docker run command.

Why does docker compose exit right after starting?

I'm trying to configure docker-compose to use GreenPlum db in Ubuntu 16.04. Here is my docker-compose.yml:
version: '2'
services:
greenplum:
image: "pivotaldata/gpdb-base"
ports:
- "5432:5432"
volumes:
- gp_data:/tmp/gp
volumes:
gp_data:
The issue is when I run it with sudo docker-compose up the GrrenPlum db is shutdowm immedately after starting. It looks as this:
greenplum_1 | 20170602:09:01:01:000050 gpstart:e1ae49da386c:gpadmin-[INFO]:-Starting Master instance 72ba20be3774 directory /gpdata/master/gpseg-1
greenplum_1 | 20170602:09:01:02:000050 gpstart:e1ae49da386c:gpadmin-[INFO]:-Command pg_ctl reports Master 72ba20be3774 instance active
greenplum_1 | 20170602:09:01:02:000050 gpstart:e1ae49da386c:gpadmin-[INFO]:-No standby master configured. skipping...
greenplum_1 | 20170602:09:01:02:000050 gpstart:e1ae49da386c:gpadmin-[INFO]:-Database successfully started
greenplum_1 | ALTER ROLE
dockergreenplumn_greenplum_1 exited with code 0 <<----- Here
Actually, when I start it with just sudo docker run pivotaldata/gpdb-base it's ok.
What's wrong with the docker compose?
First of all, be cautious running this image: the image looks to be badly maintained, and the information on Docker Hub indicates it's neither "official", nor "supported" in any way;
2017-01-09: Toolsmiths reviewed this image; it is not one we create. We make no promises about whether this is up to date or if it works. Feel free to email pa-toolsmiths#pivotal.io if you are the owner and are interested in collaborating with us on this image.
When using images from Docker Hub, it's recommended to either use official images, or when not available, prefer automated builds (in which case the source code of the image can be verified to see what's used to build theimage).
I think the image is built from this GitHub repository, which means it has not been updated for over a year, and uses an outdated (CentOS 6.7) base image that has a huge amount of critical vulnerabilities
Back to your question;
I tried starting the image, both with docker-compose and docker run, and both resulted in the same for me.
Looking at that image, it is designed to be run interactively, or to be used as a base image (and overriding the command).
I inspected the image to find out what the container's command is;
docker inspect --format='{{json .Config.Cmd}}' pivotaldata/gpdb-base
["/bin/sh","-c","echo \"127.0.0.1 $(cat ~/orig_hostname)\" >> /etc/hosts && service sshd start && su gpadmin -l -c \"/usr/local/bin/run.sh\" && /bin/bash"]
So, this is what's executed when the container is started;
echo "127.0.0.1 $(cat ~/orig_hostname)" >> /etc/hosts \
&& service sshd start \
&& su gpadmin -l -c "/usr/local/bin/run.sh" \
&& /bin/bash"
Based on the above, there is no "foreground" process in the container, so the moment /usr/local/bin/run.sh finishes, a bash shell is started. A bash shell wothout a tty attached, exits immediately, at which point the container exits.
To run this image
(Again; be cautious running this image)
Either run the image interactively, by passing it stdin and a tty (-i -t, or -it as a shorthand);
docker run -it pivotaldata/gpdb-base
Or can run it "detached", as long as a tty is passed as well (add the -d and -t flags, or -dt as a shorthand); doing so, keeps the container running in the background;
docker run -dit pivotaldata/gpdb-base
To do the same in docker-compose, add a tty to your service;
tty: true
Your compose file will then look like this;
version: '2'
services:
greenplum:
image: "pivotaldata/gpdb-base"
ports:
- "5432:5432"
tty: true
volumes:
- gp_data:/tmp/gp
volumes:
gp_data:

Resources