I have three Docker containers running on Mac OS sierra, namely web, mysql and mongo, and have linked both mongo and mysql into web, which is essentially a Ubuntu Xenail base, with Apache and PHP added.
I am currently mounting my local Symfony project into the web container, and that seems to be working fine, but when I try to interact with the DB in any way, I get:
An exception occured in driver: SQLSTATE[HY000] [2002] Connection
refused
I've tried almost every combination of parameter values, but keep getting the same result.
I suspect it might have something to do with the way that I am linking the containers?
I'm in the process of learning Docker, so please excuse my limited knowledge.
Thanks!
Web dockerfile:
FROM ubuntu:xenial
MAINTAINER Some Guy <someguy#domain.com>
RUN apt-get update && apt-get install -y \
apache2 \
vim \
php \
php-common \
php-cli \
php-curl \
php-mysql \
php-mongodb \
libapache2-mod-php \
php-gd
RUN mkdir -p /var/www/symfony.local/public_html
RUN chown -R $USER:$USER /var/www/symfony.local/public_html
RUN chmod -R 755 /var/www
COPY config/php/php.ini /usr/local/etc/php/
COPY config/apache/sites-available/*.conf /etc/apache2/sites-available/
RUN a2enmod rewrite
RUN a2dissite 000-default.conf
RUN a2ensite symfony.local.conf
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Mysql dockerfile:
FROM mysql:5.7
MAINTAINER Some Guy <someguy#domain.com>
# Set the root users password
ENV MYSQL_ROOT_PASSWORD password
# Copy over the DB dump to be run upon creation
COPY sql/ /docker-entrypoint-initdb.d
# Copy over the custom mysql config file
COPY config/ /etc/mysql/conf.d
EXPOSE 3306
Run commands:
docker run --name mongo -d mongo #Im making use of the official Mongo image
docker run --name mysql -v /usr/local/var/mysql:/var/lib/mysql -d someguy/local:mysql
docker run --name web -d -p 80:80 --link mysql:mysql --link mongo:mongo -v ~/Sites/symfony.local/:/var/www/symfony.local/public_html/ someguy/local:web
Symfony parameters.yml file:
parameters:
database_host: mysql
database_port: 3306
database_name: gorilla
database_user: root
database_password: password
UPDATE:
So I've moved over to using docker-compose, but am still receiving the same error.
docker-compose.yml file
version: "2"
services:
web:
build: ./web
ports:
- "80:80"
volumes:
- ~/Sites/symfony.local/:/var/www/symfony.local/public_html/
depends_on:
- db
- mongo
mongo:
image: mongo:latest
mysql:
image: mysql:latest
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: password
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused
Means, it has nothing to do with your network per se - the links are just fine.
What you are lacking is the how the user has been created, if the user has been created https://github.com/docker-library/mysql/blob/c207cc19a272a6bfe1916c964ed8df47f18479e7/5.7/docker-entrypoint.sh#L122 .. so actually without a host limitation per se.
The question in your case is, what is inside your "sql/" folder - those scripts are executed during the entrypoint.
Be sure to never use exitX in those scripts, they will interrupt the main script, see https://github.com/docker-library/mysql/blob/c207cc19a272a6bfe1916c964ed8df47f18479e7/5.7/docker-entrypoint.sh#L151
Check your docker logs for mysql to ensure the script did not print you any warnings, use https://github.com/docker-library/mysql/blob/c207cc19a272a6bfe1916c964ed8df47f18479e7/5.7/docker-entrypoint.sh as an reference.
And last but not least, please use docker-compose. If you have issues with the timings ( mysql starting to slow and your web-container freaks out ), use a "wait for mysql" entrypoint in web:
#!/bin/bash
# this script does only exist to wait for the database before we fire up tomcat / standalone
RET=1
echo "Waiting for database"
while [[ RET -ne 0 ]]; do
sleep 1;
if [ -z "${db_password}" ]; then
mysql -h $db_host -u $db_user -e "select 1" > /dev/null 2>&1; RET=$?
else
mysql -h $db_host -u $db_user -p$db_password -e "select 1" > /dev/null 2>&1; RET=$?
fi
done
Set db_host, $user, $pasword accordingly using ENV or whatever suits you.
Related
I'm trying to create a Docker container (using docker-compose) for an application wit Doctrine, the problem is: if I just run the application, it works, but when I try to use the application before I run command ./vendor/bin/doctrine orm:generate-proxies, I get the error:
PHP Warning: require(/tmp/__CG__DomainEntitiesAnyEntity.php): failed to open stream: No such file or directory in /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 204
PHP Fatal error: require(): Failed opening required '/tmp/__CG__DomainEntitiesAnyEntity.php' (include_path='.:/usr/local/lib/php') in /var/www/html/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 204
OK, so just run the command on docker-compose.yml
version: '3'
services:
apache_server:
build: .
working_dir: /var/www/html
ports:
- "80:80"
volumes:
- ./:/var/www/html
- ../uploads:/var/www/uploads
- ./.docker/apache2.conf:/etc/apache2/apache2.conf
- ./.docker/000-default.conf:/etc/apache2/sites-avaliable/000-default.conf
- ./.docker/php.ini:/etc/php/7.4/apache2/php.ini
depends_on:
- postgres_database
command: sh -c "./vendor/bin/doctrine orm:generate-proxies"
networks:
- some-network
Yes, it works as expected and generates the proxies to /tmp folder, but after the command run and after the prompt with proxies generated, I get the message exited with code 0. It happens because Docker finish the container execution after getting the status code 0. So I tried two more things:
Add tail to something:
command: sh -c "./vendor/bin/doctrine orm:generate-proxies && tail -f /var/www/html/log.txt"
but when I do this, the server doesn't respond to requests (http://localhost/) anymore.
Add tty before running the command:
tty: true
# restart: unless-stopped <--- also tried this
and doesn't work also. Is there another way to solve this without I have to manually run the command inside the container every time?
PS: my dockerfile is this one:
FROM php:7.4-apache
WORKDIR /var/www/html
RUN a2enmod rewrite
RUN a2enmod headers
RUN mkdir /var/www/uploads
RUN mkdir /var/www/uploads/foo-upload-folder
RUN mkdir /var/www/uploads/bar-upload-folder
RUN chmod 777 -R /var/www/uploads
RUN apt-get update \
&& apt-get install -y \
libpq-dev \
zlib1g-dev \
libzip-dev \
unzip \
&& docker-php-ext-install \
pgsql \
pdo \
pdo_pgsql \
zip
RUN service apache2 restart
Cause of your issue
Your Docker Compose configuration of command
command: sh -c "./vendor/bin/doctrine orm:generate-proxies"
in docker-compose.yml overwrites the Cmd in the Docker image php:7.4-apache that normally would start the Apache server, see
docker inspect php:7.4-apache
or more specific
docker inspect --format="{{ .Config.Cmd }}" php:7.4-apache
which gives you
[apache2-foreground]
Solution in general
If you like to run a command before the original command of a Docker image, use Entrypoint and make sure you call the original entrypoint, see
$ docker inspect --format="{{ .Config.Entrypoint }}" php:7.4-apache
[docker-php-entrypoint]
For example, instead of command define
entrypoint: sh -c "./vendor/bin/doctrine orm:generate-proxies && docker-php-entrypoint"
Solution in your case
However, in your case, I would configure Doctrine like this (see Advanced Doctrine Configuration)
$config = new Doctrine\ORM\Configuration;
// ...
if ($applicationMode == "development") {
$config->setAutoGenerateProxyClasses(true);
} else {
$config->setAutoGenerateProxyClasses(false);
}
In development your code changes (mounted as volume) and proxies may have to be updated/generated. In production your code does not change anymore (copy code to Docker image). Hence, you should generate proxies in your Dockerfile (after you copied the source code), e.g.
FROM php:7.4-apache
WORKDIR /var/www/html
# ...
Copy . /var/www/html
RUN ./vendor/bin/doctrine orm:generate-proxies
I created a docker container from mysql:5.7 image.
sudo docker run --name mysqltest -e MYSQL_ROOT_PASSWORD=password -v mysql:/var/lib/mysql -d mysql:5.7
And I Created a php container that included phpunit
sudo docker run --rm -v $(pwd):/app -w /app phpunit/phpunit:8 phpunit --testdox file.php
in file.php I'm trying to connect mysql container, via mysql container ip as host:
sudo docker inspect mysqltest
but still I get "connection Refused", but I can connect to mysql container directly via :
sudo docker exec -it mysqltest mysql -ppassword
Please Help me, I'm really confused !
The connection is refused as you are not exposing MySQL ports, so it is not seen by the host and the other containers. The proper way of handling these cases is by using docker-compose and custom docker networks, however, the following changes can act as a quick-fix:
sudo docker run --name mysqltest -p 3306:3306 --network=host -e MYSQL_ROOT_PASSWORD=password -v mysql:/var/lib/mysql -d mysql:5.7
Followed by:
sudo docker run --network=host --rm -v $(pwd):/app -w /app phpunit/phpunit:8 phpunit --testdox file.php
-p 3306:3306 tells Docker to map default port of MySQL inside the container to port 3306 of the host. --network=host directs docker to use your local machine network stack. You can verify MySQL being accessible by trying to connect to it from your machine on port 3306 with any of its client applications.
Note that you need to update your application configurations to use the MySQL database on localhost.
I got a docker-compose setup with two containers: One is the php/apache service and the other container is the database (mysql).
Here is my docker-compose.yml
version: '2'
services:
app:
depends_on:
- db
links:
- db:mysql
build: .
image: app
ports:
- "80:80"
restart: always
links:
- db:db
volumes:
- ../:/var/www/html/
db:
image: mysql:latest
restart: unless-stopped
volumes:
- ./db_data:/var/lib/mysql
- ./databaseDumps:/tmp/databaseDumps
environment:
MYSQL_USER: "myApp"
MYSQL_PASSWORD: "root"
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "myAppDatabase"
MYSQL_ROOT_HOST: "%"
And here is my app Dockerfile:
FROM php:7-apache
COPY prefilled_files/000-default.conf /etc/apache2/sites-available/000-default.conf
RUN apt-get -qq update
RUN apt-get -qq -y install libpng-dev curl git nano vim zip unzip mysql-client libmysqlclient-dev
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
RUN apt-get install -y nodejs
RUN npm install -g bower
RUN npm install -g gulp
RUN docker-php-ext-install pdo pdo_mysql gd mysqli
EXPOSE 8080 80
The main problem is, the mysql database and the app container working well, and I can connect to the mysql database from the app container via
$root#app: mysql -h db -u myApp -p
BUT
if I try to execute composer install on my symfony project, following error message appears:
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000] [2002] Connection refused
[PDOException]
SQLSTATE[HY000] [2002] Connection refused
Here are my parameters of my app:
parameters:
database_driver: pdo_mysql
database_host: db
database_port: 3306
database_name: myAppDatabase
database_user: myApp
database_password: root
Why is this happening?
I've read through several forums and sites but nothing helped.
I tried the following solutions and nothing helped:
clearing symfony cache ;)
expose 3306 on mysql container
link app and mysql container together
removing all images and containers from my computer and reinstalled everything
I tried on windows and on ubuntu 17.04. Same behavior
connecting to a docker-compose mysql container denies access but docker running same image does not
docker-compose wordpress mysql connection refused
UPDATE:
I tried to access my database with a little php script from https://gist.github.com/chales/11359952 . PHP/My Script can actually connect to the database, so the problem has to be in with my composer install or in doctrine or in my configuration of symfony.
tl;dr
2 Docker container via docker compose
I can access the database via mysql command on the app container but not over composer install. Why?
I think it's the way it's trying to find the container via the host name 'db', I've found that on the machine running docker, it doesn't seem to pick up the names of the guest containers (could be some DNS config you could change) but the way I've worked round it is to find the IP address of the MySQL container. I have docker_db_1 as the container name for MySQL, so I run (assuming *nix)
docker inspect docker_db_1 | grep IPAddress
Which in my case gives me
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.18.0.2",
And I use this IP address (172.18.0.2) to connect to rather than db.
I need to install cURL compiled with OpenSSL and zlib via Dockerfile for Debian image with apache and php 5.6. I tried many approaches but due to the fact that I don't have string understanding in Linux a failed. I use docker-compose to up my container. docker-compose.yaml looks like:
version: '2'
services:
web:
build: .
command: php -S 0.0.0.0:80 -t /var/www/html/
ports:
- "80:80"
depends_on:
- db
volumes:
- $PWD/www/project:/var/www/html
container_name: "project-web-server"
db:
image: mysql:latest
ports:
- "192.168.99.100:3306:3306"
container_name: "project-db"
environment:
MYSQL_DATABASE: dbname
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpass
MYSQL_ROOT_PASSWORD: dbpass
As a build script I use Dockerfile:
FROM php:5-fpm
RUN apt-get update && apt-get install -y \
apt-utils \
curl libcurl3 libcurl3-dev php5-curl php5-mcrypt
RUN docker-php-ext-install -j$(nproc) curl
'docker-php-ext-install' is a helper script from the base image https://hub.docker.com/_/php/
The problem is that after $ docker build --rm . which is successful a don't get an image with cURL+SSL+zlib. After $ docker-compose up I have a working container with Apache+MySQL and can run my project but libraries I need are not there.
Could you explain how to add these extensions to my apache in container properly? I even tried to create my own Dockerfile and build apache+php+needed libs there, but had no result.
Your Dockerfile is not complete. You have not done a COPY (or similar) to transfer your source code to execute from the host into the container. The point of a Dockerfile is to setup an environment together with your source code which finishes by launching a process (typically a server).
COPY code-from-some-location into-location-in-container
CMD path-to-your-server
... as per the URL you reference a more complete Dockerfile would appear like this
FROM php:5.6-cli
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
CMD [ "php", "./your-script.php" ]
notice the COPY which recursively copies all files/dirs (typically the location of your source code, etc like data and/or config files) in your $PWD where you execute the command onto the specified location internal to the container In unix a period as in . indicates the current directory so above command
COPY . /usr/src/myapp
will copy all files and directories in current directory from the host computer (the one you are using when typing in the docker build command) into the container directory called /usr/src/myapp
the WORKDIR acts to change directories into your container's dir supplied
finally the CMD launches the server which hums along once your launch the container
I created a Docker container with Apache on it. Everything works, except that I can't link MySQL (https://hub.docker.com/_/mysql/) to my container, and I'm not sure what I did wrong.
Here are the steps I did:
I run mysql server container
docker run --name mysqlserver -e MYSQL_ROOT_PASSWORD=pass123 -d mysql/mysql-server:latest
Then, I run and link my Apache Docker:
docker run -it --link mysqlserver:mysql -v "$(pwd)":/var/www/html -p 80:80 -p 3306:3306 apachebash
But I cant access MySQL.