as per this docker-compose file
version: "3.8"
services:
b:
image: b
restart: "on-failure"
ports:
- "6002:6002"
a:
image: a
restart: "on-failure"
depends_on:
- b
c:
image: c
restart: "on-failure"
in case container a restarts container b should be restarted.
Any guidance please help.
I tried placing the shell script in dockerfile container.
Since I can't come docker-compose directory this attempt failed.
Related
I have an app with separated frontend and backend, each one is a subfolder. I have dockerized the front and the back separately in their folders, respectively.
Now, I'm trying to run them in the same network by using docker-compose in the root folder. The build is done successfully, but when I run it, the front container works just fine, but the back container exits with code 0.
Maybe it's worth mentioning that the container of the back is a done with a docker-compose too.
Can you help me please?
Here's how the docker-compose.yml looks like in the root folder
version: '3.7'
services:
back:
build: ./backend/
ports:
- "8000:8000"
front:
build: ./frontend/
ports:
- "80:3000"
output:
app_back_1 exited with code 0
front_1 | INFO: Accepting connections at http://localhost:3000.
Here's the docker-compose file of the backend:
version: '3.5'
services:
app:
build:
context: .
command: gunicorn backend.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_data:/vol/static
ports:
- "8000:8000"
restart: always
env_file:
- .env
depends_on:
- app-db
app-db:
image: postgres:12-alpine
ports:
- "5432:5432"
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data:rw
env_file:
- .env
proxy:
build: ./proxy
volumes:
- static_data:/vol/static
- media_data:/vol/media
restart: always
ports:
- "8008:80"
depends_on:
- app
volumes:
static_data:
media_data:
postgres_data:
If the container runs well, It should run well with identical docker image that you have built. Try docker-compose up --build --force-recreate --no-deps to recreate everything from scratch with no cache, so then if you have error in your source code the error will throw for both standalone container and compose.
Hello I have multiple projects that have there own dockerfiles and docker-compose.yml files. I am not too familiar on how I would setup the networking between these projects. So they could share the same databases and the project would be able to talk to on another. Does anyone have suggests?
Right now, In one of the projects I am just pulling in all the dockerfile into a docker-compose.yml and setting-up all the services I need from all the other projects in this yml file. I do not think this is ideal and there is a high level a coupling between the services.
version: "3"
services:
db:
image: mysql/mysql-server
ports:
- 3306:3306
mongo:
image: mongo
restart: always
rails_app:
build:
context: ${RAILS_APP_PATH}
dockerfile: Dockerfile
volumes:
- ${RAILS_APP_PATH}:/application
ports:
- 4000:4000
depends_on:
- db
- mongo
links:
- db
- mongo
frontend:
build:
context: ${FRONTEND_PATH}
ports:
- ${EXPOSED_PORT}:${EXPOSED_PORT}
depends_on:
- go_services
links:
- go_services
go_services:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
depends_on:
- db
- mongo
- rails_app
links:
- db
- mongo
- rails_app
The trick is to use an External Docker Network.
Set up the network and the Containers can talk to each other by their Service Names.
Setup the the network on the Host
docker network create my-net
First compose file
version: '3.9'
services:
mymongo:
image: mongo:latest
restart: unless-stopped
container_name: mongo
environment:
MONGO_INITDB_DATABASE: mymongo
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- ./database:/data/db
ports:
- "27017:27017"
networks:
default:
external: true
name: my-net
Second compose file
version: '3.9'
services:
ui:
build:
context: ./build
dockerfile: Dockerfile_ui
image: ui
restart: "no"
container_name: ui
ports:
- "8005:3000"
command: ["npm", "start"]
networks:
default:
external: true
name: my-net
You can do this without any special Compose setup, if:
each project is self-contained (they do not share databases)
the service locations are configurable via environment variables
you don't mind communicating via the host
If you're thinking about scaling up this project at all, this approach can look attractive. It will work even if you're running each Compose file on a different host, and it translates well into clustered environments like Kubernetes.
Go ahead and break up your Compose file into several independent ones:
# rails/docker-compose.yml
version: '3.8'
services:
db:
image: mysql/mysql-server
app:
build: .
ports: ['4000:4000']
depends_on: [db]
# go/docker-compose.yml
services:
mongo:
image: mongo
service:
build: .
ports: ['8080:8080']
depends_on: [mongo]
environment:
- RAILS_APP_URL
The very last line here passes the RAILS_APP_URL environment variable from the host environment into the container.
You can start the Rails application independently:
docker-compose -f ./rails/docker-compose.yml up -d
You need to find some hostname where the container can call back to the host. On MacOS and Windows hosts, Docker provides a special hostname host.docker.internal for this. You can then connect the client container to the published port of its server:
export RAILS_APP_URL=http://host.docker.internal:4000
docker-compose -f ./go/docker-compose.yml up
If you're doing development, you can run the service you're working on locally, and its dependencies in containers, and point the environment variable at the container
go build -o ./server ./cmd/server
export RAILS_APP_URL=http://localhost:4000
./server
If you want to run this setup on multiple hosts but without using a dedicated cluster manager like Docker Swarm or Kubernetes, set the environment variable to point at the DNS name of the host running the service. If you did want to translate this to Kubernetes, a Helm "chart" would be analogous, containing the Deployment, Service, etc. and dependencies for a single component, and you could configure the other service's URL through Helm values.
I have 2 docker-compose files that build a dockerfile, and i want join those docker-compose files
so, i created other docker-compose that goes up these 2 images
version: "3.4"
services:
frontend:
image: frontend-image
depends_on:
- backend
ports:
- "3000:80"
networks:
- teste-network
backend:
image: backend-image
ports:
- "5001:80"
networks:
- test-network
networks:
test-network:
driver: bridge
but, this docker-compose file not build the images
then i created a bash command that build these images
bash -c "docker-compose -f ./frontend/docker/docker-compose.yml build
&& docker-compose -f ./backend/docker/docker-compose.yml build"
I want to run this script before up containers, just typing docker-compose up
i assume that you have 2 dockerfiles - one for the frontend and the other for the backend, where each of which resides in the corresponding folder from your post, that is:
frontend/docker/Dockerfile
backend/docker/Dockerfile
then you can leverage docker-compose to build and run your images. all you have to do is to tell docker-compose where are the dockerfiles, which you can do by utilizing the build configuration.
version: "3.4"
services:
frontend:
image: frontend-image
build: ./frontend/docker
depends_on:
- backend
ports:
- "3000:80"
networks:
- test-network
backend:
image: backend-image
build: ./backend/docker
ports:
- "5001:80"
networks:
- test-network
networks:
test-network:
driver: bridge
then running docker-compose up frontend will build the docker images (if they do no exist), and then start them.
Is it possible to start myapp-1 with myapp-2, then sleep for 30 seconds and only then start myapp-3?
Tried this docker-compose.yml with no luck.
version: '3'
services:
myapp-1:
container_name: myapp-1
image: myapp:latest
restart: always
myapp-2:
container_name: myapp-2
image: myapp:latest
restart: always
test-sleep:
image: busybox
command: ["/bin/sleep", "30"]
depends_on:
- "myapp-1"
- "myapp-2"
myapp-3:
container_name: myapp-3
image: myapp:latest
restart: always
depends_on:
- "test-sleep"
The docker-compose.yml you proposed could not address your use case, as the depends_on property does not wait for the dependencies to be ready (or terminated), but only for them to be started (i.e., in your example, myapp-3 is started as soon as the /bin/sleep 30 command has been started).
See e.g. the corresponding doc:
depends_on does not wait for [dependencies] to be “ready” before starting [the service] - 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.
The link above mentions several tools (including wait-for-it) that could be used to wait that some service dependencies are ready (provided they expose a web service at a given TCP port).
Otherwise, if you just want to wait for 30s before starting myapp-3, assuming the Dockerfile of myapp-3 contains CMD ["/prog", "first argument"], you could just get rid of test-sleep and write something like:
version: '3'
services:
myapp-1:
container_name: myapp-1
image: myapp:latest
restart: always
myapp-2:
container_name: myapp-2
image: myapp:latest
restart: always
myapp-3:
container_name: myapp-3
image: myapp:latest
restart: always
command:
- '/bin/sh'
- '-c'
- '/bin/sleep 30 && /prog "first argument"'
depends_on:
- "myapp-1"
- "myapp-2"
Currently I have a rabbitmq message broker and multiple celery workers that need to be containerized. My problem is, how can I fire up containers using different docker-compose.yml? My goal is to start the rabbitmq once and for all, and never touch it again.
Currently I have a docker-compose.yml for the rabbitmq:
version: '2'
services:
rabbit:
hostname: rabbit
image: rabbitmq:latest
environment:
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=mypass
ports:
- "5672:5672"
expose:
- "5672"
And another docker-compose.yml for celery workers:
version: '2'
services:
worker:
build:
context: .
dockerfile: dockerfile
volumes:
- .:/app
environment:
- CELERY_BROKER_URL=amqp://admin:mypass#rabbit:5672
links:
- rabbit
However, when I do docker-compose up for celery workers, I keep getting the following error:
ERROR/MainProcess] consumer: Cannot connect to
amqp://admin:**#rabbit:5672//: failed to resolve broker hostname.
Can anyone take a look if there is anything wrong with my code? Thanks.
the domain name rabbit in your second docker-compose.yml file does not resolve because there is no service with that name in that docker-compose.yml file.
As stated in the comments, one solution is to put both the rabbit service and worker service in the same docker-compose.yml file. In such a setup, all containers started for those services would join the same docker network and those service names could be resolved to the IP adresses of their containers.
Since having a single docker-compose.yml file is not convenient in your case, you have to find an other way to have the containers originating from different docker-compose.yml files join a same docker network.
To do so, you need to create a dedicated docker network for that purpose:
docker network create rabbitNetwork
Then, in each docker-compose.yml file, you need to refer to this network in the services definitions:
version: '2'
services:
rabbit:
hostname: rabbit
image: rabbitmq:latest
environment:
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=mypass
# ports:
# - "5672:5672" # there is no need to publish ports on the docker host anymore
expose:
- "5672"
networks:
- rabbitNet
networks:
rabbitNet:
external:
name: rabbitNetwork
version: '2'
services:
worker:
build:
context: .
dockerfile: dockerfile
volumes:
- .:/app
environment:
- CELERY_BROKER_URL=amqp://admin:mypass#rabbit:5672
networks:
- rabbitNet
networks:
rabbitNet:
external:
name: rabbitNetwork
You can use any file as service definition.
docker-compose.yml is default file name but any other name can be passed using -f argument.
docker-compose -f rabbit-compose.yml COMMAND