SQLSTATE[HY000] [2002] Connection refused when trying to Dockerize Laravel App - php

I was able to access the mysql database from phpmyadmin using user: admin and password: root and the url: 127.0.0.1:3310 and I was able to load the website on 127.0.0.1:8008 but when i try to login or interact with the database i get the error below:
SQLSTATE[HY000] [2002] Connection refused
select * from users where email = boyiajas#gmail.com limit 1
and I also try to do a migration from within the app docker container but failed as well
root#58a709f18668:/var/www/html# php artisan migrate
Illuminate\Database\QueryException
SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravelvueblog_db and table_name = migrations and table_type = 'BASE TABLE')
below is my .env file
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3309
DB_DATABASE=laravelvueblog_db
DB_USERNAME=admin
DB_PASSWORD=root
below is my vhost.conf file
<VirtualHost *:8008>
DocumentRoot /var/www/html/public
<Directory "/var/www/html/public">
AllowOverride all
Require all granted
</Directory>
#ErrorLog ${APACHE_LOG_DIR}/error.log
#CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
below is my Docker file
FROM php:8-apache
USER root
RUN apt-get update -y && apt-get install -y openssl curl zip unzip git nano
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install mysqli pdo pdo_mysql opcache
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
WORKDIR /app
COPY . /app
COPY vhost.conf /etc/apache2/sites-available/000-default.conf
RUN chown -R www-data:www-data /app && a2enmod rewrite
RUN rm -rf /var/www/html && ln -s /app /var/www/html
RUN composer install
RUN php artisan optimize:clear
CMD php artisan serve --host=0.0.0.0 --port=8000
EXPOSE 8000
below is my docker-compose.yaml file
version: '3.8'
services:
db:
image: mariadb:latest
container_name: db
ports:
- 3309:3306
environment:
MYSQL_DATABASE: laravelvueblog_db
MYSQL_ROOT_PASSWORD: root
MYSQL_PASSWORD: root
MYSQL_USER: admin
volumes:
- mysql_file:/docker-entrypoint-initdb.d
networks:
- appnetwork
main:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/app
ports:
- 8008:8000
environment:
# MYSQL_DATABASE: laravelvueblog_db
# MYSQL_ROOT_PASSWORD: root
# MYSQL_PASSWORD: root
# MYSQL_USER: admin
DB_HOST: db
DB_USER: admin
DB_PASSWORD: root
DB_NAME: laravelvueblog_db
WAIT_HOSTS: db:3306
depends_on:
- db
links:
- db
networks:
- appnetwork
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- 3310:80
links:
- mysql
environment:
PMA_HOSTS: db
PMA_PORT: 3306
depends_on:
- db
networks:
- appnetwork
volumes:
mysql_file:
driver: local
networks:
appnetwork:
driver: bridge

After several attempt I found the problem, since all the services are on the same network (appnework)
I used the internal port in my laravel .env file like below
DB_PORT=3306
And now it works fine

Related

Docker Container Define user home folder

I have the following php service in docker-compse.yml
version: '3'
networks:
laravel:
driver: bridge
services:
nginx:
image: nginx:stable-alpine
restart: unless-stopped
ports:
- "${WEB_PORT}:80"
volumes:
- "${PROJECT_DIR}:/var/www/html"
- "${NGINX_CONFIG}:/etc/nginx/conf.d/default.conf"
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- php
- mysql
networks:
- laravel
mysql:
image: mysql:5.7.29
restart: unless-stopped
user: "${HOST_UID}:${HOST_GID}"
tty: true
ports:
- "${SQL_PORT}:3306"
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker/mysql:/var/lib/mysql
networks:
- laravel
php:
build:
context: ./docker
dockerfile: Dockerfile-php
user: "${HOST_UID}:${HOST_GID}"
volumes:
- "${PROJECT_DIR}:/var/www/html"
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
#- "${COMPOSER_CACHE_DIR}:/.composer/cache"
#- "${COMPOSER_CONFIG}:/.composer/config"
working_dir: /var/www/html
networks:
- laravel
npm:
image: node:13.7
user: "${HOST_UID}:${HOST_GID}"
volumes:
- "${PROJECT_DIR}:/var/www/html"
working_dir: /var/www/html
entrypoint: ['npm']
When I run whoami in the container, it returns:
whoami: cannot find name for user ID 1000
I think this is a problem because there is no home directory, docker-compose exec php ls ~ returns:
ls: cannot access '/home/clarg': No such file or directory
This then leads to docker-compose exec php php artisan tinker returning:
ErrorException
Writing to directory /.config/psysh is not allowed.
at vendor/psy/psysh/src/ConfigPaths.php:362
358▕ #\mkdir($dir, 0700, true);
359▕ }
360▕
361▕ if (!\is_dir($dir) || !\is_writable($dir)) {
➜ 362▕ \trigger_error(\sprintf('Writing to directory %s is not allowed.', $dir), \E_USER_NOTICE);
363▕
364▕ return false;
365▕ }
366▕
+20 vendor frames
21 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
From googling, I see this is in the home directory, which does not exist in the container.
How can I solve this?
EDIT:
Dockerfile-php:
FROM php:8.0-fpm
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions gd zip pdo_mysql
# check https://github.com/mlocati/docker-php-extension-installer#supported-php-extensions for more extensions
COPY --from=composer /usr/bin/composer /usr/bin/composer
php.ini
https://pastebin.com/T2iYTZz2
Your docker containers don't have any knowledge of the users that may or may not exist on the host machine, so unless you've built those in with their accompanying config and directory structure the only thing you're getting out of feeding docker your local UID and GID is "running the container as something other than root", which is good.
But generally you don't want to tie a docker container/image to the particular environment that it is launched from, eg: requiring a user with the same name as your local user exist within the container, plus all of its associated directories and such.
In this specific case it looks like artisan just wants to cache some config, and you can control where that lands with the environment variable:
XDG_CONFIG_HOME=/some/writeable/directory
Which you could set in the Dockerfile, docker-compose, or .env file of your project. I would suggest setting it to somewhere in your project directory, but outside of the docroot.
Ref: https://stackoverflow.com/a/62041096/1064767
This is well enough for local dev where you want to mount in your local work dir for testing, but will likely need a bit more consideration if you're going to build/deploy a final docker image.

Fetching picture from folder in PHP Docker

In my PHP application i am using docker on my ubuntu machine. Previously it was working perfectly but now its not. I am trying to show image from my uplaoded folder. The link showing the the image src is correct.Plus file also exist in folder but the image is not showing . When i try to access image directly from browser URL its saying
Forbidden
You don't have permission to access this resource.
Apache/2.4.38 (Debian) Server at localhost Port 80
My Dockerfile is
FROM php:7.3.28-apache
RUN docker-php-ext-install mysqli
RUN chown -R www-data /var/*
RUN chown -R 777 /var/*
RUN a2enmod rewrite
EXPOSE 80
everything is working fine but only the image is not coming in my browser.
You can see in the above pic image src is there but its showing blank and image is exist in the folder.Also i tried to change the permission to 777 but didnt worked.
sudo chmod -R 777 uploads
Docker Compose.yaml
version: '3.1'
services:
php:
container_name: php_medix_uk
depends_on:
- db
build:
context: .
volumes:
- .:/var/www/html/
- ./config/vhosts:/etc/apache2/sites-enabled
- ./config/php/php.ini:/usr/local/etc/php/php.ini
ports:
- "80:80"
restart: "always"
# MySQL
db:
image: mysql:8.0.25
container_name: mysql_host
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: medix_pharma
MYSQL_USER: medix_pharma
MYSQL_PASSWORD: medix_pharma
volumes:
- ~/mysql/medix_uk:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
ports:
- 3306:3306
# phpMyAdmin
phpmyadmin:
# container_name: phpmyadmin
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOSTS=mysql_host
- PMA_USER=root
- PMA_PASSWORD=root
ports:
- 8080:80
depends_on:
- db
inside ./config/vhosts directory i have default.conf file
DocumentRoot /var/www/html/
<Directory /var/www/html/>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Thanks

Apache / PHP Docker containers are just serving the PHP source files and not executing the PHP files correctly

I'm trying to run a Laravel app in my local environment via Docker. I want to setup separate containers for each service i.e. Apache, PHP, MySQL. I also want to keep Composer, Artisan and PHPUnit in separate containers as well. This is more for neatness than anything else.
All the containers spin up with no issues and I can access each one no problems via the 'docker-compose exec [container name] /bin/sh' command.
The problem I'm having is that the index.php in the public folder is not being executed correctly. Apache is just serving up the file contents.
I can't figure out what I'm doing wrong. I've tried using an Nginx container instead of Apache but I get the same issue. I'm guessing my Apache container does not recognize my PHP container.
Is there anything I'm doing wrong below?
My docker-compose.yml file is as follows:
version: '3.8'
networks:
cpw:
name: cpw_network
services:
apache:
build:
context: .
dockerfile: apache.dockerfile
container_name: cpw_apache
depends_on:
- php
- mysql
ports:
- 8080:80
- 8443:443
volumes:
- ./:/var/www/html
networks:
- cpw
php:
build:
context: .
dockerfile: php.dockerfile
container_name: cpw_php
volumes:
- ./:/var/www/html
networks:
- cpw
mysql:
image: mysql:5.7.32
container_name: cpw_mysql
environment:
MYSQL_DATABASE: cpw
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: secret
networks:
- cpw
composer:
image: composer:latest
container_name: cpw_composer
volumes:
- ./:/var/www/html
working_dir: /var/www/html
networks:
- cpw
artisan:
build:
context: .
dockerfile: php.dockerfile
container_name: cpw_artisan
volumes:
- ./:/var/www/html
working_dir: /var/www/html
entrypoint: [ "php", "artisan" ]
networks:
- cpw
phpunit:
build:
context: .
dockerfile: php.dockerfile
container_name: cpw_phpunit
volumes:
- ./:/var/www/html
working_dir: /var/www/html
entrypoint: [ "/var/www/html/vendor/bin/phpunit" ]
networks:
- cpw
My apache.dockerfile is as follows:
FROM httpd:alpine
ADD ./apache/httpd-vhosts.conf /usr/local/apache2/conf/extra/httpd-vhosts.conf
RUN sed -i 's,#Include conf/extra/httpd-vhosts.conf,Include conf/extra/httpd-vhosts.conf,g' /usr/local/apache2/conf/httpd.conf
RUN mkdir -p /var/www/html
My php.dockerfile is as follows:
FROM php:7.4.12-fpm-alpine
RUN mkdir -p /var/www/html
RUN apk --no-cache add shadow && usermod -u 1000 www-data
RUN docker-php-ext-install pdo pdo_mysql
My httpd-vhosts.conf is as follows:
<VirtualHost *:80>
ServerAdmin email#email.com
DocumentRoot /var/www/html/public
ServerName localhost
ServerAlias localhost
ErrorLog logs/localhost-error_log
CustomLog logs/localhost-access_log common
<Directory /var/www/html/public>
AllowOverride All
DirectoryIndex index.php index.php
Options -Indexes
Require all granted
</Directory>
</VirtualHost>
Any help appreciated.
Regards,
Stephen
Thanks for #NicoHaase for pointing me in the right direction.
This is the piece I was missing:
<FilesMatch \.php$>
SetHandler "proxy:fcgi://php-fpm-container:9000"
</FilesMatch>
More details here:
How to deploy php-fpm on docker container and apache/nginx on localhost (Ubuntu)
This might also fix:
<FilesMatch \.(?i:php)$>
SetHandler application/x-httpd-php
</FilesMatch>

docker php-fpm: the connection between services by port 9000 fails

I'm setting up a config to run my environment. I've a mysql, redis, nginx and php-fpm.
The services mysql and redis are ok, but when I start nginx and php my environment don't run.
The nginx config call to fastcgi_pass: php:9000
The error is:
[error] 6#6: *1 connect() failed (113: No route to host) while connecting to upstream, client: 192.168.224.1, server: ~.*, request: "POST /sellers HTTP/1.1", upstream: "fastcgi://192.168.224.4:9000", host: "127.0.0.1:8080"
My Dockerfile is:
FROM php:7.2-fpm-alpine
WORKDIR /app
# Install composer
RUN apk --update add curl && rm /var/cache/apk/*
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
RUN docker-php-ext-install pdo pdo_mysql
# Copy files
COPY . /app/
## THE LIFE SAVER
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait
RUN composer up
CMD /wait && bin/console doctrine:migrations:migrate
and my docker-compose is:
version: '3'
services:
mysql:
image: mysql:5.7
restart: unless-stopped
ports:
- '3306:3306'
environment:
MYSQL_ROOT_PASSWORD: database
MYSQL_DATABASE: cart
redis:
image: redis:alpine
ports:
- '6379:6379'
web:
image: nginx:latest
depends_on:
- php
ports:
- '8080:80'
volumes:
- .:/app
- ./docker/site.conf:/etc/nginx/conf.d/site.conf
php:
build:
context: .
depends_on:
- mysql
volumes:
- .:/app
environment:
- APP_ENV=prod
- APP_SECRET=aaaa
- DATABASE_URL=mysql://root:database#mysql:3306/cart
- REDIS_HOST=redis
- REDIS_PORT=6379
- WAIT_HOSTS= mysql:3306

Connect to MariaDB with localhost from Docker container

First of I did read thoses links
Connect to Docker MySQL container from localhost?
Connect to Mysql on localhost from docker container
From inside of a Docker container, how do I connect to the localhost of the machine?
But as a beginner with docker. It did not help me.
What you need to know:
Yes, I need localhost. I'm working on an app that interact
directly with the database. It create/remove user privileges and
allow some user to access with limited privileges from a remote
access. When initialized, the app will drop the default remote access to root and forge user and grant them full privilege on localhost.
I'm using a docker-compose.yml generated by https://phpdocker.io
Ubuntu 18.10
Docker version 18.09.3, build 774a1f4
docker-compose version 1.21.0, build unknown
I'm using docker only for development purpose. On production I use forge
./docker-compose.yml
###############################################################################
# Generated on phpdocker.io #
###############################################################################
version: "3.1"
services:
mailhog:
image: mailhog/mailhog:latest
container_name: myapp-mailhog
ports:
- "8081:8025"
redis:
image: redis:alpine
container_name: myapp-redis
mariadb:
image: mariadb:10.4
container_name: myapp-mariadb
working_dir: /application
volumes:
- .:/application
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=myapp
- MYSQL_USER=forge
- MYSQL_PASSWORD=forge
ports:
- "8083:3306"
webserver:
image: nginx:alpine
container_name: myapp-webserver
working_dir: /application
volumes:
- .:/application
- ./phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "8080:80"
php-fpm:
build: phpdocker/php-fpm
container_name: myapp-php-fpm
working_dir: /application
volumes:
- .:/application
- ./phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/7.3/fpm/conf.d/99-overrides.ini
./phpdocker/nginx/nginx.conf
server {
listen 80 default;
client_max_body_size 108M;
access_log /var/log/nginx/application.access.log;
root /application/public;
index index.php;
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}
}
./phpdocker/php-fpm/Dockerfile (slightly modified to add mysql_client and not installing git in a second RUN command)
FROM phpdockerio/php73-fpm:latest
WORKDIR "/application"
# Fix debconf warnings upon build
ARG DEBIAN_FRONTEND=noninteractive
# Install selected extensions and other stuff
RUN apt-get update \
&& apt-get -y --no-install-recommends install \
php7.3-mysql php-redis php7.3-sqlite3 php-xdebug php7.3-bcmath php7.3-bz2 php7.3-gd \
git \
mysql-client \
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
./php-ini-overrides.ini
upload_max_filesize = 100M
post_max_size = 108M
I tried to use network_mode: host but it makes the webserver stopping with Exit 1
Ok but as remember it, localhost in mysql/mariadb means access thru the local unix socket. There are ways of sharing these between containers.
Have a look here Connection between docker containers via UNIX sockets
#F.Maden gave me the right direction. I accepted his answer but here's how I made it in details.
Basically has he said, I need to share mysqld.sock between my services mariadb and php-fpm
The first step is to share a folder between both services. Since I already
have /application that contains the docker config /application/phpdocker, I will reuse this one.
I had to create a custom my.cnf file to edit the default mariadb config configuration and add a custom socket path:
./phpdocker/mariadb/my.cnf
[mysql]
socket = /application/phpdocker/shared/mysqld.sock
[mysqld]
socket = /application/phpdocker/shared/mysqld.sock
Then I had to share the config file with my mariadb container
./docker-compose.yml
mariadb:
image: mariadb:10.4
container_name: myapp-mariadb
working_dir: /application
volumes:
- .:/application
- ./phpdocker/mariadb/my.cnf:/etc/mysql/my.cnf # notice this line
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=myapp
- MYSQL_USER=forge
- MYSQL_PASSWORD=forge
ports:
- "8083:3306"
I created a folder ./phpdocker/shared with privileges 777 where mariadb will be able to create mysqld.sock (I couldn't start mariadb with 755. In my case this is only used on local not on production so it's fine)
From the terminal
$ mkdir ./phpdocker/shared && chmod 777 ./phpdocker/shared
And now test it!
From the terminal
$ docker-compose up -d --force-recreate --build
$ docker exec -it -u $(id -u):$(id -g) myapp-php-fpm /bin/bash
Once in the container
$ mysql -u root -p -h localhost --socket=/application/phpdocker/shared/mysqld.sock
$ mysql > select user();
+----------------+
| user() |
+----------------+
| root#localhost |
+----------------+
If the problem with connection to DB persists:
We can interogate what IP DB container has:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name>
We'll receive container IP (eg: 172.21.0.3);
After this, we can place this IP into connection "host" section.
Enjoy!
Ref How can I access my docker maria db?

Categories