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?
I am trying to connect a Spring application (using Kotlin and Gradle) to a Google Cloud SQL instance and database. I am getting the error message
java.lang.RuntimeException: [<project-name>:europe-west1:<db-instance>] The Cloud SQL Instance does not exist or your account is not authorized to access it. Please verify the instance connection name and check the IAM permissions for project "<project-name>"
I have followed the guide on how to connect carefully, but to no avail.
Relevant files
src/main/resources/application.yml
server:
port: ${PORT:8080}
spring:
liquibase:
change-log: classpath:liquibase/db.changelog.xml
contexts: production
cloud:
appId: <project-id>
gcp:
sql:
instance-connection-name: <instance-connection-name>
database-name: <db-name>
jpa:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
default_schema: <schema>
show_sql: true
ddl-auto: none
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
continue-on-error: true
initialization-mode: always
url: jdbc:mysql:///<db-name>?cloudSqlInstance=<instance-connection-name>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<user>&password=<password>
username: <user>
password: <password>
---
spring:
config:
activate:
on-profile: dev
jpa:
hibernate:
ddl-auto: create-drop
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
datasource:
url: jdbc:h2:mem:mydb
username: sa
password: password
driverClassName: org.h2.Driver
cloud:
gcp:
sql:
enabled: false
build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.6.5"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.6.10"
kotlin("plugin.spring") version "1.6.10"
kotlin("plugin.allopen") version "1.4.32"
kotlin("plugin.jpa") version "1.4.32"
kotlin("kapt") version "1.4.32"
}
allOpen {
annotation("javax.persistence.Entity")
annotation("javax.persistence.Embeddable")
annotation("javax.persistence.MappedSuperclass")
}
group = "com.<company>"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:2.6.5")
implementation("org.springframework.boot:spring-boot-starter-webflux:2.6.5")
implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.6.5")
implementation("org.springframework.cloud:spring-cloud-gcp-starter-sql-mysql:1.2.8.RELEASE")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.6.10")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.13.2")
implementation("com.fasterxml.jackson.core:jackson-core:2.13.2")
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.2.2")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.2")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2")
implementation("org.hibernate:hibernate-core:5.6.7.Final")
implementation("javax.persistence:javax.persistence-api:2.2")
implementation( "commons-codec:commons-codec:1.15")
implementation("io.github.microutils:kotlin-logging-jvm:2.1.21")
implementation("ch.qos.logback:logback-classic:1.2.11")
implementation("com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.4.4")
runtimeOnly("com.h2database:h2:2.1.210")
runtimeOnly("org.springframework.boot:spring-boot-devtools:2.6.5")
testImplementation("org.springframework.boot:spring-boot-starter-test:2.6.5")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Dockerfile
FROM openjdk:17-alpine
ENV USER=appuser
# <placeholder> Replace context path for your own application
ENV JAVA_HOME=/opt/openjdk-17 \
HOME=/home/$USER \
CONTEXT_PATH=/aws-service-baseline
RUN adduser -S $USER
# <placeholder> Add additional packages for the docker container here
RUN apk add --no-cache su-exec
# <placeholder> Replace baseline.jar with your applications JAR file (defined in build.gradle.kts)
COPY Docker/runapp.sh build/libs/<application-name>-0.0.1-SNAPSHOT.jar $HOME/
RUN chmod 755 $HOME/*.sh && \
chown -R $USER $HOME
WORKDIR /home/$USER
CMD [ "./runapp.sh"]
Docker/runapp.sh
#!/bin/sh
set -e
# The module to start.
# <placeholder> Replace this with your own modulename (from module-info)
APP_JAR="<application-name>-0.0.1-SNAPSHOT.jar"
JAVA_PARAMS="-XshowSettings:vm"
echo " --- RUNNING $(basename "$0") $(date -u "+%Y-%m-%d %H:%M:%S Z") --- "
set -x
/sbin/su-exec "$USER:1000" "$JAVA_HOME/bin/java" "$JAVA_PARAMS $JAVA_PARAMS_OVERRIDE" -jar -Dserver.port=$PORT "$APP_JAR"
GCP details
I have made sure the SQL instances connection is added to the Cloud Run Revisions. The IAM roles for the compute service account also seem to be right. See images
IAM: https://i.stack.imgur.com/yYaC5.png
Database: https://i.stack.imgur.com/NErad.png
Cloud Run connection https://i.stack.imgur.com/fKTSZ.png
Additional details
When running ./gradlew bootRun on my local machine (with GCP credentials present), the App works properly with an SQL connection. It also works after running ./gradle bootRun to build the JAR file and run the JAR directly. It does not work out of the box when running in Docker, but if I add the GCP credentials to the Docker container locally, it connects to the Database.
Does anyone have any suggestions on what might be wrong? Any help much appreciated!
I have tried connecting locally and locally in a Docker container.
Figured it out! Human error of course. The Cloud Run Service was initially configured with another Services Account, and not the default Compute Engine Service account.
I have a nextjs app which is supposed to connect to an external MySQL database (not one from the same docker network). When running the app locally, it works correctly when connecting to DB, but when running it in a Docker container it keeps on trying to connect to 127.0.0.1, even though the environment variables are configured correctly in the container
Error: Error: connect ECONNREFUSED 127.0.0.1:3306
nextjs_1 | at connect (/opt/app/node_modules/serverless-mysql/index.js:80:15)
Dockerfile config:
FROM node:alpine
RUN mkdir -p /opt/app
RUN apk add --no-cache libc6-compat
ENV NODE_ENV production
ENV PORT 3000
EXPOSE 3000
WORKDIR /opt/app
COPY package.json /opt/app
COPY package-lock.json /opt/app
RUN npm install --no-optional
COPY . /opt/app
RUN npm run build
RUN npx next telemetry disable
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs
CMD [ "npm", "start" ]
Connection code:
const mysql = require('serverless-mysql')
const db = mysql({
config: {
host: process.env.MYSQL_HOST,
database: process.env.MYSQL_DATABASE,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
},
})
exports.query = async (query) => {
try {
const results = await db.query(query)
await db.end()
return results
} catch (error) {
return { error }
}
}
Any ideas?
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
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 %.