Zephyr
Zephyr

Reputation: 1598

Symfony + Docker, connection refused

I'm seasoned in Symfony but quite new to docker, and I have a "connection refused error" I don't manage to solve.

Pretty sure it is a beginner error and that the solution here is quite simple...

Here is the content of my docker-compose file:

version: '3.2'

services:
    cg-demo:
        build: docker/cg-demo
        container_name: cg-demo
        working_dir: /var/www/html
        volumes:
            - .:/var/www/html
            - ./docker/demo/vhost.conf:/etc/apache2/sites-available/000-default.conf:ro
            - ./docker/demo/php.ini:/usr/local/etc/php/php.ini:ro
            - ~/.ssh:/var/www/.ssh
            - ~/.composer:/var/www/.composer
        environment:
            - SYMFONY_ENV
            - DOMAIN_NAME: cg-demo.docker
            - VIRTUAL_HOST: cg-demo.docker
        depends_on:
            - database
        env_file: .env
        ports:
            - 8000:80

    database:
        image: percona:5.6
        ports:
            - 3306:3306
        expose:
            - 3306
        container_name: cg-demo-database
        volumes:
            - /docker/database:/etc/mysql/conf.d
        environment:
            MYSQL_ROOT_PASSWORD: root
            MYSQL_DATABASE: demo
        tmpfs:
            - /var/lib/mysql
            - /tmpfs:size=300M

This has been based from another project that works, but I'm not sure of all that's happening here...

I also have a phpmyadmin container, not shown here. PhpMyAdmin connects correctly to the database and can use it without problem from any web server. However when it comes to the symfony container, I have this whenever trying to use the database:

[Doctrine\DBAL\Exception\ConnectionException]
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused   

[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000] [2002] Connection refused

[PDOException]
SQLSTATE[HY000] [2002] Connection refused

The connection information is the following, in a .env file:

# Database credentials
DATABASE_HOST=database
DATABASE_PORT=3306
DATABASE_USER=root
DATABASE_PASSWORD=root
DATABASE_DB=cg-demo

Calling docker ps gives me this:

CONTAINER ID        IMAGE                 COMMAND               
CREATED             STATUS                    PORTS                  NAMES
16a67dadeebb        phpmyadmin/phpmyadmin "/run.sh phpmyadmin"     15 minutes ago      Up 15 minutes             0.0.0.0:8001->80/tcp   cg.phpmyadmin.docker
8bd783aa1dd1        cg_cg-demo            "entrypoint.sh apa..."   15 minutes ago      Up 15 minutes             0.0.0.0:8000->80/tcp   cg-demo
2fc7cd9105ba        percona:5.6           "docker-entrypoint..."   15 minutes ago      Up 15 minutes (healthy)   3306/tcp               cg-database

I've tried to ping database from the demo container and it works...

EDIT 1:

Added the following to the database container:

ports:
    - 3306:3306

EDIT 2:

Removed the following from all containers:

networks:
    - default

EDIT 3:

My doctrine configuration in app/config/config.yml:

dbal:
    host:     "%env(DATABASE_HOST)%"
    port:     "%env(DATABASE_PORT)%"
    dbname:   "%env(DATABASE_DB)%"
    user:     "%env(DATABASE_USER)%"
    password: "%env(DATABASE_PASSWORD)%"
    charset: UTF8
    mapping_types:
        enum: string
    server_version: 5.6

EDIT 4:

Added the following to the database configuration:

expose:
    - 3306

Upvotes: 2

Views: 5152

Answers (1)

famas23
famas23

Reputation: 2280

This answer is for docker-compose version 2 and it also works on version 3:

The problem is a Linking Containers problem. We need to define additional aliases that services can use to reach one another.

Expose 3306 port will not solve your problem. mysql or percona container will expose by deffault that port. Take a look to the docker hub of percona image. . It's mentioned there:

Connect to MySQL from an application in another Docker container

This image exposes the standard MySQL port (3306), so container linking makes the MySQL instance available to other application containers. Start your application container like this in order to link it to the MySQL container:

$ docker run --name some-app --link some-percona:mysql -d application-that-uses-mysql

So, you should links the database to you cg-demo container. There's tow solutions:

1) Add a link under configuration :

services:
    cg-demo:
        build: docker/cg-demo
        container_name: cg-demo
    .
    .
    .
    links:
    - mysql

The diffirence between depeds_on and links is that depends_on docker-compose up will start services in dependency order. In your following example, database will be started before web.
We can also access data. But this is not enough, because we want to make sure that your web container (cg-demo) always connect to the database container.
Links allow you to define extra aliases by which a service is reachable from another service. In the following example, database is reachable from web (cg-demo) at the hostname database. This means that thecg-demo can connect the database contanier from the 3306 port.

2) The second solution, is to configure the default network instead of (or in addition to) customizing your own network. Simply define a default entry under networks:

networks:
  bridge_name:
    driver: bridge

And then you should link every container to that bridge via networks tag:

cg-demo:
  .
  .
  networks:
    - bridge_name

database:
  .
  .
  networks:
    - bridge_name

Upvotes: 1

Related Questions