Error connecting Mysql from Go REST API with Docker Compose - mysql

I'm very new to Docker, and I'm trying to dockerize a Go REST API and MySQL database to communicate with each other using Docker Compose. I am getting the error [main] Error 1049: Unknown database 'puapp'
Docker compose:
version: '3'
services:
db:
build: ./mysql/
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- db_volume:/var/lib/mysql
api-service:
restart: always
build: ./
ports:
- "8080:80"
environment:
- DB_USER=root
- DB_PASS=root
- DB_ADDRESS=db:3306
- DB_PROTOCOL=tcp
- DB_NAME=puapp
depends_on:
- db
links:
- db
volumes:
db_volume:
Dockerfile for go service:
# syntax=docker/dockerfile:1
# Build stage
FROM golang:1.16-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod download
WORKDIR /app/src/main
RUN go build -o restserv
# Run stage
FROM alpine:3.13
WORKDIR /app
COPY --from=builder /app/src/main/restserv .
EXPOSE 8080
CMD "./restserv"
Dockerfile for MySQL:
FROM mysql:latest
ADD dump.sql /docker-entrypoint-initdb.d
Full code - https://github.com/bens-schreiber/restservproj
Let me know if I need to add anything

Containers will be having their own ip addresses, so API container won't be able to access mysql container over 127.0.0.1. As mentioned in the comments, you want to utilize container's names to addresses from container from another. See this page for details.

Related

Execute SQL script on docker compose

I have a project that runs when ./entrypoint.sh or docker-compose up is run from the root directory of project and generates the swagger API interface, but the calls return entry response no data.
If I run with MySQL on localhost without docker, works perfectly fine. How do I load the data?
entrypoint.sh
#!/bin/bash
docker network create turingmysql
docker container run -p 3306:3306 --name mysqldb --network turingmysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=tshirtshop -d mysql:5.7
docker-compose build
docker-compose up
DockerFile
FROM mysql:5.7
ADD ./database/tshirtshop.sql /docker-entrypoint-initdb.d
#### Stage 1: Build the application
FROM openjdk:8-jdk-alpine as build
# Set the current working directory inside the image
WORKDIR /app
# Copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn
# Copy the pom.xml file
COPY pom.xml .
# Build all the dependencies in preparation to go offline.
# This is a separate step so the dependencies will be cached unless
# the pom.xml file has changed.
RUN ./mvnw dependency:go-offline -B
# Copy the project source
COPY src src
# Package the application
RUN ./mvnw package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
#### Stage 2: A minimal docker image with command to run the app
FROM openjdk:8-jre-alpine
ARG DEPENDENCY=/app/target/dependency
# Copy project dependencies from the build stage
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.turing.ecommerce.TuringApplication"]
docker-compose.yml
version: '3.7'
# Define services
services:
# App backend service
app-server:
# Configuration for building the docker image for the backend service
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
restart: always
depends_on:
- mysqldb # This service depends on mysql. Start that first.
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb:3306/tshirtshop?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
networks: # Networks to join (Services on the same network can communicate with each other using their name)
- turingmysql
# Database Service (Mysql)
mysqldb:
image: mysql:5.7
ports:
- "3306:3306"
restart: always
environment:
MYSQL_DATABASE: tshirtshop
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: root
volumes:
- db-data:/var/lib/mysql
networks:
- turingmysql
# Volumes
volumes:
db-data:
# Networks to be created to facilitate communication between containers
networks:
turingmysql:
Do you have two Dockerfiles? Looks like you built your own MySQL container?
Otherwise, these shouldn't be part of your Java multi-stage build
FROM mysql:5.7
ADD ./database/tshirtshop.sql /docker-entrypoint-initdb.d
Assuming that you did build a separate image for mysql, in the Docker-Compose, you're not using it, as you're still referring to image: mysql:5.7
Rather than building your own, you should mount the SQL script into it
For example
mysqldb:
image: mysql:5.7
...
volumes:
- db-data:/var/lib/mysql
- ./database/tshirtshop.sql:/docker-entrypoint-initdb.d/0_init.sql
Then, forget the Java service for a minute and use MySQL workbench or the mysql CLI to verify that data is actually there. Once you do, then startup the API
If you copying sql scipt already to docker build then you do not need to mapped it again in the docker-compose, if you have docker-compose then you do not the bash script single command docker-compose up --build will do the job.
So modify your docker-compose as per your Dockerfile.
Dockerfile
FROM mysql
ADD init.sql /docker-entrypoint-initdb.d
docker-compose
version: '3.7'
services:
# App backend service
app-server:
# Configuration for building the docker image for the backend service
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
restart: always
depends_on:
- mysqldb # This service depends on mysql. Start that first.
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb:3306/tshirtshop?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
networks: # Networks to join (Services on the same network can communicate with each other using container name)
- uringmysql
# Database Service (Mysql)
mysql:
build: .
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: appdata
MYSQL_USER: test
MYSQL_PASSWORD: root123
volumes:
- db-data:/var/lib/mysql
tty: true
# Volumes
volumes:
db-data:
# Networks to be created to facilitate communication between containers
networks:
turingmysql:
Now just run
docker-compose up --build
this will build and up the container and you will not need to mapped the host init script, as it already in Docker image.
The directory structure will look like
Now you application will able to access DB using jdbc:mysql://mysqldb:3306/tshirtshop? this endpoint as both are in same network and can refer eacher other using name.
Thank you cricket_007 and Adii for the responses. They put me in the right direction. I want to document my experience and how the issue was resolved. New to dockerization so I was learning by practice. For anyone new to dockerization and having same issues in Spring Boot, MySQL and docker, this would surely help
First, my entrypoint.sh changed below. The docker-compose down is for restarts.
#!/bin/bash
docker-compose down -v
docker-compose up --build
Second, I had to use an existing mysql image instead of building one.
version: '3.7'
# Define services
services:
# App backend service
app-server:
# Configuration for building the docker image for the backend service
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
restart: always
depends_on:
- mysql # This service depends on mysql. Start that first.
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/tshirtshop?useSSL=false&allowPublicKeyRetrieval=true&useLegacyDatetimeCode=false&serverTimezone=UTC
SPRING_DATASOURCE_USERNAME: turing
SPRING_DATASOURCE_PASSWORD: pass
networks: # Networks to join (Services on the same network can communicate with each other using their name)
- turingmysql
# Database Service (Mysql)
mysql:
image: mysql/mysql-server
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: tshirtshop
MYSQL_USER: turing
MYSQL_PASSWORD: pass
volumes:
- db-data:/var/lib/mysql
- ./database:/docker-entrypoint-initdb.d
tty: true
networks: # Networks to join (Services on the same network can communicate with each other using their name)
- turingmysql
# Volumes
volumes:
db-data:
# Networks to be created to facilitate communication between containers
networks:
turingmysql:
driver: bridge
Needed to specify that the network is a bridge. My sql file was mounted from a folder relative to docker-compose.yml. Also had to add allowPublicKeyRetrieval=true to my jdbc url. Created a user to access the database tshirtshop.
And here is the Dockerfile.
#### Stage 1: Build the application
FROM openjdk:8-jdk-alpine as build
# Set the current working directory inside the image
WORKDIR /app
# Copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn
# Copy the pom.xml file
COPY pom.xml .
# Build all the dependencies in preparation to go offline.
# This is a separate step so the dependencies will be cached unless
# the pom.xml file has changed.
RUN ./mvnw dependency:go-offline -B
# Copy the project source
COPY src src
# Package the application
RUN ./mvnw package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
#### Stage 2: A minimal docker image with command to run the app
FROM openjdk:8-jre-alpine
ARG DEPENDENCY=/app/target/dependency
# Copy project dependencies from the build stage
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.turing.ecommerce.TuringApplication"]
to run, from root directory of project ./entrypoint.sh on mac and the rest is history.

Docker-compose up for a spring service and a mysql service works, but init.sql does is not loaded and Postman return empty data

I am working for the first time with Docker. In my job, they asked me to deploy a complete application using docker-compose and I am learning right now.
I have a docker-compose.yml that starts two services: one for spring and another one for MySQL.
The one for Spring uses a Dockerfile to build the image.
The one for MySQL uses the official MySQL image.
I don´t know how to load the init.sql to initialize and load data into the database of the MySQL container.
I´ve tried to use another Dockerfile in order to copy init.sql into the MySQL container but,
how do I tell the compose to use it when creating the image or running the container?
This is for a Windows 10 OS Desktop. Docker version 18.09.2. Docker-compose version 1.23.2
Docker Desktop
Docker-compose.yml
version: '3.7'
services:
mysql-docker-container:
image: mysql
container_name: mysql-docker-container
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=database
- MYSQL_USER=user
- MYSQL_PASSWORD=user
ports:
- 2012:3306
tty: true
spring-jpa-app:
build:
context: .
dockerfile: Dockerfile
container_name: spring-jpa-app
links:
- mysql-docker-container:mysql-docker-container
depends_on:
- mysql-docker-container
ports:
- 8087:8080
tty: true
restart: always
Dockerfile
FROM java:8
VOLUME /tmp
EXPOSE 8080
ADD app-1.0.0.jar app-1.0.0.jar
ENTRYPOINT ["java","-jar","app-1.0.0.jar"]
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql-docker-container:2012/database?autoReconnect=true&useSSL=false
spring.datasource.username=user
spring.datasource.password=user
spring.jpa.database=database
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
logging.file=log/log.log
logging.level.org.springframework=info
logging.level.orghibernate=info
Docker Desktop running
Opened Git Bash as administrator
docker-machine ls
NAME ACTIVE DRIVER STATE URL DOCKER
app * hyperv Running tcp://172.18.67.35:2376 v19.03.0
In the app folder, where is located /src
mvn clean install -DskipTests
BUILD SUCCESS
In the app folder where is located application.properties, app.jar, docker-compose.yml, Dockerfile and init.sql
docker-compose up --build
Postman
URL = http://172.18.67.35:8087
POST {{url}}/login
{
"Authorization": "gnioengrlnkwejnR",
"username": "Administrator",
"role": "ADMIN",
"id": "1"
}
GET {{url}}/listAllCenters
[]
Returns empty because init.sql is not being loaded
PD: Also, if I open a new git Bash as Administrator and do
docker ps -a
I do not get the containers running so I cannot know container's ID to enter the MySQL container.
you need to add a volume to copy the sql.init to your db continer:
version: '3.7'
services:
mysql-docker-container:
image: mysql
container_name: mysql-docker-container
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=database
- MYSQL_USER=user
- MYSQL_PASSWORD=user
ports:
- 2012:3306
volumes:
- /bath/to/file/on/host/init.sql:/docker-entrypoint-initdb.d/init.sql
tty: true
network_mode: "host"
spring-jpa-app:
build:
context: .
dockerfile: Dockerfile
container_name: spring-jpa-app
links:
- mysql-docker-container:mysql-docker-container
depends_on:
- mysql-docker-container
ports:
- 8087:8080
tty: true
restart: always
network_mode: "host"
see this and search for "Initializing a fresh instance"
on the other hand you need to use network to setup the connection between the containers - see the compose file above-
and you need to change you configs to
spring.datasource.url=jdbc:mysql://localhost:2012/database?autoReconnect=true&useSSL=false

Docker service intercommunication troubleshoot

Attempting to dockerize a Symfony 3.1 application, I run Docker for Windows:
Docker Desktop Version: 2.0.0.3
Engine Version: 18.09.2
Compose Version: 1.23.2
Here is my current docker-compose.yaml:
version: "3.6"
services:
nginx:
build:
context: ./../..
dockerfile: ./docker/dev/nginx/Dockerfile
volumes:
- ./../..:/app
ports:
- 80:80
links:
- mariadb:mariadb
- php:php
php:
build:
context: ./../..
dockerfile: ./docker/dev/php/Dockerfile
volumes:
- ./../..:/app
links:
- mariadb:mariadb
mariadb:
build:
context: ./../..
dockerfile: ./docker/dev/mariadb/Dockerfile
volumes:
- database:/var/lib/mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=todo_list
- MYSQL_USER=todo_list
- MYSQL_PASSWORD=todo_list
volumes:
database:
Here are my Dockerfiles for each of the 3 services above:
nginx:
FROM nginx:1.16.0-alpine
COPY docker/dev/nginx/config/nginx.conf /etc/nginx/conf.d/default.conf
COPY . /app
php:
FROM php:7.3.6-fpm-alpine3.10
RUN docker-php-ext-install -j$(nproc) pdo_mysql
COPY docker/dev/php/config/php.conf ${PHP_INI_DIR}/conf.d/default.ini
COPY . /app
mariadb:
FROM mariadb:10.3
COPY docker/dev/mariadb/config/mariadb.conf /etc/mysql/conf.d/default.cnf
RUN chmod 0444 /etc/mysql/conf.d/default.cnf
Running docker-compose up, everything seems fine, no inconsistencies or error/warning detected in the services logs…
The Symfony parameters.yml in which is defined database access and credentials looks like this:
parameters:
database_host: 127.0.0.1
database_port: 3306
database_name: todo_list
database_user: todo_list
database_password: todo_list
With this configuration I am able to run successfully the Symfony console commands:
php bin/console doctrine:schema:update
php bin/console doctrine:fixtures:load
Which means that in this context, the app has access to the database.
But when I interact with the app via HTTP (http://localhost in web browser), so via the docker service nginx, I get a SQLSTATE[HY000] [2002] Connection refused.
So I change the parameters:database_host entry in the parameters.yml from 127.0.0.1 to 172.31.0.1 (which is the current IP address of the mariadb container) and this time I can interact with the app via HTTP, without any problem for it to access to the database, but instead, I get a SQLSTATE[HY000] [2002] when attempting to access to the database via the Symfony console.
I suspected a Docker Compose misconfiguration but after checking and rechecking the Docker doc, tutorials, example GitHub repos, and similar SE questions, for hours, I don't get what I'd be doing wrong…
As #DavidMaze said in the comment, remove the links from the docker-compose file and use the name of the service instead of the address (mariadb instead of 127.0.0.1). This way it will work for connections coming from inside docker.
This way, as you have already seen, it stops working for connections coming from outside docker (neve used Symfony console but I assume it's outside of docker). To work around it you have at least two ways:
quick and dirty, add a line in your hosts file (on windows, the file should be at C:\Windows\System32\Drivers\etc) like
this: 127.0.0.1 mariadb, this will instruct windows to resolve
mariadb as 127.0.0.1
configure your project to use different config files depending on if you are connecting from inside or outside docker (can't tell you
exactly how, it really depends on your project structure)
IMHO option 1 is acceptable for development machines.
You can't use 127.0.0.1 in your parameter.yml but you can use 'mariadb' instead since you defined it in your links section.
Now links is described as deprecated so it will work but you'll probably want to go with networking.
version: "3.6"
services:
nginx:
build:
context: ./../..
dockerfile: ./docker/dev/nginx/Dockerfile
networks:
- frontend
- backend
volumes:
- ./../..:/app
ports:
- 80:80
php:
build:
context: ./../..
dockerfile: ./docker/dev/php/Dockerfile
networks:
- frontend
- backend
volumes:
- ./../..:/app
mariadb:
build:
context: ./../..
dockerfile: ./docker/dev/mariadb/Dockerfile
networks:
- backend
volumes:
- database:/var/lib/mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=todo_list
- MYSQL_USER=todo_list
- MYSQL_PASSWORD=todo_list
volumes:
database:
networks:
frontend:
driver: bridge
name: frontend #or whatever custom name since 3.5
backend:
driver: bridge
name: backend #or whatever custom name since 3.5

Docker compose MySql initialisation scripts not executing

I am having a problem having the mysql container to run my initialisation scripts.
I have two files create.sql and insert.sql, which I use to initialise the database.
I create the images using the command docker-compose.yml and it runs successfully and creates the images.
I am facing two problems.
When I run the docker-compose up command, the mysql container is created and started successfully. However the two initialisation scripts (create.sql and insert.sql) don't run on the database.
I explicitly use the docker run command to run the created mysql container. In this scenario the initialisation scripts run successfully.
I am using Docker version 18.09.0 and docker-compose version 1.23.1 and ubuntu 16.04 LTS
I am new to docker and can't seem to figure out the problem.
The following are the files I am using to create images.
docker-compose.yml file.
version: '3'
services:
demo-mysql:
image: demo-mysql
build: ./demo-mysql
volumes:
- /mnt/data/mysql-data:/var/lib/mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=demo
- MYSQL_PASSWORD=root
demo-api:
image: demo-api-1.0
build: ./api
depends_on:
- demo-mysql
ports:
- 8080:8080
environment:
- DATABASE_HOST=demo-mysql
- DATABASE_USER=root
- DATABASE_PASSWORD=root
- DATABASE_NAME=demo
- DATABASE_PORT=3306
demo1-app:
image: demo1-app-1.0
build: ./demo1
depends_on:
- demo-mysql
ports:
- 8090:8090
environment:
- DATABASE_HOST=demo-mysql
- DATABASE_USER=root
- DATABASE_PASSWORD=root
- DATABASE_NAME=demo
- DATABASE_PORT=3306
The following is the Dockerfile for the spring boot project
FROM java:8
VOLUME /tmp
ARG DATA_PATH=/src/main/resources
ARG APP_PORT=8080
EXPOSE ${APP_PORT}
ADD /build/libs/demo-api.jar demo-api.jar
ENTRYPOINT ["java","-jar","demo-api.jar"]
The following is the Dockerfile I used to create my mysql image
FROM mysql:5.7
ENV MYSQL_DATABASE=demo \
MYSQL_USER=root \
MYSQL_ROOT_PASSWORD=root
ADD ./1.0/create.sql /docker-entrypoint-initdb.d
ADD ./1.0/insert.sql /docker-entrypoint-initdb.d
EXPOSE 3306
From documentation (https://hub.docker.com/_/mysql/)
Initializing a fresh instance
When a container is started for the first time, a new database with
the specified name will be created and initialized with the provided
configuration variables. Furthermore, it will execute files with
extensions .sh, .sql and .sql.gz that are found in
/docker-entrypoint-initdb.d.
I suspect that, because of the persisted volume
volumes:
- /mnt/data/mysql-data:/var/lib/mysql
when docker starts the mysql image, there is already a DB. So the image isn't "fresh" and the scripts are not run.
Update:
we can confirm this suspect looking at the source code of the docker-entrypoint.sh here: https://github.com/docker-library/mysql/blob/696fc899126ae00771b5d87bdadae836e704ae7d/5.7/docker-entrypoint.sh
if [ ! -d "$DATADIR/mysql" ]; then
...
...
ls /docker-entrypoint-initdb.d/ > /dev/null
for f in /docker-entrypoint-initdb.d/*; do
process_init_file "$f" "${mysql[#]}"
done
The scripts run only if the "$DATADIR/mysql" is not present already.
btw, I personally consider a better design to have the "application" create the database schema, preload the required application data, manage schema migrations etc... at startup, but this another topic :)

Error: database is uninitialized and password option is not specified

I'm new to docker. I've been following this tutorial: https://medium.com/coderscorner/connecting-to-mysql-through-docker-997aa2c090cc . I've set up the root password but once I tried to access the mysql command, it throws out this database is uninitialized error. Also, when I do docker-compose up command to pull the needed modules, it gives out an django.db.utils.InternalError: (1049, "Unknown database 'bitpal'"). The command I placed was:
docker run --name=mysql -e MYSQL_USER=root MYSQL_ROOT_PASSWORD=password -d mysql
I reckon I've searched for answers here but I couldn't be sure of what's wrong.
docker-compose.yml
version: '2'
services:
# Redis
mysql:
image: mysql:5.7
restart: always
hostname: mysql
container_name: mysql
environment:
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DB=bitpal
ports:
- "3306:3306"
# Redis
redis:
image: redis:latest
restart: always
hostname: redis
container_name: redis
ports:
- "6379:6379"
# Django web server
bitpal:
image: python:3.5
restart: always
hostname: bitpal
container_name: bitpal
working_dir: /bitpal
command: ./bin/start_dev.sh
volumes:
- ./bitpal:/bitpal
- ./etc/config:/etc/config
- ./log:/log
ports:
- "80:80"
links:
- mysql
- redis
depends_on:
- mysql
environment:
# Database
- DB_NAME=bitpal
- DB_USER=root
- DB_PASSWORD=password
- DB_HOST=mysql
- DB_PORT=3306
# Celery worker
worker:
image: python:3.5
restart: always
container_name: worker
command: bash -c "./bin/install.sh && ./bin/celery_worker.sh"
working_dir: /bitpal
volumes:
- ./bitpal:/bitpal
- ./etc/config:/etc/config
- ./log:/log
links:
- mysql
- redis
depends_on:
- redis
# Bitshares websocket listener
websocket_listener:
image: python:3.5
restart: always
container_name: websocket_listener
command: bash -c "./bin/install.sh && ./bin/websocket_listener.sh"
working_dir: /bitpal
volumes:
- ./bitpal:/bitpal
- ./etc/config:/etc/config
- ./log:/log
links:
- mysql
- redis
depends_on:
- redis
# Nginx
nginx:
image: nginx:1.12.1
container_name: nginx
ports:
- "8000:80"
volumes:
- ./bitpal:/home/bitpal/bitpal/bitpal
- ./nginx:/etc/nginx/conf.d
depends_on:
- bitpal
My directory looks like this.
`**ROOT**
`root: .gitignore, docker-compose.yml, docker-compose-production.yml...
/bitpal /etc /log /nginx /public_html`
**ROOT/bitpal**
`.gitignore, Dockerfile, Makefile, manage.py... /bin /bitpal /media
/static /tests`
All the project's .sh files are stored under root/bitpal/bin. Do I place wait-for-it.sh there instead or place it in bitpal and nginx folders?
This tutorial you were following is incomplete. It didn't tell you that you must wait until the db is initialized if you want to use it.
Just after running the database container via run command, you should check the logs of this container and wait until the DB initialization
process is complete
You can do it with:
$ docker logs -f <container name>
Where container name in your case is mysql. When you see that db is initialized and DB is started, just detach (ctrl+c) from the logs and continue on.
Your DB is ready to use now.
important note considering your compose file
This compose file is not going to work because the other services like bitpal/worker are not waiting for the DB service to initialize.
Initially download a wait-for-it.sh script, that'd allow other servies to wait for your database when using compose file to setup your application. The script, made by vishnubob, is available here, then copy it to all the catalogs where your services requiring database are.
In the same catalogs create a docker-entrypoint.sh files and write them like this:
#!/bin/bash
set -e
sh -c './wait-for-it.sh mysql:3306 -t 30'
exec "$#"
Then, in your compose file add entries in every service that require DB (and where you places wait-for-it.sh script) that will execute the waiting script:
entrypoint: ["./docker-entrypoint.sh"]
Then, your services will wait for the DB until it's initialized and ready to accept connections.
In the edits I'll add straight forward catalog tree so that you can more clearly see how these files should be placed.
This is one of the only efficient methods because depends_on is not waiting for the db service to be initialized as it's clearly stated in the official docs.
edit with files location explanation
root
- bitpal
+ *some service files*
+ wait-for-it.sh
+ docker-entrypoint.sh
- some_service_requiring_db
+ *some service files*
+ wait-for-it.sh
+ docker-entrypoint.sh
- docker-compose.yml
And your compose file should be like:
version: '2'
services:
# MySQL service definition
mysql:
# like you have
# some services
# Django web server
bitpal:
# ...
entrypoint: ["./docker-entrypoint.sh"]
# further declarations