I have a Dockerfile set up to run a service that requires some subsequent commands be run in order to initialize properly. I have created a startup script with the following structure and set it as my entrypoint:
Set environment variables for service, generate certificates, etc.
Run service in background mode.
Run configuration commands to finish initializing service.
Obviously, this does not work since the service was started in background and the entry point script will exit with code 0. How can I keep this container running after the configuration has been done? Is it possible to do so without a busy loop running?
How can I keep this container running after the configuration has been done? Is it possible to do so without a busy loop running?
Among your many options:
Use something like sleep inf, which is not a busy loop and does not consume CPU time.
You could use a process supervisor like supervisord to start your service and start the configuration script.
You could run your configuration commands in a separate container after the service container has started.
You can look at this GitHub issue and specific comment -
https://github.com/docker-library/wordpress/issues/205#issuecomment-278319730
To summarize, you do something like this:
version: '2.1'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
image: wordpress:latest
volumes:
- "./wp-init.sh:/usr/local/bin/apache2-custom.sh"
depends_on:
db:
condition: service_started
ports:
- 80:80
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: wordpress
command:
- apache2-custom.sh
wp-init.sh is where you write the code to execute.
Note the command yml tag:
command:
- apache2-custom.sh
because we bounded the two in the volumes tag, it will actually run the code in wp-init.sh within your container.
Related
I have docker-compose.yml on my local machine like below:
version: "3.3"
services:
api:
build: ./api
volumes:
- ./api:/api
ports:
- 3000:3000
links:
- mysql
depends_on:
- mysql
app:
build: ./app
volumes:
- ./app:/app
ports:
- 80:80
mysql:
image: mysql:8.0.27
volumes:
- ./mysql:/var/lib/mysql
tty: true
restart: always
environment:
MYSQL_DATABASE: db
MYSQL_ROOT_PASSWORD: qwerty
MYSQL_USER: db
MYSQL_PASSWORD: qwerty
ports:
- '3306:3306'
The api is NestJS app, app, mysql - Angular and Mysql respectively. And I need to work with this one localy.
How could I make so, that any my changes will be applied without rebuilding containers every time?
You don't have to build an image for a development environment with your sources in it. For NestJS, and since you're using Docker (I voluntary specify this because it exists other container runtimes), you can simply run a NodeJS image from the Docker main registry: https://hub.docker.com/_/node.
You could run it with:
docker run -d -v ./app:/app node:12-alpine /app/index.js
N.B.: I choose 12-alpine for the example. I imagine the file to start your app is index.js, replace it with yours.
You must consider to install the node dependencies yourself and they must be in the ./app directory.
For docker-compose, it could look like this:
version: "3.3"
services:
app:
image: node:12-alpine
command: /app/index.js
volumes:
- ./app:/app
ports:
- "80:80"
Same way for your API project.
For a production image, it is still suggested to build the image with the sources in it.
Say you're working on your front-end application (app). This needs to make calls out to the other components, especially api. So you can start the things it depends on, but not the application itself
docker-compose up -d api
Update your application configuration for this different environment; if you would have proxied to http://api:3000 before, for example, you need to change this to http://localhost:3000 to connect to the container's published ports:.
Now you can develop your application totally normally, without doing anything Docker-specific.
# outside Docker, on your normal development workstation
yarn run dev
$EDITOR src/components/Foo.tsx
You might find it convenient to use environment variables for these settings that will, well, differ per environment. If you're developing the back-end code but want to attach a live UI to it, you'll either need to rebuild the container or update the front-end's back-end URL to point at the host system.
This approach also means you do not need to bind-mount your application's code into the container, and I'd recommend removing those volumes: blocks.
I have a docker container which is brought up with the help of a docker-compose file along with a database container. I want to do this:
Keep the database container running
Schedule the container with my python program to run daily, generate results and stop again
This is my configuration file:
version: '3.7'
services:
database:
container_name: sql_database
image: mysql:latest
command: --init-file /docker-entrypoint-initdb.d/init.sql
ports:
- 13306:3306
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- ./backup.sql:/docker-entrypoint-initdb.d/init.sql
python-container:
container_name: python-container
build: ./python_project
command: python main.py
depends_on:
- database
volumes:
- myvol:/python_project/data
volumes:
myvol:
Can someone please help me with this? Thanks!
I was just about to ask the same thing. Seems silly to keep a container going 24/7 just to run one job a day (in my case, certbot renew).
I think there may be a way to fake this using the RESTART_POLICY option with a long delay and no maximum retries, but I haven't tried it yet.
EDIT: Apparently restart_policy only works for swarms. Pity.
If the underlying container has a bash shell, you set the command to run a loop with a delay, like this:
while true; do python main.py; sleep 1; done
This question already has an answer here:
Docker-compose depends on not waiting until depended on service isn't fully started
(1 answer)
Closed 3 years ago.
I am dealing with a docker composer project. Here is the compose file :
version: '3.3'
services:
tomcatserver:
build: ./mavenServer
depends_on:
- db
ports:
- "8010:8080"
db:
image: mariadb
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "tpformation"
MYSQL_USER: "tomcat"
MYSQL_PASSWORD: "tomcat"
expose:
- "3306"
when I start my stack with docker-composer up, it is always the maven containers that starts first. However, it should be the db one. Could you help please.
Docker Compose used to have a condition configuration under depends_on. This is no longer the case.
From this page:
depends_on does not wait for db and redis to be “ready” before starting web - only until
they have been started. If you need to wait for a service to be ready, see Controlling
startup order for more on this problem and strategies for solving it.
Version 3 no longer supports the condition form of depends_on.
The simplest way to handle this issue, is to simply avoid it. Do docker-compose up -d db and then you can start and restart anything that depends on it (docker-compose up tomcatserver).
In most cases, dependencies normally "become healthy" before any other container needs them, so you can just docker-compose up your-app and never notice the issue.
Of course, all the above statements are valid assuming you are not using the same docker-compose in production.
If however, you are still interested in hardening the startup sequence, you can take a look at the Control startup and shutdown order docker manual page, for some possibilities.
Relevant snippet from this page:
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
db:
image: postgres
Personally, I recommend against such tricks wherever possible.
I have several containers which are described in a docker-compose-<service>.yaml file each, and which I start with
docker-compose -f docker-compose-<service>.yaml up -d
I then see via docker ps the container running.
I expected that I could stop that container via
docker-compose -f docker-compose-<service>.yaml down
The container is however not stopped. Neither it is when I use the comane above with stop instead of down.
Doing a docker kill <service> stops the container.
My question: since all my services started with docker-compose are effectively one container for each docker-compose-<service>.yaml file, can I use the bare docker command to stop it?
Or more generally speaking: is docker-compose simply a helper for underlying docker commands which means that using docker is always safe (from a "consistency in using different commands" perspective)?
My question: since all my services started with docker-compose are effectively one container for each docker-compose-.yaml file, can I use the bare docker command to stop it?
Actually docker-compose is using docker engine, you can try locally:
ex: docker-compose.yaml:
version: "3"
services:
# Database
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
networks:
- wpsite
# phpmyadmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- '9090:80'
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: wordpress
networks:
- wpsite
networks:
wpsite:
You can now interact with them thought docker engine if needed:
More globally docker-compose is a kind of orchestrater ( I prefer the terme of composer), if you need a to define container stack, dependent each others (like the previous example phpmyadmin/mysql) it is perfect to test in dev environment. In my point of view to have a better resilience, HA, service management... of containers stack in production environment, you strongly need to consider the implementation of a real orchestrater such as docker-swarm, kubernetes, openshift....
Here some documentation to explain the difference: https://linuxhint.com/docker_compose_vs_docker_swarm/
You can also see: What is the difference between `docker-compose build` and `docker build`?
I want to restart a container if it crashes automatically. I am not sure how to go about doing this. I have a script docker-compose-deps.yml that has elasticsearch, redis, nats, and mongo. I run this in the terminal to set this up: docker-compose -f docker-compose-deps.yml up -d. After this I set up my containers by running: docker-compose up -d. Is there a way to make these containers restart if they crash? I noticed that docker has a built in restart, but I don't know how to implement this.
After some feedback I added restart: always to my docker-compose file and my docker-compose-deps.yml file. Does this look correct? Or is this how you would implement the restart always?
docker-compose sample
myproject-server:
build: "../myproject-server"
dockerfile: Dockerfile-dev
restart: always
ports:
- 5880:5880
- 6971:6971
volumes:
- "../myproject-server/src:/src"
working_dir: "/src"
external_links:
- nats
- mongo
- elasticsearch
- redis
myproject-associate:
build: "../myproject-associate"
dockerfile: Dockerfile-dev
restart: always
ports:
- 5870:5870
volumes:
- "../myproject-associate/src:/src"
working_dir: "/src"
external_links:
- nats
- mongo
- elasticsearch
- redis
docker-compose-deps.yml sample
nats:
image: nats
container_name: nats
restart: always
ports:
- 4222:4222
mongo:
image: mongo
container_name: mongo
restart: always
volumes:
- "./data:/data"
ports:
- 27017:27017
If you're using compose, it has a restart flag which is analogous to the one existing in the docker run command, so you can use that. Here is a link to the documentation about this part -
https://docs.docker.com/compose/compose-file/
When you deploy out, it depends where you deploy to. Most container clusters like kubernetes, mesos or ECS would have some configuration you can use to auto-restart your containers. If you don't use any of these tools you are probably starting your containers manually and can then just use the restart flag just as you would locally.
Looks good to me. What you want to understand when working on Docker policies is what each one means. always policy means that if it crashes for any reason automatically restart.
So if it stops for any reason, go ahead and restart it.
So why would you ever want to use always as opposed to say on-failure?
In some cases, you might have a container that you always want to ensure is running such as a web server. If you are running a public web application chances are you want that server to be available 100% of the time.
So for web application I expect you want to use always. On the other hand if you are running a worker process on a file and then naturally exit, that would be a good use case for the on-failure policy, because the worker container might be finished processing the file and you probably want to let it close out and not have it restart.
Thats where I would expect to use the on-failure policy. So not just knowing the syntax, but when to apply which policy and what each one means.