docker-compose up not starting all declared services - docker

I am trying to docker-compose up -d the docker-compose.yml below.
The first container is a mariadb with an sql script to init the database schema.
The second container is a nestjs application.
When I run docker-compose up -d the first container is completely ignored, and it starts trying to boot the second container up, which eventually leads to the startup of the nestjs app failing due to the missing database connection.
I'm failing to understand why docker-compose goes straight to initializing the server container, since if I manually start server-db container it does start up.
The actual logs from the docker-compose up -d
Deploying 'Compose: integration'...
"C:\Program Files\Docker\Docker\resources\bin\docker-compose.exe" -f D:\dev\projects\integration\docker-compose.yml up -d --build
Building server
I am on Docker Engine v20.10.5 for windows.
version: '3.3'
services:
server-db:
image: mariadb:10.3
restart: always
environment:
MYSQL_DATABASE: 'serverdb'
MYSQL_USER: 'serverdb'
MYSQL_PASSWORD: 'serverdb'
MYSQL_ROOT_PASSWORD: 'root'
command: --init-file /data/application/init.sql
ports:
- '3306:3306'
volumes:
- ./serverdb/database/init.sql:/data/application/init.sql
server:
build: ./server
ports:
- '8080:3000'
depends_on:
- server-db

Related

Docker-compose: Why restart does not work with docker-compose run or when there's only one container in docker-compose file

I want to execute a command using of a docker-compose file, and the code sometimes fails because of connection timeouts. I thought that adding restart: on-failure would automatically restart the container if it failed.
The command looks like that
docker-compose run --rm \
-e VAR1=value1 \
[...] \
web flask tasks my_failing_task
My docker-compose.yml looks like that
version: "3"
services:
web:
user: root
image: my-image
network_mode: "host"
environment:
APPLICATION: "web"
GOOGLE_APPLICATION_CREDENTIALS: "mysecret.json"
volumes:
- ../../../stuff/:/stuff/
restart: on-failure:3
I have noticed that the container does not restart when I use docker-compose run.
I have then tried to move the command inside the docker-compose.yml, like this:
version: "3"
services:
web:
user: root
image: my-image
network_mode: "host"
command: flask tasks my_failing_task
environment:
APPLICATION: "web"
GOOGLE_APPLICATION_CREDENTIALS: "mysecret.json"
VAR1: value1
volumes:
- ../../../stuff/:/stuff/
restart: on-failure:3
And execute docker-compose up, but same result.
It seems that restart only works with docker-compose up when I add another container, like a redis for example
version: "3"
services:
web:
user: root
image: my-image
network_mode: "host"
command: flask tasks my_failing_task
environment:
APPLICATION: "web"
GOOGLE_APPLICATION_CREDENTIALS: "mysecret.json"
VAR1: value1
volumes:
- ../../../stuff/:/stuff/
restart: on-failure:3
redis:
hostname: redis
image: redis
ports:
- "6379:6379"
Then it actually restarts up to 3 times if fails.
So my questions are:
Why doesn't restart work with run
Why does restart only work with up IF there are more than 1 container in the docker-compose.yml file
Thanks!
In the code, docker-compose run always implies restart: no. The GitHub issue docker/compose#6302 describes this a little bit further.
docker-compose run is used to run a "one-off" container, running a single alternate command with mostly the same specification as what's described in docker-compose.yml. Imagine Compose didn't have this override. If you did docker-compose run a command that failed, it would restart, potentially forever. If it ran in the background, you'd leak a restarting container; if it ran in the foreground, you'd have to go to another terminal to kill off the container. That's a harsh penalty for typing docker-compose run web bsah by accident.
Otherwise, most of the options, including restart:, get passed through directly to the Docker API. It shouldn't make a difference running docker-compose up if there's only one container or multiple.

What are the consequences of using "docker" and "docker-compose" commands interchangeably?

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`?

Docker: Can't connect to mysql under container with docker-compose parameters

I'm trying to run mysql under container with mysql parameters i defined on docker-compose.yml file. But i have an access denied when i run :
mysql -utest -ptest
I'm only able to connect with mysql -uroot -proot.
Help me please.
Thanks.
mysql:
container_name: mysql
image: mysql
restart: always
volumes:
- .docker/data/db:/var/lib/mysql
environment:
MYSQL_DATABASE: app
MYSQL_ROOT_PASSWORD: test
MYSQL_USER: test
MYSQL_PASSWORD: test
Try to launch with specified database name like this:
mysql -u test -p test app
Explanation:
MYSQL_USER, MYSQL_PASSWORD
These variables are optional, used in conjunction to create a new user and to set that user's password. This user will be granted superuser permissions (see above) for the database specified by the MYSQL_DATABASE variable. Both variables are required for a user to be created.
From MySQL docker hub page
Permissions are granted only for the database specified by environment variable. When you try to log into default database you have no permissions to it only for app database.
My complete docker-compose file.
version: '3.2'
services:
apache:
container_name: apache
build: .docker/apache/
restart: always
volumes:
- .:/var/www/html/app/
ports:
- 80:80
depends_on:
- php
- mysql
links:
- mysql:mysql
php:
container_name: php
build: .docker/php/
restart: always
volumes:
- .:/var/www/html/app/
working_dir: /var/www/html/app/
mysql:
container_name: mysql
image: mysql
restart: always
volumes:
- .docker/data/db:/var/lib/mysql
environment:
MYSQL_DATABASE: app
MYSQL_ROOT_PASSWORD: test
MYSQL_USER: test
MYSQL_PASSWORD: test
Maybe you could try attaching an interactive bash process to the already running container by following these steps:
Get your container id or name from running docker container ls in your terminal (I'm talking about the mysql container, which should have the mysql name according to your docker-compose.yml file)
Run docker exec -it mysql bash to associate an interactive bash process to the running container
Now, being inside of your container's filesystem, run mysql --user=test --password=test and you should be able to get on with your work

Unable to connect mysql from docker container?

I have created a docker-compose file it has two services with Go and Mysql. It creates container for go and mysql. Now i am running code which try to connect to mysql database which is running as a docker container. but i get error.
docker-compose.yml
version: "2"
services:
app:
container_name: golang
restart: always
build: .
ports:
- "49160:8800"
links:
- "mysql"
depends_on:
- "mysql"
mysql:
image: mysql
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=testDB
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3307:3306"
volumes:
dbdata:
Error while connecting to mysql database
golang | 2019/02/28 11:33:05 dial tcp 127.0.0.1:3306: connect: connection refused
golang | 2019/02/28 11:33:05 http: panic serving 172.24.0.1:49066: dial tcp 127.0.0.1:3306: connect: connection refused
golang | goroutine 19 [running]:
Connection with MySql Database
func DB() *gorm.DB {
db, err := gorm.Open("mysql", "root:root#tcp(mysql:3306)/testDB?charset=utf8&parseTime=True&loc=Local")
if err != nil {
log.Panic(err)
}
log.Println("Connection Established")
return db
}
EDIT:Updated docker file
FROM golang:latest
RUN go get -u github.com/gorilla/mux
RUN go get -u github.com/jinzhu/gorm
RUN go get -u github.com/go-sql-driver/mysql
COPY ./wait-for-it.sh .
RUN chmod +x /wait-for-it.sh
WORKDIR /go/src/app
ADD . src
EXPOSE 8800
CMD ["go", "run", "src/main.go"]
I am using gorm package which lets me connet to the database
depends_on is not a verification that MySQL is actually ready to receive connections. It will start the second container once the database container is running regardless it was ready for connections or not which could lead to such an issue with your application as it expects the database to be ready which might not be true.
Quoted from the documentation:
depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started.
There are many tools/scripts that can be used to solve this issue like wait-for which sh compatible in case your image based on Alpine for example (You can use wait-for-it if you have bash in your image)
All you have to do is to add the script to your image through Dockerfile then use this command in docker-compose.yml for the service that you want to make it wait for the database.
What comes after -- is the command that you would normally use to start your application
version: "2"
services:
app:
container_name: golang
...
command: ["./wait-for", "mysql:3306", "--", "go", "run", "myapplication"]
links:
- "mysql"
depends_on:
- "mysql"
mysql:
image: mysql
...
I have removed some parts from the docker-compose for easier readability.
Modify this part go run myapplication with the CMD of your golang image.
See Controlling startup order for more on this problem and strategies for solving it.
Another issue that will rise after you solve the connection issue will be as the following:
Setting MYSQL_USER with root value will cause a failure in MySQL with this error message:
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'#'%'
This is because this user already exist in the database and it tries to create another. if you need to use the root user itself you can use only this variable MYSQL_ROOT_PASSWORD or change the value of MYSQL_USER so you can securely use it in your application instead of the root user.
Update: In case you are getting not found and the path was correct, you might need to write the command as below:
command: sh -c "./wait-for mysql:3306 -- go run myapplication"
First, if you are using latest version of docker compose you don't need the link argument in you app service. I quote the docker compose documentation Warning: The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, https://docs.docker.com/compose/compose-file/#links
I think the solution is to use the networks argument. This create a docker network and add each service to it.
Try this
version: "2"
services:
app:
container_name: golang
restart: always
build: .
ports:
- "49160:8800"
networks:
- my_network
depends_on:
- "mysql"
mysql:
image: mysql
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
networks:
- my_network
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=testDB
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3307:3306"
volumes:
dbdata:
networks:
my_network:
driver: bridge
By the way, if you only connect to Mysql from your app service you don't need to expose the mysql port. If the containers runs in the same network they can reach all ports inside this network.
If my example doesn't works try this
run the docker compose and next go into the app container using
docker container exec -it CONTAINER_NAME bash
Install ping in order to test connection and then run ping mysql.

how to map database from couchdb container to another containers webapp in same docker-compose file

I am having one web application which is running with couchdb database.
This coudb container has multiple databases from which web application need only one database.
I am using docker compose to run it but web application didn't recognize database inside couchdb container
by docker-compose.yml file as below
version: "2"
services:
db:
image: mysite/couch:latest
ports:
- "15984:5984"
environment:
DB_USER: admin
DB_PASSWORD: password
DB_NAME: db_new
webapp:
image: mysite/webapp:latest
ports:
- "3050:3000"
links:
- db
- db:db_new
If I run docker manually as mentioned below it works fine
docker run --rm -e DB_URL=http://localip:15984/db_new -p 0.0.0.0:3050:3000
Any Ideas what I am missing in docker-compose file?
After spending lots of time on docker-compose I got the solution as below
version: "2"
services:
db:
image: mysite/couch:latest
ports:
- "15984:5984"
webapp:
image: mysite/webapp:latest
ports:
- "3050:3000"
links:
- db
environment:
DB_URL: http://admin:password#db:5984/db_new

Resources