Docker: MySQL[2002] when trying to setup 2 DB containers - mysql

Hi I'm trying to learn Docker.
As a starting point, I've followed DigitalOcean's setup tutorial for Laravel here.
I've managed to get all containers up and even finished building my Laravel app. Now I want to setup a 2nd DB for testing.
I duplicated the settings of the db part of docker-compose, and changed the container name and ports.
All containers setup fine, but whenever I try do run docker exec in either of the db containers, I get a 2002 error, which I did not encounter while I had only 1 DB container running:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Dockerfile:
FROM php:7.2-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
mysql-client \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
docker-compose.yml:
version: '3'
services:
#PHP Service
app:
build:
context: .
dockerfile: Dockerfile
image: digitalocean.com/php
container_name: todo_app
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
#Nginx Service
web:
image: nginx:alpine
container_name: todo_web
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#MySQL Service
db:
image: mysql:5.7.22
container_name: todo_db
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: todo
MYSQL_ROOT_PASSWORD: ent3r1n
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- dbdata:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- app-network
db_test:
image: mysql:5.7.22
container_name: todo_db_test
restart: unless-stopped
tty: true
ports:
- "3307:3306"
environment:
MYSQL_DATABASE: todo
MYSQL_ROOT_PASSWORD: ent3r1n
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- dbdata:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
Output of docker ps:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f5ccebc57f9d digitalocean.com/php "docker-php-entrypoi…" 15 seconds ago Up 13 seconds 9000/tcp todo_app
7cc53434d7d7 nginx:alpine "nginx -g 'daemon of…" 15 seconds ago Up 13 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp todo_web
7aab5318e7af mysql:5.7.22 "docker-entrypoint.s…" 15 seconds ago Up 13 seconds 0.0.0.0:3307->3306/tcp todo_db_test
5b72306f63a4 mysql:5.7.22 "docker-entrypoint.s…" 15 seconds ago Up 13 seconds 0.0.0.0:3306->3306/tcp todo_db

I have ever got the problem like this, because of image you use: image: mysql:5.7.22
You should use: image: mysql/mysql-server:5.7.
Hope it can help you.

Related

Can't figure out what ports to use in docker compose [ECONNREFUSED, port alredy used...]

version: '3.3'
services:
mysqldb:
image: mysql:8
restart: on-failure
env_file: ./.env
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=database
ports:
- 3307:3306
volumes:
- db:/var/lib/mysql
network_mode: "host"
app:
depends_on:
- mysqldb
build: ./
restart: on-failure
env_file: ./.env
ports:
- 8004:8003
environment:
- DB_HOST=mysqldb
- DB_USER=user
- DB_PASSWORD=password
- DB_NAME=database
- DB_PORT=3306
stdin_open: true
tty: true
volumes:
db:
I want to properly configure the ports in my docker compose, but I am not sure exactly how to go about it. Up until this point I was following a medium tutorial on how to set up docker with node.js and mysql but I am getting ECONNREFUSED for 127.0.0.7:3306(mysql port) and a message that the 8003 port is already taken(I have tried killing processes, restarting... but the issue seems to be in docker compose). If I run mysql service and npm start, or just the dockerfile, it works fine with the database but doesn't in docker.
My mysql port here is 3306 and my nodejs app is running on 8003. I have also tried to set it to 3306:3306 and 8003:8003 but haven't had any luck.
I'm adding this just in case it's usefull somehow:
FROM node:latest
WORKDIR /home/user/...
COPY package*.json ./
RUN npm install
RUN npm ci --only=production
COPY . .
EXPOSE 8003
CMD [ "npm", "start" ]
How did I missconfiger the ports?
You might have old containers around that used the ports and exited. They don't release the ports until you remove them.
To see if you have one that uses port 3306, you can run
docker ps -a | grep :3306
If there is a container with status 'Exited', you can remove it with
docker rm <container name>
Then the port should be available again
A quick way to remove all exited containers is (on Linux)
docker rm $(docker ps -aq)

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'db'

I have an error in logs of my docker-compose
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'db'
Full error text https://controlc.com/3e1bc743
On the server docker-compose works without this error.
It seems that mysql isn't running on port 3306
sudo netstat -tunpl | grep 3306 # did not show anything
Also didn't see any tasks on this port
sudo lsof -i tcp:3306
Could you please recommend direction how to solve the proble?
db/Dockerfile
FROM mysql
RUN mkdir /var/log/mysql && chmod 777 /var/log/mysql
docker-compose.yaml
version: '3'
services:
sender:
container_name: sender
build:
context: ./sender
dockerfile: Dockerfile
image: sender:latest
#command: tail -f /dev/null
command: python run.py
#command: python run_output_to_files.py
depends_on:
- stream_server
- db
env_file:
- sender/variables.env
- database.env
volumes:
- ./sender/logs/:/logs/:rw
ports:
- 8083:8083
- 554:554
- "1241-1244:1241-1244/udp"
receiver:
container_name: receiver
ports:
- 5004:5000
image: receiver:latest
build:
context: ./receiver
dockerfile: Dockerfile
command: flask run --host=0.0.0.0
depends_on:
- stream_server
- sender
- db
environment:
- STREAM_SERVER_URL=stream_server
- DELAY_MSEC=750
stream_server:
container_name: stream_server
ports:
- 1935:1935
- 1985:1985
- 8080:8080
image: ossrs/srs:3
#command: ./objs/srs -c conf/realtime.conf
db:
container_name: db
image: db:latest
build:
context: ./db
dockerfile: Dockerfile
restart: on-failure
ports:
- "3306:3306"
volumes:
- ./db/mysql/:/var/lib/mysql/
- ./db/conf.d/:/etc/mysql/conf.d/
#- ./db/logs/:/var/log/mysql/:rw
- ./db/startup_scripts/:/docker-entrypoint-initdb.d/
env_file:
- database.env
networks:
default:
external:
name: buildings_default

run command in docker-compose.yml

I have laravel project and must create a docker container for this.
I am done doing this but for MySQL I must run some commands
docker-compose exec app php artisan key:generate
docker-compose exec db bash
mysql -u root -p
Login Using password Library!23
GRANT ALL ON laravel.* TO 'root'#'%' IDENTIFIED BY '123';
FLUSH PRIVILEGES;
EXIT;
exit
docker-compose exec app php artisan migrate
In the line 2 app switch the bash and I must exit to run commands
but I need to open MySQL bash login and give permission to the user after that run artisan migrate
and its my docke-compose.yml
version: '3'
services:
#PHP Service
app:
build:
context: .
dockerfile: Dockerfile
image: xxxxxxx/lumen:Library
container_name: Library
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
networks:
- app-network
#Nginx Service
webserver:
image: nginx:alpine
container_name: LibraryWebserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#MySQL Service
db:
image: mysql:5.7.22
container_name: Librarydb
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: library
MYSQL_ROOT_PASSWORD: Library!23
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- app-network
volumes:
- dbdata:/var/lib/mysql
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
and my Dockerfile
FROM php:7.4-fpm
COPY composer.lock composer.json /var/www/
WORKDIR /var/www
RUN apt-get update --fix-missing && apt-get install -y \
build-essential \
libssl-dev \
zlib1g-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
zlibc \
mariadb-client \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
zip
RUN docker-php-ext-install opcache && docker-php-ext-enable opcache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pdo_mysql exif pcntl
#RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install bcmath
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
EXPOSE 9000
CMD ["php-fpm"]
can anyone help me???
and i want to run composer install in app bash
for step 2 - 8 you have to ways like our friends says
create bootstrap file with sql commands and run it in your dockerfile
or
you can create user and pass and grant admin access to user in docker-compose.yml
db:
image: mysql:5.7.22
container_name: Librarydb
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: library
MYSQL_ROOT_PASSWORD: TheRootPassword
MYSQL_USER: root
MYSQL_PASSWORD: PasswordForLoginAndUse
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- app-network
volumes:
- dbdata:/var/lib/mysql
and about generating a key with artisan its not necessary
app think you run it in one system because of docker
and i prefer you to run migration manually
its better
instead of executing the MySQL commands directly (or manually). You can bootstrap MySQL containers with all the needed data and configurations using the following approach.
1- Create a bootstrap file : sql-scripts.sql
GRANT ALL ON laravel.* TO 'root'#'%' IDENTIFIED BY '123';
FLUSH PRIVILEGES;
2- Create a custom MySQL Docker image: mysql.Dockerfile
FROM mysql:8.0.1
COPY ./sql-scripts.sql /docker-entrypoint-initdb.d/
3- build MySQL docker image and use it in your docker-compose file. You need to before the below change on your docker-compose. The bootstrap file will be executed automatically the FIRST TIME you execute docker-compose up. you need to remove the MySQL volume to make this works for your stack docker volume rm dbdata.
db:
build:
context: .
dockerfile: mysql.Dockerfile

django cant access mysql docker compose

this is my docker-compose file
version: '3'
services:
djangoSql:
restart: always
network_mode: bridge
container_name: djangoSql
image: mysql
volumes:
- .:/code
environment:
MYSQL_DATABASE: test1
MYSQL_ROOT_PASSWORD: 1234
ports:
- 6044:3306
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
interval: 2s
timeout: 20s
retries: 10
web:
build: .
network_mode: bridge
volumes:
- .:/code
ports:
- "8000:8000"
image: django
environment:
WAIT_HOSTS: djangoSql:3306
WAIT_HOSTS_TIMEOUT: 300
WAIT_SLEEP_INTERVAL: 30
WAIT_HOST_CONNECT_TIMEOUT: 30
depends_on:
- djangoSql
links:
- djangoSql:mysql
this is my error
django.db.utils.OperationalError: (1045, 'Plugin caching_sha2_password could not be loaded: /usr//usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory')
the url has two usr i don't know why
this is docker file
FROM python:3.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD ./wait-for-it.sh /code/wait-for-it.sh
ADD . /code/
CMD ["/code/wait-for-it.sh", "djangoSql:3306", "-t", "6000", "--`","python","manage.py", "runserver", "0.0.0.0:8000"]`
and this is requirement.txt
Django>=2.0,<3.0
djangorestframework
mysqlclient
tensorflow==1.15
setuptools>=41.0.0
pandas
Keras
according to mysql official image you need to add this command to your mysql service in the compose file:
command: --default-authentication-plugin=mysql_native_password
and do not forget to create a new container of your mysql image after adding this command.

Rails app using docker-compose wont connect to the mysql container

Trying to get a rails app running using docker-compose. I run docker-compose build and it completes with no errors. I then run docker-compose up and both of the containers start. Then I run docker-compose run web rake db:create db:migrate and run into an error:
rake aborted!
Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1' (111 "Connection refused")
My Dockerfile:
FROM ruby:2.5.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs mysql-client sqlite3 zlib1g-dev libxslt-dev git && \
gem install bundler
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
Docker-compose
version: '3.3'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'online_community_development'
MYSQL_ROOT_PASSWORD: '******'
MYSQL_HOST: 'localhost'
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3306:3306'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- 'my-db:/var/lib/mysql'
container_name: datab
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- web-app:/myapp
ports:
- "3000:3000"
depends_on:
- db
links:
- db:db
restart: always
volumes:
my-db: {}
web-app: {}
Database.yml
development:
adapter: mysql2
encoding: utf8
database: online_community_development
pool: 5
username: root
password: slumland
socket: /var/run/mysqld/mysqld.sock
host: db
New to docker so not even sure if I am issuing the commands correctly. I need to create and seed the database and have the app container connect to it. I think the issue is related to it trying to connect via localhost, but even when I changed the host to db I still got the same results. Any help would be greatly appreciated.
tl;dr:
Try this docker-compose.yml:
version: '3.3'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'online_community_development'
MYSQL_ROOT_PASSWORD: '******'
MYSQL_HOST: 'localhost'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- 'my-db:/var/lib/mysql'
container_name: datab
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
environment:
DATABASE_URL: 'mysql2://db'
RAILS_ENV: 'development'
volumes:
- web-app:/myapp
ports:
- "3000:3000"
depends_on:
- db
restart: always
volumes:
my-db: {}
web-app: {}
In detail:
First of all your docker-compose-file is kinda misconfigured.
Therefore I will do a small instruction on docker-compose.yml-files before heading over to your question.
The links:-thing is a legacy feature of docker which you should strictly avoid:
https://docs.docker.com/compose/compose-file/#links
Moreover, it is not even required when you're working with docker-compose
Also, you're using expose: and ports: when defining your database-service.
The ports-key is opening up a port on your host-machine and forwards it to your docker-service:
https://docs.docker.com/compose/compose-file/#ports
Using ports-key on database-definitions makes your database accessible to the www - which is not what you want in most cases.
The expose-key opens the port locally, in the created docker network.
https://docs.docker.com/compose/compose-file/#expose
This is what we want for databases.
Editing your docker-compose.yml-file results in the following:
version: '3.3'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'online_community_development'
MYSQL_ROOT_PASSWORD: '******'
MYSQL_HOST: 'localhost'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- 'my-db:/var/lib/mysql'
container_name: datab
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- web-app:/myapp
ports:
- "3000:3000"
depends_on:
- db
restart: always
volumes:
my-db: {}
web-app: {}
Getting back to your primary problem:
rake aborted! Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1' (111 "Connection refused")
It looks like rake expects the database to be available at localhost - therefore I think that the cause of this issue is a misconfiguration.
Unfortunately I'm not very familiar with rake but nevertheless your database.yaml looks correct.
I did some research and came across this post:
Rake tasks seem to ignore database.yml configuration
Maybe you could try to set the environment-variable DATABASE_URL in your docker-compose-file: DATABASE_URL=mysql://db
I'd also recommend to set the correct context-environment-variable: RAILS_ENV=development
When you do alle these changes you should come up with the following docker-compose.yml:
version: '3.3'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'online_community_development'
MYSQL_ROOT_PASSWORD: '******'
MYSQL_HOST: 'localhost'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- 'my-db:/var/lib/mysql'
container_name: datab
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
environment:
DATABASE_URL: 'mysql2://db'
RAILS_ENV: 'development'
volumes:
- web-app:/myapp
ports:
- "3000:3000"
depends_on:
- db
restart: always
volumes:
my-db: {}
web-app: {}
Hope this helps.
Regards,
Hermsi
your db seems to be configured to listen on localhost only. Unfortunately this will not work since your app is technically another network host (container) within the compose network. Try making your db listen on all network interfaces.