after looking for an answer 2 weeks along, going deep into the docker compose and docker networks documentations, I'd like to ask for some help right here.
I am creating two Web API services, let's called them a back API (back.api.dev) and a front API (front.api.dev).
What I tried so far :
The back API is connected to a MySQL database, and the front API only sends cURL requests to the back API. Both APIs are built upon Symfony and are processed by a docker PHP-FPM container. Everything is served by a docker Apache 2.4 container.
Sending requests through Postman and cURL requests to back.api.dev & front.api.dev are both working great. It works both from my host, but also from the Apache container. I also added 127.0.0.1 back.api.dev and 127.0.0.1 front.api.dev to my /etc/hosts host machine file. The back API is well connected to the database as well.
But when I send a request to a specific front API route which runs a cURL request to the back API using GuzzleHTTP client and send the answer back to the user, I get a cURL error 7: Failed to connect to back.api.dev port 80: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://back.api.dev/api/videos/
I also tried to send cURL requests from the CLI inside the front_api container but the result is the same. I also tried to send it directly to the port 9000 handled by php-fpm but I get a cURL error 56: Recv failure: Connection reset by peer error.
Here's the docker-compose.yml file :
version: "3.8"
networks:
my_api_network:
driver: bridge
# external:
# name: my_api_network_default
services:
apache:
container_name: 'api_apache'
image: bitnami/apache:latest
ports:
- 8080:8080
# - 8443:8443
volumes:
- ./docker/apache/vhosts/back-api-dev.conf:/vhosts/back-api-dev.conf:ro
- ./docker/apache/vhosts/front-api-dev.conf:/vhosts/front-api-dev.conf:ro
volumes_from:
- php_backend_api
- php_frontend_api
depends_on:
- php_backend_api
- php_frontend_api
networks:
- my_api_network
php_backend_api:
hostname: 'back.api.dev'
container_name: 'php_backend_api'
build:
context: docker/php7-fpm
network: host
args:
TIMEZONE: 'UTC'
volumes:
- ./docker/php7-fpm/php.ini:/usr/local/etc/php/php.ini:ro
- ./back_api/:/var/www/back_api:cached
- ./back_api/vendor:/var/www/back_api/vendor:delegated
- /var/www/back_api/var/
networks:
- my_api_network
php_frontend_api:
hostname: 'front.api.dev'
container_name: 'php_frontend_api'
build:
context: docker/php7-fpm
network: host
args:
TIMEZONE: 'UTC'
volumes:
- ./docker/php7-fpm/php.ini:/usr/local/etc/php/php.ini:ro
- ./front_api/:/var/www/front_api:cached
- ./front_api/vendor:/var/www/front_api/vendor:delegated
- /var/www/front_api/var/
networks:
- my_api_network
db:
container_name: 'mysql_db'
image: mysql:5.7
restart: always
volumes:
- ./docker/data/mysql:/var/lib/mysql:delegated
- ./docker/mysql:/etc/mysql/conf.d:ro
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
TZ: ${TIMEZONE}
command: --sql_mode="STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER" --default-authentication-plugin=mysql_native_password
ports:
- 3306:3306
networks:
- my_api_network
Here is my back API Apache Virtualhost :
<VirtualHost *:8080>
ServerName back.api.dev
DocumentRoot "/var/www/back_api/public"
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php_backend_api:9000/var/www/back_api/public/$1
<Directory "/var/www/back_api/public">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
</IfModule>
</Directory>
LogLevel debug
# LogLevel warn
# LogLevel notice
ErrorLog /opt/bitnami/apache2/logs/error-back.log
CustomLog /opt/bitnami/apache2/logs/access-back.log combined
</VirtualHost>
My guess is that Apache is not enough configured to forward incoming curl requests to the php-fpm instance. I looked after Docker networks, aliases, drivers, extra_hosts but nothing has helped so far to fix this issue.
Thank you for your help.
I'm thinking that there's no url http://back.api.dev/api/videos/ from the front end.
maybe it needs a host entry in the front end like you've done on your host box.
sorry I don't have enough points to put this in as a suggestion comment rather than an answer.
Related
I'm trying to setup a docker environment with the the following containers: apache, php, mysql, phpmyadmin.
I have a problem making both phpmyadmin and my applications work at the same time, and I was wondering if it wasn't because I use a PHP container to run my PHP instead of phpmyadmin that also have PHP installed.
I understood that phpmyadmin runs with PHP (hence the name), though I was wondering if it was possible to have a docker image without PHP and then to proxy the requests to php files from phpmyadmin to the php container.
I've already established a reverse proxy from apache to phpmyadmin because I don't need phpmyadmin to run it's own apache server, and I would like to do the same with PHP.
I tried to proxy php requests from apache to my php container, but I doesn't work.
Here is my full compose.yaml
version: '3.8'
services:
php:
build:
context: './php/'
args:
- PHP_VERSION=${PHP_VERSION}
volumes:
- "${APPS_VOLUME:-apps}:/var/www/html/"
networks:
- backend
restart: unless-stopped
stdin_open: true
tty: true
container_name: php
apache:
build:
context: './apache/'
args:
- APACHE_VERSION=${APACHE_VERSION}
ports:
- '${APACHE_PORT:-8000}:80'
volumes:
- "${APPS_VOLUME:-apps}:/usr/local/apache2/htdocs/"
- "pma:/usr/local/apache2/htdocs/phpmyadmin/"
networks:
- frontend
- backend
depends_on:
- php
- mysql
working_dir: /usr/local/apache2/htdocs/
restart: unless-stopped
container_name: apache
mysql:
image: mysql:${MYSQL_VERSION}
ports:
- '${MYSQL_PORT:-3307}:3306'
volumes:
- "db-data:/var/lib/mysql"
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
command: --federated
working_dir: /usr/
restart: unless-stopped
container_name: mysql
phpmyadmin:
image: phpmyadmin:${PHPMYADMIN_VERSION:-latest}
volumes:
- "pma:/var/www/html/"
networks:
- backend
environment:
- PMA_HOST=mysql
- PMA_ABSOLUTE_URI=http://localhost:${APACHE_PORT:-8000}/phpMyAdmin/
restart: unless-stopped
container_name: phpmyadmin
volumes:
apps:
name: apps
db-data:
name: db-data
pma:
name: pma
networks:
frontend:
name: frontend
backend:
name: backend
And my apache conf
ServerName localhost
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so
<VirtualHost *:80>
# Proxy .php requests to port 9000 of the php-fpm container
#ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
<FilesMatch \.php$>
SetHandler "proxy:fcgi://php:9000/var/www/html/"
</FilesMatch>
DocumentRoot /usr/local/apache2/htdocs/
<Directory /usr/local/apache2/htdocs/>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Proxy phpmyadmin request to port 80 of the phpmyadmin container
ProxyPass "/phpMyAdmin/" "http://phpmyadmin/"
ProxyPassReverse /phpMyAdmin/ http://phpmyadmin/
# Send apache logs to stdout and stderr
CustomLog /proc/self/fd/1 common
ErrorLog /proc/self/fd/2
</VirtualHost>
Is my configuration wrong? Do I have to use the phpmyadmin container to handle PHP requests or is there a way to separate them?
Thanks
Edit: Changed the title of the issue after Nigel Ren observation
I seem to have found a solution, I don't know if it is how I'm supposed to do but I can now use the phpmyadmin interface and open my apps. There's still some problems with both of them, but I'm not sure if it have anything to do with the apache configuration
I used the fpm-alpine image of phpmyadmin instead of the normal one and changed my conf file like so:
ServerName localhost
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so
LoadModule proxy_http_module /usr/local/apache2/modules/mod_proxy_http.so
<VirtualHost *:80>
# Proxy phpmyadmin request to the phpmyadmin container
ProxyPassMatch ^/phpMyAdmin/(.*\.php(/.*)?)$ fcgi://phpmyadmin:9000/var/www/html/$1
ProxyPassReverse /phpMyAdmin/ fcgi://phpmyadmin:9000/var/www/html/
# Proxy .php requests to port 9000 of the php-fpm container
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
ProxyPassReverse / fcgi://php:9000/var/www/html/$1
DocumentRoot /usr/local/apache2/htdocs/
<Directory /usr/local/apache2/htdocs/>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Send apache logs to stdout and stderr
CustomLog /proc/self/fd/1 common
ErrorLog /proc/self/fd/2
</VirtualHost>
I'm not sure the ProxyPassReverse are required as I seem to have the same result without them.
I just realized that phpmyadmin is simply an app. The docker image just provides you the latest version along with an environment to make it ready to use, but you can really just copy the source files into your apps directory and parse the php files with your php container like you do for any other app.
So to answer one of my first questions, you don't need to have both containers because you don't even need the phpmyadmin image.
I feel stupid.
Hope it helps someone so I can at least feel like it was not all in vain.
My laravel project runs on docker, and I can browse the project with http://localhost:8000. But when it comes to sending a request to the API of this project (API and Website are in the same project and container named web_master), I get this error:
cURL error 7: Failed to connect to localhost port 8000: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://localhost:8000/api/v1/user/register
I can send requests to other sites like google.com, but I can not send requests to the project.
this is a part of my docker-compose file:
services:
mysql:
image: mysql:8.0.30
container_name: mysql_master
restart: always
environment:
MYSQL_ROOT_USER: root
MYSQL_ROOT_PASSWORD: 123
MYSQL_DATABASE: master
volumes:
- ./mysql-data:/var/lib/mysql
ports:
- '33060:3306'
networks:
- laravel_master
web:
build:
context: .
container_name: web_master
ports:
- '8000:80'
volumes:
- ./core:/var/www/app
- ./apache/default.conf:/etc/apache2/sites-enabled/000-default.conf
depends_on:
- mysql
networks:
- laravel_master
and the virtual host file:
<VirtualHost *:80>
ServerName laravel_app
DocumentRoot /var/www/app/public
<Directory /var/www/app>
AllowOverride All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Can anybody help me?
I build nginx revers proxy with self signed sert companion for local development and wordpress with docker behind proxy. My problem is when try to access wordpress by domain name he give my ERROR 502 BAD GATEWAY. I see in docker log on nginx-proxy with docker logs nginx-proxy this line (*1 no live upstreams while connecting to upstream, client: 172.17.0.1, server: kasha.com, request: "GET / HTTP/2.0", upstream: "http://kasha.com/", host: "kasha.com)
######## my docker-compose.yml ########
services:
db:
container_name: ${CONTAINER_DB_NAME}
image: ${DB_IMAGE:-mariadb}:${DB_VERSION:-latest}
restart: unless-stopped
volumes:
#- /srv/www/${DOMAINS}/db_data:/var/lib/mysql
- ./database:/var/lib/mysql
- ./mysqldumps/backup.sql.gz:/docker-entrypoint-initdb.d/backup.sql.gz
environment:
#MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
wp:
container_name: ${CONTAINER_SITE_NAME}
ports:
- "8080:80"
- "8443:443"
#build: .
image: ${SITE_IMAGE:-wordpress}:${SITE_VERSION:-latest}
depends_on:
- db
restart: unless-stopped
volumes:
# - ./theme:/var/www/html/wp-content/themes/${WP_THEME}:rw
# - ./plugin:/var/www/html/wp-content/plugins/${WP_PLUGIN}:rw
- ./site/wp-content:/var/www/html/wp-content
# - /srv/www/${DOMAINS}/wp_content:/var/www/html/wp-content:rw
- ./init/prep.sh:/usr/local/bin/prep.sh
environment:
WORDPRESS_DB_HOST: ${CONTAINER_DB_NAME}:3306
WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
WORDPRESS_DB_USER: ${MYSQL_USER}
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
WORDPRESS_TABLE_PREFIX: ${WORDPRESS_TABLE_PREFIX}
WORDPRESS_DEBUG: ${wp_debug_mode}
DISABLED_PLUGINS: ${wp_plugins_to_disable}
VIRTUAL_HOST: ${DOMAINS}
VIRTUAL_PORT: ${VIRTUAL_PORT}
SELF_SIGNED_HOST: "kasha.com"
#LETSENCRYPT_HOST: ${DOMAINS}
#LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
#LETSENCRYPT_TEST: 'true'
logging:
options:
max-size: ${LOGGING_OPTIONS_MAX_SIZE:-200k}
networks:
default:
external:
name: ${NETWORK} ~~~
################ my .env file ###################
```
# .env file to set up your wordpress site
# (Required) URL of site you are bringing down to develop
# E.g https://www.yourdomain.co.uk
production_url='http://www.kasha.com'
# (Optional) You can disable certain plugins that are not needed for development, e.g. security or SEO plugins.
# Comma separated string (no spaces), leave blank if no plugins to disable.
# E.g. plugin-folder-name-1,plugin-folder-name-2
wp_plugins_to_disable=
#
# Compose default env variables
#
COMPOSE_PROJECT_NAME=kasha.com
#
# Network name
#
#
NETWORK=proxy
VIRTUAL_PORT=80
#
# Database Container options
#
# [IMPORTANT] We recommend to always set a version when starting a new site.
# When migrating or restoring a backup you must know the running version
# Database image (mariadb|mysql)
DB_IMAGE=mariadb
# Database version
DB_VERSION=latest
# Database container name
CONTAINER_DB_NAME=kasha.com-db
# Path to store your database files
DB_FILES=./data/db
# Root password for your database
MYSQL_ROOT_PASSWORD=123456
# Database name, user and password for your wordpress
MYSQL_DATABASE=kashacom
MYSQL_USER=kashacom
MYSQL_PASSWORD=wzQjRKndgpJT
#
# Site Container options
#
# [IMPORTANT] We recommend to always set a version when starting a new site.
# When migrating or restoring a backup you must know the running version for
# theme and plugins compatibility.
# Site Image (wordpress)
SITE_IMAGE=wordpress
# Site Version
SITE_VERSION=latest
# Path to store your site files
SITE_FILES=./data/site
# Site container name
CONTAINER_SITE_NAME=kasha.com
# Max Log File Size
LOGGING_OPTIONS_MAX_SIZE=200k
# Table prefix
WORDPRESS_TABLE_PREFIX=wp_
# Your domain (or domains)
DOMAINS=kasha.com,www.kasha.com
COMPOSER_CONTAINER=kasha_cp
REPLACE_DB_SERVICE_NAME=kasha.com-db
REPLACE_SITE_SERVICE_NAME=kasha.com-wp
wp_debug_mode=false
```
it seems that the problem is in my wordpress docker file really i can't figure out where the problem is if anyone can help me i would be very grateful
Our website-framework(s) are designed to work on both xampp and docker environments. We are recognizing our database hosts by host name/IP-address (dev, test, staging, live env). People who are working with xampp are using https://localhost, so they get the environment variable called Development. People who are working with docker are using https://docker as their host. They get the env-variable called Development/Docker. We need this differentiation because inside the php applications our xampp users are connecting to their mysql service with host localhost. Docker users have to connect via host called mysql (this is the container name of the mysql-service).
Because of the last occurred problems (not relevant to be mentioned here) we want a unique solution for both user-groups concerning the database connection: Docker users should be able to connect to their mysql service with host localhost.
docker-compose.yaml (shortened for better overview):
version: '2'
services:
#######################################
# PHP application Docker container
#######################################
app:
build:
context: .
dockerfile: Dockerfile.development
links:
- mail
- mysql
- redis
ports:
- "80:80"
- "443:443"
- "10022:22"
- "3307:3306"
volumes:
- ./app/:/app/
- ./:/docker/
cap_add:
- SYS_PTRACE
env_file:
- etc/environment.yml
- etc/environment.development.yml
environment:
- POSTFIX_RELAYHOST=[mail]:1025
#######################################
# MySQL server
#######################################
mysql:
build:
context: docker/mysql/
dockerfile: MariaDB-10.Dockerfile
ports:
- "3306"
volumes:
- mysql:/var/lib/mysql
env_file:
- etc/environment.yml
- etc/environment.development.yml
#######################################
# phpMyAdmin
#######################################
# /// #
#######################################
# Mail
#######################################
# /// #
#######################################
# Redis
#######################################
# /// #
# Volumes
volumes:
mysql:
phpmyadmin:
redis:
I tried a lot and played with the docker-compose but didn't find a solution for weeks. Tried with links, networks and so on. I think my docker skills are exhausted by now...
I also added to the mysql.conf:
bind-address = 0.0.0.0
Any ideas?
It is because of docker's networking structure.
docker creates 3 base interfaces. docker0 , host and none.
each container uses docker0 by default. then each container will have a virtual network interface for communicating between containers. so you can use your database with mysql address.
if you want to connect to database with address localhost you should config docker to use host network mode (you can do it by adding one line to defenition of your app service in docker compose file). it will be able to connect to every app which is running on your system. By the way you would loose communication with other container by their name. maybe you loose your connection with your redis (which is connected with redis address)
In this network mode, every dependency should be deployed or be exposed to your localhost.
I'm running the latest stable Docker Desktop for Windows on Windows 10.
I've written a docker-compose file (see below) that builds separate containers, based on Centos 6 with SCL, one for httpd24-httpd (Apache) and one for rh-php56-php-fpm (PHP-FPM). The containers start up fine with the services reporting an OK status. If I ping a container from the other it resolves it fine. If I visit the index.html page Apache is happy and brings it up.
Apache is currently set to use proxy:fcgi:phpfpm:9000 but if I try to load a php file Apache returns a 503 error. I have tried a number of different connection options e.g proxy:fcgi:127.0.0.1:9000 -- 0.0.0.0:9000 -- 172.20.0.3:9000 (this being the phpfpm ip from docker) however Apache is just logging:
[proxy:error] [pid 60:tid ...] (...)Connection refused: AH00957: FCGI:
attempt to connect to 172.20.0.3:9000 (*) failed [proxy_fcgi:error]
[pid 60:tid ...] [client 172.20.0.1:44546] AH01079: failed to make
connection to backend: ...
I've also tried it with a proxypassmatch and still no joy.
<IfModule proxy_module>
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
</IfModule>
mod_proxy, mod_proxy_http and mod_proxy_fcgi are being loaded by Apache.
PHP-FPM is obviously also being configured. I've generally had this just set to listen on port 9000 but did also try :::9000
During the build in the development.php.dockerfile I've added:
EXPOSE 9000
and, as you can see in the compose file, httpd is linked to phpfpm so by my reckoning they should have total knowledge of each other and apache should be able to reach phpfpm:9000
Can anyone please help me work out why this isn't working?? It's driving me round the twist. Many many thanks.
docker-compose:
version: '2'
services:
httpd:
build:
context: .
dockerfile: ./docker/development.httpd.Dockerfile
environment:
- APACHE_RUN_USER=apache
- APACHE_RUN_GROUP=apache
- APACHE_LOG_DIR=/var/log/httpd24
- APACHE_RUN_DIR=/opt/rh/httpd24/root/var/run/httpd
- APACHE_LOCK_DIR=/opt/rh/httpd24/root/var/lock
- APACHE_SERVERADMIN=admin#mtf8.bar
- APACHE_SERVERNAME=foo.bar
- APACHE_SERVERALIAS="foo.foo.bar www.foo.bar"
- APACHE_DOCUMENTROOT=/var/www/html
volumes:
- ./data/www/html:/var/www/html
ports:
- "10180:80"
tty: true
networks:
- front-tier
phpfpm:
build:
context: .
dockerfile: docker/development.php.Dockerfile
environment:
- PHPFPM_RUN_USER=apache
- PHPFPM_RUN_GROUP=apache
- PHPFPM_LISTEN=9000
- PHPFPM_PM=dynamic
- PHPFPM_PM_MAX_CHILDREN=50
- PHPFPM_PM_START_SERVERS=5
- PHPFPM_PM_MIN_SPARE_SERVERS=5
- PHPFPM_PM_MAX_SPARE_SERVERS=35
- PHPFPM_LOG_DIR=/var/log/rh-php56-php-fpm
volumes:
- ./data/www/html:/var/www/html
tty: true
networks:
- front-tier
- back-tier
mysql:
build:
context: .
dockerfile: docker/development.mysql.Dockerfile
volumes:
- ./data/db:/usr/tmp/db/
- mysql:/var/lib/mysql
expose:
- 3306
ports:
- "10133:3306"
tty: true
networks:
- back-tier
volumes:
mysql:
networks:
front-tier:
driver: bridge
back-tier:
driver: bridge
www.conf
[...]
user = apache
group = apache
listen = 9000
listen.allowed_clients = httpd
[...]
00-custom.conf
[...]
<VirtualHost *:80>
[...]
<Directory "/var/www/html">
Options -Indexes +FollowSymlinks +MultiViews
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:fcgi://php:9000"
</FilesMatch>
[...]
</VirtualHost>
UPDATE
Issue was with PHP-FPM configuration file. I didn't realise it but rh-php56-php-fpm from SCL was creating 2 directories of conf files. I was modifying /opt/rh/rh-php56/register.content/etc/opt/rh/rh-php56/php-fpm.d/www.conf but the service was using /etc/opt/rh/rh-php56/php-fpm.d/www.conf
I should have made clear the full filepaths in the question!
I also removed listen.allowed_clients = httpd as it was causing a Broken pipe AH01074 Apache error. Using the container IP was fine but I don't want to head down that route. Either way not important.
Issue resolved.
The configurations were all correct but I was modifying the wrong www.conf file. rh-php56-php-fpm created 2 directories of conf files. I was modifying /opt/rh/rh-php56/register.content/etc/opt/rh/rh-php56/php-fpm.d/www.conf instead of /etc/opt/rh/rh-php56/php-fpm.d/www.conf which was used by the service.