Get PHP container on port 8000 after php artisan serve - php

I can't container to listen on port 8000, even after adding the port mapping on my docker-compose.yml file.
All relevant files can be found here: https://github.com/salvatore-esposito/laravel-dockerized
I ran the following commands: docker-compose exec app php artisan serve and it has run successfully.
Anyway if I go inside the container, curl works as expected, but it doesn't work from the outside. The connection gets refused.
I fetched the ip using docker-machine ip
Please note that I mapped the outside-inside port in my container via docker-compose.yml even if in the repository there si no map.
I tried to copy all files to a built image and launch:
docker run --rm -p 8000:8000 --name laravel salvio/php-laravel php artisan serve
and
docker exec -it laravel bash
Once more time if a run "curl localhost:80" and "curl localhost:8000" the former doesn't work and the latter it does whereas if I take the container's ip via docker inspect name_container and digit curl ip_of_container:8000 nothing.

When using docker-compose exec a command keeps running until it's interactive session is stopped(by using ctrl-c or closing the terminal) because it isn't running as a service. To be able to keep the following command running
docker-compose exec app php artisan serve
you would have to open 2 terminals, 1 with the command and 1 to connect to the container and ping port 8000
If you want to access your container port 8000 you would have to expose the port 8000 in the Dockerfile:
# rest of docker file
# Copy existing application directory permissions
#COPY --chown=www-data:www-data ./code /var/www/html
# Change current user to www-data
#USER www-data
# Expose port 9000 and start php-fpm server
EXPOSE 80
EXPOSE 80000
and map it to your host in docker-compose(file):
app:
build:
context: .
dockerfile: .config/php/Dockerfile
image: salvio/php-composer-dev
container_name: app
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www/html
ports:
- "80:80"
- "8000:8000"
volumes:
- ./code/:/var/www/html
- .config/php/php.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- myproject-network
Please keep in mind php artisan serve binds to localhost:8000. This means this is only reachable within the container. Use
php artisan serve --host 0.0.0.0
to bind to the shared network interface. Checkout the following resources:
https://stackoverflow.com/a/54022753/6310593
How do you dockerize a WebSocket Server?

Related

Access index.php from docker

I've created a docker with a database and a php server but I'm failing accessing the php file from the server.
For testing purpose I'm currently having 2 index.php in my test app ./index.php and ./app/index.php
This is my docker-compose.yml
version: '3'
services:
symfony:
build:
context: .
dockerfile: docker/Dockerfile
image: project-manager
ports:
- 80:80
db:
image: mysql
ports:
- 3306:3306
volumes:
- "./.data/db:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: root
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8080:80"
links:
- db
This is the php dockerfile
FROM php:7.4-fpm
# Install Composer
COPY --from=composer /usr/bin/composer /usr/bin/composer
# Copy all our files in the docker root
COPY . /
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f80a16af8336 project-manager "docker-php-entrypoi…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 9000/tcp project-manager_symfony_1
d97688010adf phpmyadmin/phpmyadmin "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:8080->80/tcp project-manager_phpmyadmin_1
55781c004031 mysql "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp project-manager_db_1
In my /etc/hosts
#Project Manager
127.0.0.1 project-manager.local
I can successfully access to the phpmyadmin using project-manager.local:8080
But if I try the simple project-manager.local/ or project-manager.local/index
I've got an empty response.
Root cause:
For symfony, you bind 80:80, this means you suppose there is a port 80 open in the php container. But, you use php:7.4-fpm which will just open port 9000.
(If you install net-tools in the container & use netstat -oanltp to check, there won't be 80 port open.)
Solutions:
Option 1:
If you insist to use php-fpm, then you need another web server container to pass the 80 request to php container's 9000 port. Maybe could add a more service with nginx container, and refers to connecting-nginx-to-php-fpm to set your configure for nginx container:
fastcgi_pass symfony:9000;
Option 2:
Switch to use php:7.4-apache, which defaults has a web server in the image open the 80 port, like next:
Dockerfile:
FROM php:7.4-apache
COPY . /var/www/html
index.php:
<?php
phpinfo();
NOTE: you should copy files to /var/www/html.
In a word, you should assure the container which you expose 80:80 really have a port 80 open in the container, otherwise, your expose is useless...

Connect container created with docker-compose to another one created with docker run

I have the following container created with docker-compose (php:7.2.20-apache):
version: "3"
services
php72:
build:
context: .
ports:
- 80:80
volumes:
- ./www:/var/www/html
And I have the following container created with docker run:
docker run --name mysql5 -p 3306:3306 -v mysql5-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.27
I can connect to the mysql with MySQL Workbench, but my applications in the first container (php7 created with docker-compose) can't connect to the database with same connection credentials.
How to solve this?
PS: It`s a test of a dev environment in MacOs
You could manage a user-defined bridge for them to communicate with each other, see this, detail as next:
1. Create a user-define bridge
$ docker network create my-net
2. Link mysql container to this network
$ docker run --name mysql5 -p 3306:3306 -v mysql5-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.27
$ docker network connect my-net mysql5
3. Configure docker-compose to use the network
version: "3"
services
php72:
build:
context: .
ports:
- 80:80
volumes:
- ./www:/var/www/html
networks:
default:
external:
name: my-net
Then, from this:
User-defined bridges provide automatic DNS resolution between containers.
You can visit each other with service name or container name.
First make sure that you use the correct address in php:7.2.20-apache container for the database as your MySQL Workbench most likely use different ip address (e.g. 127.0.0.1) than the php:7.2.20-apache container (e.g. 172.19.0.1)
Make sure the containers are on same network by listing your networks with
docker network ls
And if they are not, connect them to same one with
docker network connect
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
(See 'docker network connect --help' for more info.)
You can get more info about each network with command
docker network inspect
Usage: docker network inspect [OPTIONS] NETWORK [NETWORK...]

Why php development server hangs with docker compose?

I have the following docker-compose.yml configuration file:
silex-twig:
image: php:7.1
command: php -S localhost:4000 /app/index.php
volumes:
- .:/app
ports:
- 3000:4000
When I run docker-compose up it downloads the base image but then it hangs here:
Recreating silextwig_silex-twig_1
Attaching to silextwig_silex-twig_1
What am I doing wrong? There is nothing available on port 3000.
I know there are setups with php-fpm + nginx but that seemed complicated for only development.
That is normal. It is attaching to the stdout of the container (for which there is no stdout being logged). At this point, the container is running.
If you want to run in the background you would run with docker-compose up -d instead of just docker-compose up.
The actual HTTP request to port 3000 won't work because PHP is listening only on localhost. You need to modify your command to be php -S 0.0.0.0:4000 /app/index.php so that it is listening on all IP addresses and can accept connections through the Docker NAT.

How to access docker url from windows host

I have a php project in localhost which I can access from http://localhost:8000 and I have a service running in a docker container which I can access from http://192.168.56.100:8080. To access http://192.168.56.100:8080 I must configure my browser under manual proxy like this( this is from firefox configuration)
http proxy: proxy.comp.mycompanyname.com
No proxy for: localhost, 127.0.0.1,192.168.56.0/24
If I configure my browser above way then I can access this service http://192.168.56.100:8080 from browser.
Now the problem is, I want to connect to the service from my php project from localhost in windows machine. I tried this
$client = new Soapclient("http://192.168.56.100:8080");
This gives me error
PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'SoapFault: Could not connect to host"
I think I am missing some proxy configuration somewhere but not sure where. How to solve this?
Running following command gives me this
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.56.100:2376 v1.12.3
And my docker compose file
version: '2'
services:
idtool3-mysql-gpas:
image: mysql:5.7
container_name: tmf-gpas-1.7.8-mysql
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "gpas_2016"
volumes:
- ./gpas/sqls:/docker-entrypoint-initdb.d
labels:
- "service-name:gpas"
- "service-type:db-srv"
- "environment:test"
idtool3-gpas-wildfly:
image: tmfev/gpas:1.7.8
container_name: tmf-gpas-1.7.8-wildfly
links:
- "idtool3-mysql-gpas:mysqldb"
ports:
- "8080:8080"
depends_on:
- idtool3-mysql-gpas
labels:
- "service-name:gpas"
- "service-type:app-srv"
- "environment:test"
entrypoint: /bin/bash
command: -c "/opt/wait-for-it.sh mysqldb:3306 -t 120 && /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0"

Localhost connection refused in Docker development environment

I use Docker for my PHP development environment, and I set up my images with Docker Compose this way:
myapp:
build: myapp/
volumes:
- ./myapp:/var/www/myapp
php:
build: php-fpm/
expose:
- 9000:9000
links:
- elasticsearch
volumes_from:
- myapp
extra_hosts:
# Maybe the problem is related to this line
- "myapp.localhost.com:127.0.0.1"
nginx:
build: nginx/
ports:
- 80:80
links:
- php
volumes_from:
- myapp
elasticsearch:
image: elasticsearch:1.7
ports:
- 9200:9200
Nginx is configured (in its Docker file) with a virtual host named myapp.localhost.com (server_name parameter) and that points to the /var/www/myapp folder.
All this works fine.
But here is my problem: my web app is calling itself via the myapp.localhost.com URL with cURL (in the PHP code), which can be more easily reproduced by running this command:
docker-compose run php curl http://myapp.localhost.com
The cURL response is the following:
cURL error 7: Failed to connect to myapp.localhost.com port 80: Connection refused
Do you have any idea on how I can call the app URL? Is there something I missed in my docker-compose.yml file?
Months later, I come back to post the (quite straightforward) answer to my question:
Remove the server_name entry in the Nginx host configuration
Remove the extra_hosts entry in docker-compose.yml file (not necessary, but it's useless)
Simply call the server with the Nginx container name as a host (nginx here):
docker-compose exec php curl http://nginx

Categories