Docker container always restarting - docker

I try to start a Docker container from debian image, with a Docker compose file.
But when I do docker ps - a, the container is always restarting. I don't know why :s
Here my dockerfile :
FROM debian:jessie
ENV DEBIAN_FRONTEND noninteractive
RUN mkdir /home/server
RUN cd /home/server
VOLUME /home/server
CMD /bin/bash
Here my docker compose file :
version: '2'
services:
server:
build: .
restart: always
container_name: server
volumes:
- "/home/binaries:/home/server"

When docker-compose runs your "server" container, it will immediately terminate. A docker container needs at least one running process, otherwise, the container will exit. In your example, you are not starting a process that keeps alive.
As you have configured restart: always, docker-compose will endlessly restart new containers for "server". That should explain the behavior that you describe.
I have seen docker-compose files, where data containers were defined which only mounted images (in combination with volumes_from). They deliberately used /bin/true as a command, which also lead to permanent but harmless restarts. For example:
data:
restart: always
image: postgres:latest
volumes:
- /var/lib/postgresql
command: "true"
If restarts are not what you want, you could start a process in the container that does something useful, like running a web server or a database. But a bash alone is not something that will keep a container alive. A bash running in non-interactive mode will exit immediately.

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

Why does docker-compose up not seem to sync volumes

Here is a simplified version of my docker-compose.yml (it's the volume in buggy-service that does not behave as I expect):
version: '3.4'
services:
local-db:
image: postgres:9.6
environment:
- DB_NAME=${DB_NAME}
# other env vars (not important)
ports:
- 5432:5432
volumes:
- ~/.docker-volumes/${DB_NAME}/postgresql/data:/var/lib/postgresql/data
- postgresql:/docker-entrypoint-initdb.d
buggy-service:
build:
context: .
dockerfile: Dockerfile.test
target: buggy-image
args:
# bunch of args (not important)
volumes:
- /Users/me/temp:/temp
volumes:
postgresql:
driver_opts:
type: none
device: /Users/me/postgresql
o: bind
If I do docker-compose -f docker-compose.yml up -d local-db, a container for it starts up automatically and I find that /Users/me/postgresql on the host machine (Mac OSX) binds correctly to /docker-entrypoint-initdb.d with content synced.
However, if I do docker-compose -f docker-compose.yml up --build -d buggy-service, a container does not start up automatically.
Question: How do I get buggy-service to behave like local-db, i.e., start up automatically with the required volume mounted?
Here's the stripped down version of Dockerfile.test referenced by buggy-service:
FROM microsoft/dotnet:2.1-sdk-alpine AS buggy-image
# Bunch of ARG definitions (not important)
VOLUME /temp
# other stuff (not important)
ENTRYPOINT ["/bin/bash"]
# Other FROMs
Edit 1
A bit more info about what I’m trying to achieve...
The buggy-container I’m trying to get working runs .Net Core as the base image. Its purpose is to run dotnet test and generate coverage reports, which can then be consumed in the host, which may either be a local dev machine or a build server (in this case, BitBucket pipelines).
... followed by docker run -dit --name buggy-container buggy-image
This command creates a new container, not based on anything in the compose yml file. Without a volume specification, it will only get an anonymous volume since you've defined the volume in the Dockerfile (I tend to recommend against defining a volume there). You can see the anonymous volumes with a docker volume ls command, they'll be the ones with a long unique id and no reference to what they belong to.
To define a host volume from docker run, you need the -v flag:
docker run -dit -v /Users/me/temp:/temp --name buggy-container buggy-image
From your now changed question, you have a new issue. Your container specifies a single command to run in the entrypoint:
ENTRYPOINT ["/bin/bash"]
When bash runs, it reads input from stdin. When that input ends, like when you run a container with no input attached, bash will exit. When the process your container runs exits, the container exits. From the details available, I can't tell you what that command should be, but a good starting point is to look at other images on docker hub that perform a similar task that you're trying to run, and look at the Dockerfile they use (many hub images point back to a GitHub repo with the full source).

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.

container exit with code 0 while using docker compose file

I have a dockerfile to install httpd. When i run this dockerfile using the command
docker run -dit /bin/bash,
the container is started and it is running in the background. when i perform docker ps i could see the container running.
I have created a docker-compose.yml file as below,
version: '2'
services:
web:
build:
context: ./web
dockerfile: Dockerfile-apache
image: web:1.0
container_name: web
ports:
- "80:80"
command: service httpd start
i have build this compose file using the
docker-compose build.
Once after that i started the containers using
docker-compose up -d.
The containers are getting exited. i am not sure how to make the containers run at background.
Also i want to make the services running inside the container. For example i need to run the command like service httpd start inside the container and how to do it ?
This is because a Docker container only lives as long as its command runs.
Your command service httpd start will start httpd in the background and then exit. This will terminate httpd and the container.
You will have to run the httpd process directly and in the foreground, see the official image's start script:
httpd -DFOREGROUND
You can't run docker with -dit options together. -d means to run it in background mode and -ti means an interaction with terminal. So, have to run with -d OR with -ti and not both

Strange way to launch a background apache/mysql docker container

I am downloaded a debian image for docker and i have created a container from it.
I haver successfully installed apache and mysql on this container (from /bin/bash).
I want to make this docker container running in background.
I have tried a lot of tutorials (i have created images with Dockerfile) but nothing really works. Apache and mysql were run as root...
So i have launched this command:
docker run -d -p 80:80 myimagefile /bin/bash -c "while true; do sleep 10; done"
Then i have attached a /bin/bash with exec command and i started manually mysql and apache2 (/etc/init.d/ scripts). When i type CTRL-D, the bash is killed but the container stills in background, with mysql and apache alive !
I am wondering if this method is correct or is it something ugly ? Is there a best way to do this ?
I do not want to write a Dockerfile that describes how to install apache and mysql. I have made my own image, with my application and all prerequisites.
I just want to start a container from my image and start automatically apache and mysql.
I have a second question: With my method, the container is not reloaded if i reboot physical computer. How can i start it automatilcy with persistence of data ?
Thanks
I would suggest using running mysql and apache in separate containers. Additionally the docker hub already has container images that you could re-use:
https://hub.docker.com/_/mysql/
The following is an example of a docker-compose file that describe how to launch Drupal
version: '2'
services:
db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=letmein
- MYSQL_DATABASE=drupal
- MYSQL_USER=drupal
- MYSQL_PASSWORD=drupal
volumes:
- /var/lib/mysql
web:
image: drupal
depends_on:
- db
ports:
- "8080:80"
volumes:
- /var/www/html/sites
- /var/www/private
Run as follows
$ docker-compose up -d
Creating dockercompose_db_1
Creating dockercompose_web_1
Which exposes Drupal on port 8080
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
dockercompose_db_1 docker-entrypoint.sh mysqld Up 3306/tcp
dockercompose_web_1 apache2-foreground Up 0.0.0.0:8080->80/tcp
Note:
When running the drupal installer, configure it to connect to a host called "db", which is the mysql container.

Resources