How to connect to services running in different docker stack? - php

Can a services running in two different docker stack communicate ?
This is what I have tried and not able to achieve it.
Created a stack (stack1) running nginx and php-fpm its running great.
Created another stack (stack2) running mysql database.
Now I want to make the stack1 service able to communicate with stack2 such that it can access the database service.
I though this might help and created a external network and trying to
add the service in stack1 and stack2 to it such that they can
communicate with each others too
Mystack1 docker-compose file
version: "3.4"
networks:
apps-net:
db-net:
external:
name: db-net
services:
web:
image: nginx:latest
ports:
- "9080:80"
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
networks:
- apps-net
- db-net
deploy:
mode: replicated
replicas: 1
php:
image: php:7-fpm
volumes:
- ./code:/code
networks:
- apps-net
- db-net
deploy:
mode: replicated
replicas: 1
MY stack2 docker-compose file
version: '3.3'
networks:
db-net:
external:
name: db-net
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: root
MYSQL_PASSWORD: password
networks:
- db-net
volumes:
db_data:
I created a swarm scope network with docker network create db-net command
OUTPUT:
The nginx and php is working fine but I added the database connection
codes in the index.php which resulted in error message.Is the error
because they are not connected? I have installed php-mysql extensions
too but it has the error. How can I make sure the services are
communicating successfully.
nginx and php working
Fatal error: Uncaught Error: Call to undefined function mysqli_connect() in /code/index.php:11 Stack trace: #0 {main} thrown in /code/index.php on line 11

Instead of networks (which I often see asked here on stack as not working like expected) try using external_links which is well explained here.
Try removing all custom network configurations and simply modify your application compose file like this:
version: "3.4"
# removed all custom networks configuration
services:
web:
image: nginx:latest
external_links:
- mysql_1:mysql
[..]
php:
image: php:7-fpm
external_links:
- mysql_1:mysql
[..]
where mysql_1 is a actual container name create by your latter compose file, and mysql is a alias by which your service will be available inside php and web containers
Links are a legacy option in v3 and Docker suggests using networks instead.
I'll post a edit about swarm deployment as approach would be totally different because Docker ignores links when deploying swarm.

Related

Laravel 9 test dusk does not work on Docker with selenium/standalone-chrome

I installed dusk based on the laravel document, but I can't run a test dusk on docker interactive mode. I searched the web without finding the correct configuration.
This is a part of the docker-compose file:
services:
php-apache:
build:
context: .
container_name: app_php
ports:
- '8081:80'
volumes:
- ./core:/var/www/app
- ./apache/default.conf:/etc/apache2/sites-enabled/000-default.conf
links:
- selenium
depends_on:
- database
networks:
- mysite
selenium:
image: selenium/standalone-chrome:104.0
container_name: selenium
ports:
- "4444:4444"
networks:
- mysite
And this is the error I get:
1) Tests\Browser\ExampleTest::testBasicExample TypeError: Facebook\WebDriver\Remote\DesiredCapabilities::__construct(): Argument #1 ($capabilities) must be of type array, null given, called in /var/www/app/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php on line 648
I've put in two days to solve the problem. I would appreciate it if anyone could help me.
On your duskTestCase.php file, on the driver function, add these 2 lines to the options:
'--whitelisted-ips=""',
'--disable-dev-shm-usage'
1st line to allow the containers to communicate, 2nd to solve issue on dev-shm mount reference: https://github.com/SeleniumHQ/docker-selenium/issues/1267
also on the same driver function, the url must be pointing to your selenium container:
return RemoteWebDriver::create(
'http://selenium:4444/wd/hub',

Link between symfony and docker

I'm on a symfony project and i'm using docker here's my docker-compose.yml :
version: '3.7'
services:
db:
image: mysql:latest
container_name: ruakh_db
restart: always
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
networks:
- dev
phpmyadmin:
image: phpmyadmin:latest
container_name: ruakh_phpmyadmin
restart: always
depends_on:
- db
ports:
- 8080:80
environment:
PMA_HOST: db
networks:
- dev
maildev:
image: maildev/maildev
container_name: ruakh_mail_dev
restart: always
command: bin/maildev --web 80 --smtp 25 --hide-exetensions STARTTLS
ports:
- 8081:80
networks:
- dev
apache:
build: php
container_name: ruakh_www
ports:
- 8088:80
volumes:
- ./php/vhosts:/etc/apache2/sites-enabled
- ./:/var/www
restart: always
networks:
- dev
networks:
dev:
volumes:
db-data:`
here's the database url used in my symfony project :
DATABASE_URL=mysql://root:root#ruakh_db/ruakh
I'm trying to run a php bin/console make:migration however when i'm running I get this error :
An exception occurred in driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution
I'm assuming that the database url is incorrect, when I changed it to :
DATABASE_URL=mysql://root:root#127.0.0.1:8080/ruakh
This error is thrown:
An exception occurred in driver: SQLSTATE[HY000] [2006] MySQL server has gone away
How can I manage to connect my symfony project to my docker database ?
There is a couple things wrong with your DATABASE_URL.
DATABASE_URL=mysql://root:root#ruakh_db/ruakh
You don't set the password in your service config
You have the wrong host name
You don't specify the database
You are using native authentication, which must be enabled when using MySQL 8
(optional) your database port is not exposed
Password
In your docker-compose.yml. you do not specify the root password and instead allow for an empty password. You can set the root password using an environment variable:
services:
db:
...
environment:
MYSQL_ROOT_PASSWORD: example
Database name
In order to create a default database named ruakh you need to provide another environment variable MYSQL_DATABASE.
Host
The next issue is the host name in your DATABASE_URL: ruakh_db. This is the name of the container, but not the name of the service (i.e. the host in the virtual network that docker-compose sets up). This should be db instead.
Port
You will not be able to access your mysql database from outside the docker container, because you do not expose any ports. That is not necessarily an issue, but you should be aware of it. Looking at your other database url DATABASE_URL=mysql://root:root#127.0.0.1:8080/ruakh this will not work, because the port 8080 is for the web interface provided by phpmyadmin. It is not the port of the actual database. Also, the port for the database is not exposed. You probably want to add:
services:
db:
...
ports:
- 3306:3306
Authentication
Another issue, you will face is using the image mysql:latest this will use MySQL 8.0 which does not allow the authentication mechanism you want to use by default. You will have to change the command executed when running the container or downgrade to MySQL 5.7. If you want to keep MySQL 8, you should add this:
services:
db:
...
command:
- 'mysqld'
- '--character-set-server=utf8mb4'
- '--collation-server=utf8mb4_unicode_ci'
- '--default-authentication-plugin=mysql_native_password'
Summary
This is roughly what your db service should look like to work with your DATABASE_URL:
db:
image: mysql:latest
ports:
- '3306:3306'
environment:
MYSQL_DATABASE: ruakh
MYSQL_ROOT_PASSWORD: 'root'
command:
- 'mysqld'
- '--character-set-server=utf8mb4'
- '--collation-server=utf8mb4_unicode_ci'
- '--default-authentication-plugin=mysql_native_password'

Cannot connect Wordpress on external dbgetaddrinfo failed: Name or service not known

I would like to run my Wordpress site on Docker, and I want to connect the Wordpress database to another container which have only the databases of all my sites.
For doing so, I've created a LAMP container using the following docker-compose.yml:
version: "3"
services:
web:
image: webdevops/php-apache:alpine-php7
ports:
- "4500:80"
volumes:
- ./www:/app
- ./uploads.ini:/opt/docker/etc/php/php.ini
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "8088:80"
as you can see I've installed Apache as service using the webdevops image, this return the following:
Then, I've created a new container which have the Wordpress instance:
version: '3'
services:
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- ./wp/wp-content:/var/www/html/wp-content
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: lamp_db_1:3306
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root
volumes:
dbdata:
wp-content:
as you can see I mount the wp-content folder since I already have a Wordpress installation with plugins and media... then I tried to connect this container to lamp_db_1 container but when I run this using:
docker-compose up --build
I get:
MySQL Connection Error: (2002) php_network_getaddresses: getaddrinfo failed: Name or service not known
what I did wrong?
How can I connect the wordpress container to the LAMP container?
You can specify a custom network in your LAMP stack and have your Wordpress stack and other containers defined in other Compose files use this network by using network.external parameter in Compose.
Being on the same network, you'll be able to join your lamp_db container using it's container name as hostname.
A complete example:
docker-compose.yml for LAMP stack:
version: '3.5'
services:
db:
# This will be the hostname for your DB container on the network
container_name: lamp_db
image: mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
# Have db container join our db network
networks:
- db_network
# Ensure our custom network is managed by this stack
networks:
db_network:
name: db_network
docker-compose.yml for Wordpress stack:
version: '3.5'
services:
wordpress:
image: wordpress:latest
ports:
- "8000:80"
environment:
# Name of the db container
WORDPRESS_DB_HOST: lamp_db:3306
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root
# Have wordpress container join our db network
networks:
- db_network
# Declare db_network as external with it's name
# Network won't be created by this stack but must exists before running
# See https://docs.docker.com/compose/compose-file/#external-1
networks:
db_network:
external: true
name: db_network
And a generic example any service that would need to use our database:
version: '3.5'
services:
some_container:
image: some-image:latest
# Have this container join our db network
networks:
- db_network
# Note: make sure to reference db container by it's hostname lamp_db
networks:
db_network:
external: true
name: db_network
Notes:
db_network is managed via LAMP stack. When uping the LAMP stack, Docker Compose will ensure this network is created. Other stacks using this network should declare it as external: true with it's name
You'll need version: '3.5' or more to be able to use network.name config
It seems the reason you are running into this issue is due to the fact that you have two separate services. One contains your LAMP stack and the other contains your wordpress image.
When you run docker-compose it sets up a single network for your app. Thus your wordpress image isn't on the same network as your LAMP stack.
You can add your wordpress container to your LAMP docker-compose.yml file such as
version: "3"
services:
web:
image: webdevops/php-apache:alpine-php7
ports:
- "4500:80"
volumes:
- ./www:/app
- ./uploads.ini:/opt/docker/etc/php/php.ini
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "8088:80"
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- ./wp/wp-content:/var/www/html/wp-content
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root
volumes:
dbdata:
wp-content:
And unless you are doing something specific with your php-apache image you can actually remove it at this point.
Another approach you could take if you do not want everything in the same docker-compose file is that you can manually define the networks and get your containers to join them. The answers on this question show how to do that fairly easily.

Docker SQLSTATE[08006] for pgsql service only from php service

Not sure if my title is accurate, but here's my issue. I am running a basic laravel site on Docker and cannot get the site itself to connect to the PostgreSQL service. I will post my docker-compose.yml below. When i run php artisan migrate i get no errors and it all works. I can even use my Postico PostgreSQL client to connect to the DB and run queries. But, when i try and connect to the DB from the site, it errors out saying this:
SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5433?
Here are my PostgreSQL client settings (which DO work):
Host: 127.0.0.1
Port: 5433
User: homestead
Password: homestead
Database: homestead
I have been messing around with different settings and things so here is my docker-compose.yml, although i'm sure there are things i don't need in there:
version: '2'
services:
php:
image: jguyomard/laravel-php:7.2
build:
context: .
dockerfile: infrastructure/php/Dockerfile
volumes:
- ./:/var/www/
- $HOME/.composer/:$HOME/.composer/
networks:
- default
links:
- postgresql
- redis
nginx:
image: jguyomard/laravel-nginx:1.13
build:
context: .
dockerfile: infrastructure/nginx/Dockerfile
ports:
- 81:80
networks:
- default
links:
- postgresql
- redis
postgresql:
image: postgres:9.6-alpine
volumes:
- pgsqldata:/var/lib/postgresql/data
environment:
- "POSTGRES_DB=homestead"
- "POSTGRES_USER=homestead"
- "POSTGRES_PASSWORD=homestead"
ports:
- "5433:5432"
networks:
- default
redis:
image: redis:4.0-alpine
command: redis-server --appendonly yes
ports:
- "6379:6379"
networks:
- default
# elastic:
# image: elasticsearch:5.5-alpine
# ports:
# - "9200:9200"
volumes:
pgsqldata:
networks:
default:
Any thoughts on why the site can't connect to the DB?
My docker network ls output:
NETWORK ID NAME DRIVER SCOPE
2bf85424f466 bridge bridge local
c29d413f768e host host local
0bdf9db30cd8 none null local
f3d9cb028ae3 my-app_default bridge local
The error message ask Is the server running on host "127.0.0.1" but in your case PostgreSQL is running on a different docker container which is not 127.0.0.1 reference to php app so, change the server host to postgresql inside your php application.
And for the modified error, it is because that you have used port 5433 inside the php application which is the port of host machine which is for use outside the docker container (for host machine, that's why your Postico PostgreSQL client worked). But the port you have to use inside the docker network is 5432 change the server port to 5432 inside your php application.
And you have made the compose file complex by defining network in each host as default network. (You can follow this link for more details) If you don't have a requirement for that you don't need to do that as docker-compose will deploy all containers in single network.
And you don't need to use links they are deprecated. When multiple containers are in one docker-compose.yml file they are automatically deployed in a same single network.
So this simplified compose file will be recommended.
version: '2'
services:
php:
image: jguyomard/laravel-php:7.2
build:
context: .
dockerfile: infrastructure/php/Dockerfile
volumes:
- ./:/var/www/
- $HOME/.composer/:$HOME/.composer/
nginx:
image: jguyomard/laravel-nginx:1.13
build:
context: .
dockerfile: infrastructure/nginx/Dockerfile
ports:
- 81:80
postgresql:
image: postgres:9.6-alpine
volumes:
- pgsqldata:/var/lib/postgresql/data
environment:
- "POSTGRES_DB=homestead"
- "POSTGRES_USER=homestead"
- "POSTGRES_PASSWORD=homestead"
ports:
- "5433:5432"
redis:
image: redis:4.0-alpine
command: redis-server --appendonly yes
ports:
- "6379:6379"
# elastic:
# image: elasticsearch:5.5-alpine
# ports:
# - "9200:9200"
volumes:
pgsqldata:

docker-php environment with docker-compose.yml and links error

I am trying to setup a development environment for upgrading old php applications with docker. I've tried to create a docker-compose.yml file with the following content:
version: "3"
services:
mysql:
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=dev
- MYSQL_USER=dev
- MYSQL_PASSWORD=dev
- MYSQL_DATABASE=todo
volumes:
- ./storage/mysql:/var/lib/mysql
nginx:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./../src:/var/www
- ./site.conf:/etc/nginx/conf.d/site.conf
links:
- php
php:
image: tommylau/php-5.2
volumes:
- ./../src:/var/www
depends_on:
- mysql
There may be additional issues within my yml file but at first i'm facint two problems here:
1) what about links?
when using
$ docker stack deploy -c docker-compose.yml phpdev
i'm getting the following output saying the links option is unssupported and i don't see why
Ignoring unsupported options: links
Creating network phpdev_default
Creating service phpdev_nginx
Creating service phpdev_php
Creating service phpdev_mysql
2) nothing on localhost:8080
any hints on solving my two problems?

Categories