Upgrading MySQL Connector/ODBC massively degrades performance - mysql

When upgrading from mysql-connector-odbc-8.0.19 to mysql-connector-odbc-8.0.29 I am noticing a ~70% reduction in speed of execution.
docker-compose.yaml
version: '3.1'
services:
db:
image: mysql:8.0.29-debian
command: --default-authentication-plugin=mysql_native_password
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: example
test:
build: ./
Dockerfile
FROM python:3.10-bullseye
ARG odbcdlurl
RUN { apt-get update && apt install -y unixodbc-dev && wget -qO- $odbcdlurl | tar -xvz -C / --strip-components 1; } && \
cp /lib/libmyodbc8* /usr/lib/x86_64-linux-gnu/odbc/ && \
/bin/myodbc-installer -d -a -n "MySQL" -t "DRIVER=/usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so;"
RUN pip3 install pyodbc==4.0.32
RUN printf '\n\
import timeit \n\
import pyodbc \n\
mysql_conn = pyodbc.connect("DRIVER=/usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so;SERVER=db;DATABASE=sys;UID=root;PWD=example;charset=utf8mb4;") \n\
mysql_cursor = mysql_conn.cursor() \n\
mysql_cursor.execute("SET GLOBAL general_log = 1;") \n\
mysql_cursor.execute("SET global log_output = \x27table\x27;") \n\
mysql_cursor.execute("create temporary table temp(junkvarchar varchar(100));") \n\
start_time = timeit.default_timer() \n\
mysql_cursor.executemany("insert into temp(junkvarchar) values (?)", [("a"*100,) for i in range(100000)]) \n\
print(f"Elapsed Time: {timeit.default_timer() - start_time}") \n\
' >> /test.py
CMD sleep 20 && python3 '/test.py'
Results:
ODBC 8.0.19:
docker-compose down && docker-compose build --build-arg odbcdlurl=https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.19-linux-glibc2.12-x86-64bit.tar.gz && docker-compose up
result: ~13 seconds
ODBC 8.0.29:
docker-compose down && docker-compose build --build-arg odbcdlurl=https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.29-linux-glibc2.12-x86-64bit.tar.gz && docker-compose up
result: ~21 seconds
Test Environments:
I have tested on Docker Desktop 4.8.2 (79419) Windows 10 Pro (19044.1706), as well as AWS EKS, and another Linux Dev machine I have. Point being the results seem consistent regardless of Docker version, OS, or orchestration framework.
The Question:
Why is this occurring and how can I update my ODBC Connector while also not destroying performance?

Related

Docker cannot execute mysqld

I have a Laravel app that was running fine up until a day ago.
Now, anytime I run a "sail up" command, Mysql will start and then immediately shut down with the following error:
[Entrypoint] MySQL Docker Image 8.0.31-1.2.10-server
/entrypoint.sh: line 57: /usr/sbin/mysqld: cannot execute binary file: Exec format error
[Entrypoint] ERROR: Unable to start MySQL. Please check your configuration.
I'm not sure if this has anything to do with it or if it's just a coincidence but this issue seems to have started when I tried to run another "sail up" command on a different Laravel app.
I've tried the following
Tried to replicate in a fresh Laravel app. The same result occurs.
Tried to start the entrypoint with the -l and -c options. The same result occurs.
Tried to start the application with mysql server 5.7. The same result occurs.
Tried forwarding to another port 3307, instead of 3306. The same result occurs.
Both my docker-compose and Dockerfile are pretty standard...no changes from what Laravel provides:
Docker-composer
# For more information: https://laravel.com/docs/sail
version: '3'
services:
laravel.test:
build:
context: ./docker/8.1
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-8.1/app
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
- redis
- meilisearch
- mailhog
- selenium
mysql:
image: 'mysql/mysql-server:8.0'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- 'sail-mysql:/var/lib/mysql'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
networks:
- sail
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
retries: 3
timeout: 5s
redis:
image: 'redis:alpine'
ports:
- '${FORWARD_REDIS_PORT:-6379}:6379'
volumes:
- 'sail-redis:/data'
networks:
- sail
healthcheck:
test: ["CMD", "redis-cli", "ping"]
retries: 3
timeout: 5s
meilisearch:
image: 'getmeili/meilisearch:latest'
ports:
- '${FORWARD_MEILISEARCH_PORT:-7700}:7700'
volumes:
- 'sail-meilisearch:/meili_data'
networks:
- sail
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]
retries: 3
timeout: 5s
mailhog:
image: 'mailhog/mailhog:latest'
ports:
- '${FORWARD_MAILHOG_PORT:-1025}:1025'
- '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
selenium:
image: 'selenium/standalone-chrome'
volumes:
- '/dev/shm:/dev/shm'
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
sail-redis:
driver: local
sail-meilisearch:
driver: local
Dockerfile
FROM ubuntu:22.04
LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=16
ARG POSTGRES_VERSION=14
WORKDIR /var/www/html
ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update \
&& apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
&& mkdir -p ~/.gnupg \
&& chmod 600 ~/.gnupg \
&& echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
&& echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \
&& gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \
&& gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
&& apt-get update \
&& apt-get install -y php8.1-cli php8.1-dev \
php8.1-pgsql php8.1-sqlite3 php8.1-gd \
php8.1-curl \
php8.1-imap php8.1-mysql php8.1-mbstring \
php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \
php8.1-intl php8.1-readline \
php8.1-ldap \
php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \
php8.1-memcached php8.1-pcov php8.1-xdebug \
&& php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update \
&& apt-get install -y yarn \
&& apt-get install -y mysql-client \
&& apt-get install -y postgresql-client-$POSTGRES_VERSION \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container
EXPOSE 8000
ENTRYPOINT ["start-container"]
I'm not really sure what the issue is. Anyone have any suggestions?
Thanks.

I can't do mysql php artisan migrations in my docker compose. Error SQLSTATE[HY000] [2002]

I'm currently developing a laravel-vue-mysql environment with docker compose.
I took as guide these articles link link
My docker compose is working fine the web and app services are working good and its deploy as it should. But i can't configure my db.
I'm try executing docker-compose exec app php artisan migrate but I have SQLSTATE no such file or directory exception, I'm been stuck for 3 days in this.
I've read all comments about this problem but could get solution. I have given all privileges to root user in my db. I have tried changing my dbhost with my container ip or container db name, I have tried changing database.php host for my db name too but it didn't work either.
I think my error could be in my "unix_socket' => '/var/run/mysqld/mysqld.sock',"
I'd like to clarify this route i got it through log in my docker mysql service and put a command in my db. I don't know if i have to put mysql.lock local route
which is /tmp/mysql.sock
Or it could be my database_url route, I'm not sure what i'm doing wrong. Need some help.
I want to create the data tables in my mysql docker service
This is my docker-compose.yml
version: '2'
services:
# The Application
app:
build:
context: ./
dockerfile: app.dockerfile
container_name: app
working_dir: /var/www
volumes:
- ./:/var/www
environment:
- "DB_PORT=3306"
- "DB_HOST=database"
# The Web Server
web:
build:
context: ./
dockerfile: web.dockerfile
container_name: web
working_dir: /var/www
volumes_from:
- app
ports:
- 8080:80
# The Database
database:
build:
context: ./
dockerfile: db.dockerfile
image: mysql:5.7
container_name: db
environment:
- "MYSQL_DATABASE=homestead"
- "MYSQL_USER=root"
- "MYSQL_PASSWORD=secret"
- "MYSQL_ROOT_PASSWORD=secret"
volumes:
- dbdata:/var/lib/mysql
ports:
- "33061:3306"
#Volumes
volumes:
dbdata:
app.dockerfile
FROM php:7.3-fpm
# Update packages
RUN apt-get update
# Install PHP and composer dependencies
RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev
# Clear out the local repository of retrieved package files
# RUN apt-get clean
# Install needed extensions
# Here you can install any other extension that you need during the test and deployment process
RUN apt-get -y install libzip-dev
RUN pecl install mcrypt-1.0.3
RUN docker-php-ext-enable mcrypt
RUN apt-get clean; docker-php-ext-install pdo pdo_mysql zip gd pcntl opcache bcmath
# Installs Composer to easily manage your PHP dependencies.
RUN curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install Node
RUN apt-get update &&\
apt-get install -y --no-install-recommends gnupg &&\
curl -sL https://deb.nodesource.com/setup_10.x | bash - &&\
apt-get update &&\
apt-get install -y --no-install-recommends nodejs &&\
npm config set registry https://registry.npm.taobao.org --global &&\
npm install --global gulp-cli
CMD php-fpm
db.dockerfile
FROM mysql:5.7
# Setup the custom configuration
ADD my.cnf /mysql/mysql.conf.d/my.cnf
web.dockerfile
FROM nginx:1.10
ADD vhost.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www
.env
DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=root
DB_PASSWORD=secret
DATABASE_URL=mysql://root:#database:33061/homestead
vhost.config
server {
listen 80;
index index.php index.html;
root /var/www/public;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
This is my .cnf
[mysqld]
# Accept connections from any IP address
general_log = 1
general_log_file = /var/lib/mysql/general.log
bind-address = 0.0.0.0
socket= /var/run/mysqld/mysqld.sock
#skip-grant-tables
This is my app/config/database.php
'mysql' => [
'driver'=>'mysql',
'url'=>env('DATABASE_URL'),
'host'=>env('DB_HOST','database'),
'port'=>env('DB_PORT','3306'),
'database'=>env('DB_DATABASE', 'forge'),
'username'=>env('DB_USERNAME', 'forge'),
'password'=>env('DB_PASSWORD', ''),
'unix_socket'=>'/var/run/mysqld/mysqld.sock',
'charset'=>'utf8mb4',
'collation'=>'utf8mb4_unicode_ci',
'prefix'=>'',
'prefix_indexes'=>true,
'strict'=>true,
'engine'=> null,
'options'=> extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA =>env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
When i try to migrate the mysql database it's return me this error:
Illuminate\Database\QueryException : SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from information_schema.tables where table_schema = homestead and table_name = migrations and table_type = 'BASE TABLE')
at /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
665| // If an exception occurs when attempting to run a query, we'll format the error
666| // message to include the bindings with SQL, which will make this exception a
667| // lot more helpful to the developer instead of just the database's errors.
668| catch (Exception $e) {
> 669| throw new QueryException(
670| $query, $this->prepareBindings($bindings), $e
671| );
672| }
673|
Exception trace:
1 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[HY000] [2002] No such file or directory")
/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:31
2 PDOException::("SQLSTATE[HY000] [2002] No such file or directory")
/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:27
3 PDO::__construct("mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=homestead", "root", "secret", [])
/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:27
4 Doctrine\DBAL\Driver\PDOConnection::__construct("mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=homestead", "root", "secret", [])
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:67
5 Illuminate\Database\Connectors\Connector::createPdoConnection("mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=homestead", "root", "secret", [])
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:46
6 Illuminate\Database\Connectors\Connector::createConnection("mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=homestead", [])
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/MySqlConnector.php:24
7 Illuminate\Database\Connectors\MySqlConnector::connect()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php:182
8 Illuminate\Database\Connectors\ConnectionFactory::Illuminate\Database\Connectors\{closure}()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:924
9 call_user_func(Object(Closure))
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:924
10 Illuminate\Database\Connection::getPdo()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:959
11 Illuminate\Database\Connection::getReadPdo()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:404
12 Illuminate\Database\Connection::getPdoForSelect()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:330
13 Illuminate\Database\Connection::Illuminate\Database\{closure}("select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'")
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:662
14 Illuminate\Database\Connection::runQueryCallback("select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", Object(Closure))
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:629
15 Illuminate\Database\Connection::run("select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", Object(Closure))
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:338
16 Illuminate\Database\Connection::select("select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'")
/var/www/vendor/laravel/framework/src/Illuminate/Database/Schema/MySqlBuilder.php:18
17 Illuminate\Database\Schema\MySqlBuilder::hasTable("migrations")
/var/www/vendor/laravel/framework/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php:169
18 Illuminate\Database\Migrations\DatabaseMigrationRepository::repositoryExists()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:590
19 Illuminate\Database\Migrations\Migrator::repositoryExists()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php:91
20 Illuminate\Database\Console\Migrations\MigrateCommand::prepareDatabase()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php:63
21 Illuminate\Database\Console\Migrations\MigrateCommand::handle()
/var/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
22 call_user_func_array([])
/var/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
23 Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
/var/www/vendor/laravel/framework/src/Illuminate/Container/Util.php:36
24 Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
/var/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90
25 Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))
/var/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34
26 Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])
/var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php:590
27 Illuminate\Container\Container::call()
/var/www/vendor/laravel/framework/src/Illuminate/Console/Command.php:134
28 Illuminate\Console\Command::execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
/var/www/vendor/symfony/console/Command/Command.php:255
29 Symfony\Component\Console\Command\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
/var/www/vendor/laravel/framework/src/Illuminate/Console/Command.php:121
30 Illuminate\Console\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
/var/www/vendor/symfony/console/Application.php:1001
31 Symfony\Component\Console\Application::doRunCommand(Object(Illuminate\Database\Console\Migrations\MigrateCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
/var/www/vendor/symfony/console/Application.php:271
32 Symfony\Component\Console\Application::doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
/var/www/vendor/symfony/console/Application.php:147
33 Symfony\Component\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
/var/www/vendor/laravel/framework/src/Illuminate/Console/Application.php:93
34 Illuminate\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:131
35 Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
/var/www/artisan:37
First of all if you perform docker exec app env | grep -e DB_ -e DATABASE, you will see only
DB_PORT=3306
DB_HOST=database
This is due to .env file purpose. If you want other variables to be set in you container at running stage, just pass them by this way:
version: '2'
services:
# The Application
app:
...
environment:
- DB_CONNECTION=${DB_CONNECTION}
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
- DATABASE_URL=${DATABASE_URL}
And now
docker exec app env | grep -e DB_ -e DATABASE
DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=root
DB_PASSWORD=secret
DATABASE_URL=mysql://root:#database:33061/homestead
your app container knows how to communicate with your DB

Connection refused when trying to connect to local mysql database from docker container

I have a problem to connect with local mysql database from a docker container. I'm using docker-compose with two services in containers, database is not on container
I have this docker-compose file:
version: '2'
services:
web:
build:
context: ./
dockerfile: web-dev.dockerfile
volumes:
- ./:/var/www
ports:
- "8080:80"
links:
- app
network_mode: "bridge"
dns:
- 10.0.50.6
app:
build:
context: ./
dockerfile: app-dev.dockerfile
volumes:
- ./:/var/www
network_mode: "bridge"
dns:
- 10.0.50.6
the web container is an nginx service with this Dockerfile:
FROM nginx:1.10
ADD ./vhost.dev.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www
and this configuration file:
server {
listen 80;
index index.php index.html;
root /var/www/formapp/public;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
the app container is an app service with this Dockerfile:
FROM php:7-fpm
ENV USER=pasquale
RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client \
openssl zip unzip git nano wget libaio-dev iputils-ping
RUN mkdir -p /opt/oracle/instantclient_10_2
# Download files from in oracle folder:
# https://agora.zanichelli.it/downloads/basic-10.2.0.5.0-linux-x64.zip
# https://agora.zanichelli.it/downloads/sdk-10.2.0.5.0-linux-x64.zip
ADD oracle/basic-10.2.0.5.0-linux-x64.zip /opt/oracle/basic-10.2.0.5.0-linux-x64.zip
ADD oracle/sdk-10.2.0.5.0-linux-x64.zip /opt/oracle/sdk-10.2.0.5.0-linux-x64.zip
RUN unzip /opt/oracle/basic-10.2.0.5.0-linux-x64.zip -d /opt/oracle \
&& unzip /opt/oracle/sdk-10.2.0.5.0-linux-x64.zip -d /opt/oracle \
&& ln -s /opt/oracle/instantclient_10_2/libclntsh.so.10.1 /opt/oracle/instantclient_10_2/libclntsh.so \
&& ln -s /opt/oracle/instantclient_10_2/libclntshcore.so.10.1 /opt/oracle/instantclient_10_2/libclntshcore.so \
&& ln -s /opt/oracle/instantclient_10_2/libocci.so.10.1 /opt/oracle/instantclient_10_2/libocci.so
ADD oracle/tns-admin/tnsnames.ora /opt/oracle/instantclient_10_2/network/admin/tnsnames.ora
ENV LD_LIBRARY_PATH /opt/oracle/instantclient_10_2/
RUN docker-php-ext-install pdo_mysql \
&& pecl install mcrypt-1.0.1 \
&& docker-php-ext-enable mcrypt \
&& pecl install mongodb \
&& docker-php-ext-enable mongodb \
&& docker-php-ext-configure pdo_oci --with-pdo-oci=instantclient,/opt/oracle/instantclient_10_2,10.2 \
&& echo 'instantclient,/opt/oracle/instantclient_10_2' | pecl install oci8 \
&& docker-php-ext-install pdo_oci \
&& docker-php-ext-enable oci8
RUN yes | pecl install xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_enable=1' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.default_enable=1' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_connect_back=1' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_autostart=1' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_handler="dbgp"' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_port=9000' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_host=0.0.0.0' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_log=/var/www/xdebug.log' >> /usr/local/etc/php/conf.d/xdebug.ini
RUN mkdir -p /home/$USER
RUN groupadd -g 1000 $USER
RUN useradd -u 1000 -g $USER $USER -d /home/$USER
RUN chown $USER:$USER /home/$USER
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
WORKDIR /var/www
USER $USER
launching the containers with docker-compose -f docker-compose.dev.yml up --build -d works fine and docker ps command give me this output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7202e2862ef5 190todb_web "nginx -g 'daemon of…" 9 hours ago Up About an hour 443/tcp, 0.0.0.0:8080->80/tcp 190todb_web_1_3c628ae1c69b
d45c04d353d5 190todb_app "docker-php-entrypoi…" 9 hours ago Up About an hour 9000/tcp 190todb_app_1_dd2ac7028b87
I install a lumen app in my project folder formapp and then I created a seeder to insert fake data in my database, and from bash, if I run /projectfolder/formapp$ php artisan db:seed the seeder works and I have this output:
Seeding: UsersTableSeeder
Database seeding completed successfully.
Then I created a route to access my users table from the lumen app:
$router->get('users', function () use ($router) {
return User::all();
});
my lumen env file is this:
APP_NAME=Lumen
APP_ENV=local
APP_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
APP_DEBUG=true
APP_URL=http://localhost
APP_TIMEZONE=UTC
LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=form_db
DB_USERNAME=root
DB_PASSWORD=radiohead
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
JWT_SECRET=JhbGciOiJIUzI1N0eXAiOiJKV1QiLC
but if I try to connect from http://localhost:8080/users I have this lumen error:
SQLSTATE[HY000] [2002] Connection refused (SQL: select * from `users`)
I tried to change the DB_HOST but I cannot solve the problem:
0.0.0.0 (SQLSTATE[HY000] [2002] Connection refused (SQL: select * from `users`));
172.17.0.1 (SQLSTATE[HY000] [1130] Host '172.17.0.2' is not allowed to connect to this MySQL server (SQL: select * from `users`));
172.17.0.1 is my docker0 inet address.
How can I config my project to work?
PS: the lumen app is up and running, is only the db connection that is not working
You cannot use localhost when the database and app are not on the same server.
You need to allow access by something like:
GRANT ALL PRIVILEGES ON *.* TO 'root'#'172.17.0.2' IDENTIFIED BY '<password>';
You can replace 172.17.0.2 by wildcard %.

Connection refused when running October artisan command with docker exec in Jenkins

I'm trying to execute an OctoberCMS migration through Jenkins with a docker command, but I have the next error in Jenkins console:
+ docker exec -u jenkins dockerfilemaster_app_1 php artisan october:up
Migrating application and plugins...
[Illuminate\Database\QueryException]
SQLSTATE[HY000] [2002] Connection refused (SQL: select * from
information_s
chema.tables where table_schema = databasename and table_name =
migrations)
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000] [2002] Connection refused
[PDOException]
SQLSTATE[HY000] [2002] Connection refused
This is the declarative Jenkinsfile I'm using (the "ping" command is to ensure the database is reachable):
pipeline {
agent any
stages {
stage('Composer') {
steps {
script {
sh '''
chmod -R 777 storage
composer install
docker-compose up --build -d
'''
}
}
}
stage('Docker') {
steps {
script {
sh '''
docker exec dockerfilemaster_app_1 useradd jenkins
docker exec -u jenkins dockerfilemaster_app_1 ping -c 2 database
docker exec -u jenkins dockerfilemaster_app_1 php artisan october:up
docker exec -u jenkins dockerfilemaster_app_1 php artisan october:down --force
'''
}
}
}
}
post {
always {
sh '''
docker-compose down
'''
}
}
}
But if I connect to the Jenkins server with SSH, and I execute the same script, It works:
docker-compose up --build -d
docker exec dockerfilemaster_app_1 useradd jenkins
docker exec -u jenkins dockerfilemaster_app_1 php artisan october:up
The database config:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'database'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'databasename'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'secret'),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
The docker-compose.yml file:
version: '2'
services:
web:
build:
context: ./
dockerfile: web.docker
volumes:
- ./:/var/www/public
ports:
- "8081:80"
links:
- app
app:
build:
context: ./
dockerfile: app.docker
volumes:
- ./:/var/www
links:
- database
environment:
- "DB_PORT=3306"
- "DB_HOST=database"
database:
image: mysql:5.6
environment:
- "MYSQL_ROOT_PASSWORD=secret"
- "MYSQL_DATABASE=databasename"
ports:
- "3306:3306"
I can't see why If I execute the script in the server connected with SSH works, but It does not works If Jenkins execute the same script.
This is the whole Jenkins console output:
Branch indexing
> git rev-parse --is-inside-work-tree # timeout=10
Setting origin to https://gitlab.com/[...]
> git config remote.origin.url https://gitlab.com/[...] # timeout=10
Fetching origin...
Fetching upstream changes from origin
> git --version # timeout=10
> git config --get remote.origin.url # timeout=10
using GIT_ASKPASS to set credentials
> git fetch --tags --progress origin +refs/heads/*:refs/remotes/origin/*
Seen branch in repository origin/develop
Seen branch in repository origin/master
Seen 2 remote branches
Obtained Jenkinsfile from e40e597c1a6bb87221f6c0844174534b5a5a4e15
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/docker-file_master
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
> git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url https://gitlab.com/[...] # timeout=10
Fetching without tags
Fetching upstream changes from https://gitlab.com/[...]
> git --version # timeout=10
using GIT_ASKPASS to set credentials
> git fetch --no-tags --progress https://gitlab.com/[...] +refs/heads/*:refs/remotes/origin/*
Checking out Revision e40e597c1a6bb87221f6c0844174534b5a5a4e15 (master)
> git config core.sparsecheckout # timeout=10
> git checkout -f e40e597c1a6bb87221f6c0844174534b5a5a4e15
Commit message: "Testing with env"
> git rev-list --no-walk 1b46891b6e4078d426f8a33dc5fc1f6b2a743f56 # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Composer)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ whoami
jenkins
+ chmod -R 777 storage
+ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Nothing to install or update
Generating autoload files
+ docker-compose up --build -d
Creating network "dockerfilemaster_default" with the default driver
Building app
Step 1/4 : FROM php:7.1-fpm
---> 894f8d826f6a
Step 2/4 : RUN apt-get update && apt-get install -y apt-utils mcrypt libmcrypt-dev mysql-client git zip unzip zlib1g-dev iputils-ping && docker-php-ext-install pdo_mysql mysqli zip
---> Using cache
---> 0881c5505ea5
Step 3/4 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
---> Using cache
---> d1f1d74f8b0f
Step 4/4 : WORKDIR /var/www
---> Using cache
---> 60aefdca48ba
Successfully built 60aefdca48ba
Successfully tagged dockerfilemaster_app:latest
Building web
Step 1/3 : FROM nginx:1.10
---> 0346349a1a64
Step 2/3 : ADD ./vhost.conf /etc/nginx/conf.d/default.conf
---> Using cache
---> 74cadd23348a
Step 3/3 : WORKDIR /var/www
---> Using cache
---> 4142e3e3d33a
Successfully built 4142e3e3d33a
Successfully tagged dockerfilemaster_web:latest
Creating dockerfilemaster_database_1
Creating dockerfilemaster_app_1
Creating dockerfilemaster_web_1
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Docker)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ docker exec dockerfilemaster_app_1 useradd jenkins
+ docker exec -u jenkins dockerfilemaster_app_1 whoami
jenkins
+ docker exec -u jenkins dockerfilemaster_app_1 ping -c 2 database
PING database (172.26.0.2) 56(84) bytes of data.
64 bytes from dockerfilemaster_database_1.dockerfilemaster_default (172.26.0.2): icmp_seq=1 ttl=64 time=0.158 ms
64 bytes from dockerfilemaster_database_1.dockerfilemaster_default (172.26.0.2): icmp_seq=2 ttl=64 time=0.198 ms
--- database ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.158/0.178/0.198/0.020 ms
+ docker exec -u jenkins dockerfilemaster_app_1 php artisan october:up
Migrating application and plugins...
[Illuminate\Database\QueryException]
SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_s
chema.tables where table_schema = databasename and table_name = migratio
ns)
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000] [2002] Connection refused
[PDOException]
SQLSTATE[HY000] [2002] Connection refused
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Required)
Stage "Required" skipped due to earlier failure(s)
[Pipeline] parallel
[Pipeline] { (Branch: editorConfig)
[Pipeline] stage
[Pipeline] { (editorConfig)
Stage "editorConfig" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
Failed in branch editorConfig
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] sh
+ docker-compose down
Stopping dockerfilemaster_web_1 ...
Stopping dockerfilemaster_app_1 ...
Stopping dockerfilemaster_database_1 ...
[3A[2K
Stopping dockerfilemaster_web_1 ... done
[3B[2A[2K
Stopping dockerfilemaster_app_1 ... done
[2B[1A[2K
Stopping dockerfilemaster_database_1 ... done
[1BRemoving dockerfilemaster_web_1 ...
Removing dockerfilemaster_app_1 ...
Removing dockerfilemaster_database_1 ...
[2A[2K
Removing dockerfilemaster_app_1 ... done
[2B[3A[2K
Removing dockerfilemaster_web_1 ... done
[3B[1A[2K
Removing dockerfilemaster_database_1 ... done
[1BRemoving network dockerfilemaster_default
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
Hmm seems when application is installing meanwhile DB instance is not able to start so may be we can add depends_on. database is always create problem in this environments.
version: '2'
services:
web:
build:
context: ./
dockerfile: web.docker
volumes:
- ./:/var/www/public
ports:
- "8081:80"
links:
- app
depends_on: <= THIS
- "app" <= N THIS
app:
build:
context: ./
dockerfile: app.docker
volumes:
- ./:/var/www
links:
- database
depends_on: <= THIS
- "database" <= N THIS
environment:
- "DB_PORT=3306"
- "DB_HOST=database"
database:
image: mysql:5.6
environment:
- "MYSQL_ROOT_PASSWORD=secret"
- "MYSQL_DATABASE=databasename"
ports:
- "3306:3306"
may be it can solve your issue. if NOT then you need to check tools suggested in reference below will help you. as they also mention DB creates problem in docker environment.
You can check reference from here : https://docs.docker.com/compose/startup-order/
if any doubt please comment.
Adding the "sleep" command worked for me. Seems that Docker is still not build when the second stage (the stage named "Docker) starts. I thought the stage starts when the previous stage It's fully finished.
This is the final Jenkins file:
pipeline {
agent any
stages {
stage('Docker') {
steps {
script {
sh '''
chmod -R 777 storage
docker-compose up --build -d
sleep 30
docker exec dockerfilemaster_app_1 useradd jenkins
docker exec dockerfilemaster_app_1 chmod -R 777 /var/www
docker exec -u jenkins dockerfilemaster_app_1 composer install
docker exec -u jenkins dockerfilemaster_app_1 php artisan october:up
docker exec -u jenkins dockerfilemaster_app_1 php artisan october:down --force
'''
}
}
}
}
post {
always {
sh '''
docker-compose down
'''
}
}
}
I put together the "docker-compose up" command with the rest of docker commands, due to putting that command in another stage did not help.

django cannot connect mysql in docker-compose

I'm very new for docker, now I am trying to run django with mariadb in docker through docker-compose, but I always get this error:
I use Docker version 17.09.1-ce, build 19e2cf6, docker-compose version 1.18.0, build 8dd22a9
django.db.utils.OperationalError: (2003, 'Can\'t connect to MySQL
server on \'mariadb55\' (111 "Connection refused")')
I can connect db correctly after run docker-compose up db in local or remote, and I even can run python manage.py runserver 0.0.0.0:6001 correctly in anaconda virtual environment to connect db service in docker by setting parameters of settings.py file like below:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'belter',
# 'HOST': 'mariadb55',
'HOST': '127.0.0.1',
'PORT': '3302',
'PASSWORD': 'belter_2017',
'default-character-set': 'utf8',
'OPTIONS': {
'sql_mode': 'traditional',
}
}
}
This is my docker-compose.yml file
version: '3'
services:
db:
image: mariadb:5.5
restart: always
environment:
- MYSQL_HOST=localhost
- MYSQL_PORT=3306
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
- MYSQL_USER=belter
- MYSQL_PASSWORD=belter_2017
- MYSQL_ROOT_PASSWORD=123456_abc
volumes:
- /home/belter/mdbdata/mdb55:/var/lib/mysql
ports:
- "3302:3306"
web:
image: onlybelter/django_py35
command: python3 manage.py runserver 0.0.0.0:6001
volumes:
- /mnt/data/www/mysite:/djcode
ports:
- "6001:6001"
depends_on:
- db
links:
- db:mariadb55
I almost tried everything I can find, but still cannot figure it out, any help would be nice!
What I have tried:
Docker compose mysql connection failing
Linking django and mysql containers using docker-compose
Django connection to postgres by docker-compose
Finally, I figured it out!
The key point is, just as #SangminKim said, I need to use 3306 not 3302 in settings.py, and use db as HOST not 127.0.0.1.
So this is my docker-compose.yml file now:
version: '3'
services:
db:
image: mariadb:5.5
restart: always
environment:
- MYSQL_HOST=localhost
- MYSQL_PORT=3306 # cannot change this port to other number
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
- MYSQL_USER=belter
- MYSQL_PASSWORD=belter_2017
- MYSQL_ROOT_PASSWORD=123456_abc
volumes:
- /home/belter/mdbdata/mdb55:/var/lib/mysql
ports:
- "3302:3306"
web:
image: onlybelter/django_py35
command: python3 manage.py runserver 0.0.0.0:6001
volumes:
- .:/djcode
ports:
- "6001:6001"
depends_on:
- db
So now we can connect this docker-mysql by mysql -h 127.0.0.1 -P 3302 -u root -p in shell directly, but we have to use db and 3306 in django settings.py file:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'belter',
# 'HOST': 'mariadb55',
'HOST': 'db', #<---
'PORT': '3306', #<---
'PASSWORD': 'belter_2017',
'default-character-set': 'utf8',
'OPTIONS': {
'sql_mode': 'traditional',
}
}
}
And we can still check if this port is open, by running extra command in docker-compose.yml file:
...
web:
image: onlybelter/django_py35
command: /bin/sh -c "python check_db.py --service-name mysql --ip db --port 3306"
volumes:
- .:/djcode
...
Here is check_db.py file:
# check_db.py
import socket
import time
import argparse
""" Check if port is open, avoid docker-compose race condition """
parser = argparse.ArgumentParser(description='Check if port is open, avoid\
docker-compose race condition')
parser.add_argument('--service-name', required=True)
parser.add_argument('--ip', required=True)
parser.add_argument('--port', required=True)
args = parser.parse_args()
# Get arguments
service_name = str(args.service_name)
port = int(args.port)
ip = str(args.ip)
# Infinite loop
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((ip, port))
if result == 0:
print("{0} port is open! Bye!".format(service_name))
break
else:
print("{0} port is not open! I'll check it soon!".format(service_name))
time.sleep(3)
By the way, this is my Dockerfile for build django-py35:
FROM python:3.5-alpine
MAINTAINER Xin Xiong "xiongxin20008#126.com"
ENV PYTHONUNBUFFERED 1
RUN set -e; \
apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
linux-headers \
mariadb-dev \
python3-dev \
postgresql-dev \
freetype-dev \
libpng-dev \
g++ \
;
RUN mkdir /djcode
WORKDIR /djcode
ENV REFRESHED_AT 2017-12-25
ADD requirements.txt /djcode/
RUN pip install --no-cache-dir -r /djcode/requirements.txt
RUN pip install uwsgi
ADD . /djcode/ # copy . to /djcode/
EXPOSE 6001
See more details from here: https://github.com/OnlyBelter/django-compose
You should use the container name instead of localhost (or 127.0.0.1) in your settings.py file. Try providing a container name to the db service in the docker-compose.yml file using container_name attribute and replace the host name in the settings.py by the value of the container_name. (Make sure that they are in the same network that docker compose creates for you.)
Build container with this:
docker run --name mysql-latest \
-p 3306:3306 -p 33060:33060 \
-e MYSQL_ROOT_HOST='%' -e MYSQL_ROOT_PASSWORD='strongpassword' \
-d mysql/mysql-server:latest
Make sure MYSQL_ROOT_HOST='%', that means root can connect from any IP.