stelios
stelios

Reputation: 2845

docker-compose: Can't connect application container with mysql container

I am having trouble to make the container that contains a python/bottle web app to reach the mysql server/container.

docker-compose build:

Step 8/9 : RUN python3 bin/initdb.py
 ---> Running in 30d963677711
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 583, in connect
    **kwargs)
  File "/usr/lib/python3.7/socket.py", line 707, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
  File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bin/initdb.py", line 18, in <module>
    password=config('MYSQL_PASSWORD', default='tspass')
  File "/usr/local/lib/python3.7/dist-packages/pymysql/__init__.py", line 94, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 325, in __init__
    self.connect()
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 630, in connect
    raise exc
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'db' ([Errno -2] Name or service not known)")
ERROR: Service 'web' failed to build: The command '/bin/sh -c python3 bin/initdb.py' returned a non-zero code: 1

docker-compose.yml:

version: '3'

services:
  db:
    container_name: mysql
    image: mysql
    env_file: .env
    restart: always
    volumes:
      - ./init.sql:/app/init.sql
    networks:
      - "dock"
    expose:
      - "3306"
    # on host it's mapped on 33060

  web:
    container_name: app
    build: .
    env_file: .env
    restart: always
    depends_on:
      - db
    links:
      - db:db
    networks:
      - "dock"
    ports:
      - "8888:8888"

networks:
  dock:

Dockerfile:

FROM debian:stable

EXPOSE 8888
# CMD ["./bin/run.sh"]

RUN apt-get update && \
    apt-get install -y --no-install-recommends build-essential python3 python3-dev python3-pip python3-setuptools
RUN pip3 install --upgrade pip && \
    rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apt/archives/*.deb

WORKDIR /app

COPY . /app/
RUN pip install --no-cache-dir -r /app/requirements.txt

RUN python3 bin/initdb.py
RUN python3 main.py 0.0.0.0 8888

initdb.py:

#!/usr/bin/env python

import pymysql
from decouple import Config, RepositoryEnv

...

conn = pymysql.connect(
    host=config('DB_HOST', default='db'),  # NOT ACCESSIBLE?
    port=config('DB_PORT', default=3306, cast=int),
    db=config('MYSQL_DATABASE', default='db1'),
    user=config('MYSQL_USER', default='user'),
    password=config('MYSQL_PASSWORD', default='password')
)

.env:

# DEPLOYMENT
DB_HOST=db
DB_PORT=3306

# DOCKER MYSQL
MYSQL_HOST="0.0.0.0"
MYSQL_ROOT_HOST="%"
MYSQL_ROOT_USER=root
MYSQL_ROOT_PASSWORD=toor
MYSQL_DATABASE=db1
MYSQL_USER=user
MYSQL_PASSWORD=password

Any thoughts how to debug this?

PS: The above setup works perfectly without docker, by changing DB_HOST=db to DB_HOST=localhost and running python main.py

Upvotes: 1

Views: 298

Answers (2)

stelios
stelios

Reputation: 2845

Modified files, based on both answers above, solving this particular issue are:

Dockerfile:

FROM debian:stable

EXPOSE 8888

RUN apt-get update && \
    apt-get install -y --no-install-recommends build-essential python3 python3-dev python3-pip python3-setuptools

RUN pip3 install --upgrade pip && \
    rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apt/archives/*.deb

WORKDIR /app

COPY . /app/
RUN pip install --no-cache-dir -r /app/requirements.txt
RUN chmod +x ./bin/*

CMD ["./bin/run.sh"]

bin/wait-for-it.sh: as is

bin/run.sh:

#!/usr/bin/env bash

./bin/wait-for-it.sh -h db -p 3306 -- python3 ./bin/initdb.py
./bin/wait-for-it.sh -h db -p 3306 -- python3 ./main.py 0.0.0.0 8888

Upvotes: 0

F.Igor
F.Igor

Reputation: 4390

Basically, any other container/service is not present in the build stage, so you can't access any other container (like 'db'). You may run any startup script during the container startup using the dockerfile CMD or ENTRYPOINT, for example:

myEntryPoint.sh (created in the root folder

python3 bin/initdb.py
python3 main.py 0.0.0.0 8888

Dockerfile

COPY myEntryPoint.sh /
RUN chmod +x /myEntryPoint.sh
ENTRYPOINT ["/myEntryPoint.sh"]

Upvotes: 1

Related Questions