Connect to mySQL in Laravel 9 installed using Docker - mysql

Recently, I installed Laravel 9 by following the steps below:
First, I downloaded and installed Docker Desktop and after running it,
I ran the following command in the directory where I wanted to install my Laravel project:
curl -s "https://laravel.build/example-app" | bash
After Laravel was successfully installed, I ran the following lines of code to activate sail:
./vendor/bin/sail up
cd example-app
Now when I check Docker to see the services that are being run for example-app, I see:
example-app_mysql_1 mysql/mysql-server:8.0
But when I click on the "OPEN IN BROWSER" button to see a page similar to phpmyadmin, I get one of the following errors:
Error 1: This error is thrown when I enter the URL as http://localhost:3306:
localhost sent an invalid response. ERR_INVALID_HTTP_RESPONSE
Error 2: And this error is thrown when I enter the URL as http://localhost:3306:
localhost sent an invalid response.
ERR_SSL_PROTOCOL_ERROR
As I need to create a new database with the same name defined in my .env file (shown below), I need to have access to mysql wizard. Besides, in the developing phase, sometimes, I may need to manipulate the database manually (with using migrations and other artisan commands).
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=example_app
DB_USERNAME=sail
DB_PASSWORD=password
How can I solve this?

mysql is not available through the browser.
You must either install phpmyadmin or connect to mysql as a wizard through softwares such as tableplus or sequel pro or etc.
But in any case you can install phpmyadmin by adding the following code to docker-compose.
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- 8080:80
environment:
MYSQL_USERNAME: "${DB_USERNAME}"
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
PMA_HOST: mysql
networks:
- sail
Do not forget after adding this code use sail build --no-cache to rebuild services

Related

docker-compose up invalid mode /docker-entrypoint-initdb.d/ - cannot create container for service database

I have to use docker-compose up to start a database. Everything we needed for that is already given and it works for my partners. Meanwhile I have the following problem. (I'm using Mac OS Catalina btw)
Every time I try to use docker-compose up the following error occurs
docker-compose up
Creating ziegel24_database_1 ... error
ERROR: for ziegel24_database_1 Cannot create container for service database: invalid mode: /docker-entrypoint-initdb.d/
ERROR: for database Cannot create container for service database: invalid mode: /docker-entrypoint-initdb.d/
ERROR: Encountered errors while bringing up the project.
the docker-compose.yml is the following
version: "3.1"
services:
database:
image: mysql:5.7
volumes:
- ./mysql/db/entrypoint:/docker-entrypoint-initdb.d/
ports:
- "3308:3306"
environment:
- "MYSQL_ROOT_PASSWORD=geheim"
- "MYSQL_DATABASE=Ziegel24"
I have already checked if my docker compose and engine are the correct version which they are. (Mysql is on a newer version but since docker creates a new database it would pull the needed sql version I was told)
I also have tried to locate the said docker-entrypoint-initdb.d directory but even running find on my whole computer didn't give results, so I guess the whole directory is not there?
Is there any way to download it manually or does it come in a package I mistakenly didn't install?
EDIT
I've realised the docker-entrypoint-initdb.d shouldn't be on my computer anyway, but in the mysql:5.7 image. I still don't know what the exact error is and how to fix it but yeah that's new.
Since I didn't find any help when I searched my error I came here for help.
The short syntax for volumes is (HOST:CONTAINER) or (HOST:CONTAINER:ro) if access mode is specified.
If the host path contains a colon (:) CONTAINER is interpreted as access mode.
In your case ./mysql/db/entrypoint is a relative path and docker expands it to full path. If this full path contains a colon, /docker-entrypoint-initdb.d/ is considered the access mode which is obviously invalid (allowed values are ro and rw), hence the error.
This might not be your case but I could reproduce the behaviour above with Docker version 18.04.0-ce, build 3d479c0 and docker-compose version 1.21.0, build 5920eb0 on Ubuntu 14.04.5 LTS.
Hope this helps.

Switch from docker mysql container to host's mysql without using network-mode="host"

My company has a docker-container based website (Ubuntu containers), deployed via GitHub => CircleCI => AWS. (This was set up by a consultant, who we are not currently working with. I'm trying to make sense out of everything on my own.)
I've copied the source files to my Windows 10 development PC.
Locally, the website is running successfully, until it tries to access MySQL data.
I've installed MySQL (8) locally, with default settings (port 3306) and location (C:\ProgramData\MySQL\MySQL Server 8.0\Data), and imported the database. I've created root user. Running test queries as root from MySQL Workbench works.
I've read Q&A's such as How to connect locally hosted MySQL database with the docker container.
I've successfully bridged to host's IP (on EthernetV; Docker running in Hyper-V) 172.26.92.81 for other purposes, specifically to have XDebug in my website container talk to phpstorm on my Windows 10 host. (I could use host.docker.internal for IP; but I'm making everything as "concrete" as possible, until everything works.)
I just don't understand what I have to change where, for redirecting MySQLi queries (in php as create web pages) to the (development pc) host. (Assume I'm clueless about both MySQL and Docker and Apache, until proven otherwise.)
Relevant parts of (original) docker-compose.yml:
mywebsite:
build:
context: ./mywebsite/
dockerfile: Dockerfile
...
depends_on:
- mysql
links:
- mysql
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASS: xxx
MYSQL_SCHEMA: xxx
MYSQL_PORT: 3306
MYSQL_CHARSET: utf8
mysql:
image: mysql:5.7
ports:
- 3305:3306
command: mysqld --sql_mode=""
environment:
MYSQL_DATABASE: xxx
MYSQL_ROOT_PASSWORD: xxx
volumes:
- data:/var/lib/mysql
NOTE: Not going for "best practices" above; I need to see a simple approach working. Security comes later.
I'd prefer a solution that doesn't involve "network_mode: "host" -- solving it that way would avoid details that I need to understand. [The linked Q&A shows that host mode is the simplest solution, but that is "too simple" - obscures some important considerations.]
Host has MySQL on its port 3306. The mysql container shown above: is it using its own copy of MySQL? Or is that already attempting to connect to host's MySQL? And why does it have the port mapping 3305:3306? (I can't change that to 3306:3306; if do so, it is unable to assign the port number. I assume that is because host's MySQL already uses 3306, and that port line is exposing the mysql container's MySQL?)
The volume mapping data:... is where I should move the data to, if I want to use the mysql container as is? That's probably what I will do for now - which may make this SO question moot - but I'd still like to know how to do what I ask.
I'm assuming it is its own database, because it has its own version number (5.7).
From php inside mywebsite:
$connection = new \mysqli(
$_ENV["MYSQL_HOST"],
$_ENV["MYSQL_USER"],
$_ENV["MYSQL_PASS"],
'INFORMATION_SCHEMA',
$_ENV["MYSQL_PORT"]
);
$result = $connection->query("SELECT VERSION();");
# breakpoint: $result > one row > ['VERSION()'] = 5.7.25
which is the version number of that mysql image, not the host's mysql.
similarly, list of databases doesn't include some databases I see on the host mysql from Workbench.
What changes do I need to make in docker-compose.yml?
Do I also need to make changes in mywebsite's Dockerfile?
mywebsite is based on apache2 + php 7.3. Dockerfile:
FROM php:7.3.3-apache-stretch
...
RUN apt-get update && ... docker-php-ext-install ... mysqli \
&& docker-php-ext-enable mysqli ...
...
COPY /php.ini /usr/local/etc/php/
COPY /src/ /var/www/html/
First of all, the declaration:
links:
- mysql
in the mywebiste service is not needed and actually stays in the way of you solving your issue. You should remove it.
After doing that, you can try 2 things (both of them worked for me):
change MYSQL_HOST to point to your computer's IP (not 'localhost', not '127.0.0.1' but your local network IP address) and start only the mywebsite service.
in version 3.0 or higher of docker-compose file you can add extra hosts:
mywebsite:
...
extra_hosts:
- "mysql:<your ip>"
I hope this helps

How to tie mysql database in one container to another container running my django blog app (with docker-compose)

I have created a blog app with django and attached it to a mysql database stored on my local machine(localhost), which I manage through phpmyadmin.
However, I switched to an ubuntu 18.04 LTS (previously on a windows machine) and wanted to deploy my app with docker containers.
I want to run mysql database in one container, and my blog app in another container, and have them communicate with each other (I am using docker-compose to achieve this).
Below is the DATABASES dictionary on my app:
And here is docker-compose.yml file.
After firing the docker-compose up command, I get this error:
It says '(2006, "Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(/usr/local/mysql/lib/plugin/caching_sha2_password.so: cannot open shared object file: No such file or diectory")'.
In the DB container, you are only setting password for root user but using test user. So you either need to set MYSQL_PASSWORD env var. Or use root user.
More on the env variables in mysql docker hub docs
My recommendation is to change db service definition to
services:
db:
image: mysql
enviroment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
This encurages not to use root user, which is considered best practice.
What actually probably causes this errors is that you have wrong version of mysql. On mysql docker hub, you can see that the latest tag (with is the implicit tag if you don't provide any), is the same as 8.0. But a lot of apps is only compatible with the older 5.7. To switch this, in your docker-compose add 5.7 tag:
services:
db:
image: mysql:5.7
(5.7 and 8.0 is actually only one major release apart, and 8.0 was released in 2017)

Adding Flyway to a MySQL Docker Container

I'm building an derivative to this Docker container for mysql (using it as a starting point): https://github.com/docker-library/mysql
I've amended the Dockerfile to add in Flyway. Everything is set up to edit the config file to connect to the local DB instance, etc. The intent is to call this command from inside the https://github.com/docker-library/mysql/blob/master/5.7/docker-entrypoint.sh file (which runs as the ENTRYPOINT) around line 186:
flyway migrate
I get a connection refused when this is run from inside the shell script:
Flyway 4.1.2 by Boxfuse
ERROR:
Unable to obtain Jdbc connection from DataSource
(jdbc:mysql://localhost:3306/db-name) for user 'root': Could not connect to address=(host=localhost)(port=3306)(type=master) : Connection refused
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL State : 08
Error Code : -1
Message : Could not connect to address=(host=localhost)(port=3306)(type=master) : Connection refused
But, if I remove the command from the shell script, rebuild and log in to the container, and run the same command manually, it works with no problems.
I suspect that there may be some differences with how the script connects to the DB to do its thing (it has a built in SQL "runner"), but I can't seem to hunt it down. The container restarts the server during the process, which is what may be the difference here.
Since this container is intended for development, one alternative (a work-around, really) is to use the built in SQL "runner" for this container, using the filename format that Flyway expects, then use Flyway to manage the production DB's versions.
Thanks in advance for any help.
I mean it's the good way to start from the ready image (for start).
You may start from image docker "mysql"
FROM mysql
If you start the finished image - when creating new version your docker then
will only update the difference.
Next, step you may install java and net-tools
RUN apt-get -y install apt-utils openjdk-8-jdk net-tools
Config mysql
ENV MYSQL_DATABASE=mydb
ENV MYSQL_ROOT_PASSWORD=root
Add flyway
ADD flyway /opt/flyway
Add migrations
ADD sql /opt/flyway/sql
Add config flyway
ADD config /opt/flyway/conf
Add script to start
ADD start /root/start.sh
Check start mysql
RUN netstat -ntlp
Check java version
RUN java -version
Example file: /opt/flyway/conf/flyway.conf
flyway.driver=com.mysql.jdbc.Driver
flyway.url=jdbc:mysql://localhost:3306/mydb
flyway.user=root
flyway.password=root
Example file: start.sh
#!/bin/bash
cd /opt/flyway
flyway migrate
# may change to start.sh to start product migration or development.
Flyway documentation
I mean that you in next step may use flyway as service:
For example:
docker run -it -p 3307:3306 my_docker_flyway /root/start << migration_prod.sh
docker run -it -p 3308:3306 my_docker_flayway /root/start << migration_dev.sh
etc ...
services:
# Standard Mysql Box, we have to add tricky things else logging by workbench is hard
supermonk-mysql:
image: mysql
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
- MYSQL_ROOT_PASSWORD=P#ssw0rd
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
ports:
- "3306:3306"
healthcheck:
test: ["CMD-SHELL", "nc -z 127.0.0.1 3306 || exit 1"]
interval: 1m30s
timeout: 60s
retries: 6
# Flyway is best for mysql schema migration history.
supermonk-flyway:
container_name: supermonk-flyway
image: boxfuse/flyway
command: -url=jdbc:mysql://supermonk-mysql:3306/test?verifyServerCertificate=false&useSSL=true -schemas=test -user=root -password=P#ssw0rd migrate
volumes:
- "./sql:/flyway/sql"
depends_on:
- supermonk-mysql
mkdir ./sql
vi ./sql/V1.1__Init.sql # and paste below
CREATE TABLE IF NOT EXISTS test.USER (
id VARCHAR(64),
fname VARCHAR(256),
lname VARCHAR(256),
CONSTRAINT pk PRIMARY KEY (id));
save and close
docker-compose up -d
wait for 2 minutes
docker-compose run supermonk-flyway
Ref :
https://github.com/supermonk/webapp/tree/branch-1/docker/docker-database
Thanks to docker community and mysql community
docker-compose logs -f

Can't connect nodejs and mysql in same docker

I'm new in docker and i'm trying to make my nodejs express run inside it.
I'm trying to install the dependencies using shellscript and its working but in the end I can't connect to mysql.
My docker file install mysql, create an user and a database, and install nodejs too.
Then it runs npm install and try to start my app but knex says it can't connect to the mysql with the message:
Knex:Error Pool2 - Error: connect ECONNREFUSED /var/run/mysqld/mysqld.sock
Here's a gist with the code i'm using. (nodejs part is incomplete, just with the important part):
https://gist.github.com/jradesenv/527f6e59ab2e7985c38fbed3a2084c83
I hope anyone will have a good ideia on how to resolve or debbug this.
The best practice is to keep the components of a micro-service separate in their own container.
See for instance "Learn Docker by building a Microservice" from Dave Kerr.
He does declare two services:
version: '2'
services:
users-service:
build: ./users-service
ports:
- "8123:8123"
depends_on:
- db
environment:
- DATABASE_HOST=db
db:
build: ./test-database
With a dedicated Dockerfile for the database:
FROM mysql:5
ENV MYSQL_ROOT_PASSWORD 123
ENV MYSQL_DATABASE users
ENV MYSQL_USER users_service
ENV MYSQL_PASSWORD 123
ADD setup.sql /docker-entrypoint-initdb.d
Docker containers are designed to run a single command. The mysql installer expects the service it registered to automatically be started on the OS bootup, but that's not the case inside of a container.
The proper solution is to split these into two separate containers, one db container, and another nodejs/app container. Link and run the two together with a docker-compose configuration that automatically sets up the host names.
The less ideal option is supervisord which you can use to run and manage multiple processes inside of the container. You install it just like any other app, configure your db and node app as two services for supervisord to manage, and then launch supervisord as your container's run command.
Use docker-compose and create a dockerfile for your nodejs and one for mysql. Each container is responsible for doing their thing. In your compose, link them. Then point your nodejs db connection to the mysql container.