How to log to a file from a dockerized php app - php

I have a php app dockerized.
My issue is how to capture errors from php service into a dedicated file on the host.
docker file looks is next:
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "3000:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./public:/public
php:
build:
context: .
dockerfile: PHP.Dockerfile
environment:
APP_MODE: 'development'
env_file:
- 'dev.env'
volumes:
- ./app:/app
- ./public:/public
- ./php.conf:/usr/local/etc/php-fpm.d/zz-log.conf
mysql:
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: <pass here>
env_file:
- 'dev.env'
volumes:
- mysqldata:/var/lib/mysql
- ./app:/app
ports:
- '3306:3306'
volumes:
mysqldata: {}
my php.conf that maps as /usr/local/etc/php-fpm.d/zz-log.conf inside php service looks like bellow:
php_admin_value[error_log] = /app/php-error.log
php_admin_flag[log_errors] = on
catch_workers_output = yes
My intention is using php error_log() function and have all the logs recorded in php-error.log which is a file inside volume app.
Now, all logs from containers are shown on terminal only.
I have been struggling with this several hours and have no ideea how to continue. Thank you

I don't know what is your source image. I assume some official docker image for PHP like https://hub.docker.com/_/php
All containerized applications are usually configured to log to stdout so you must override that behaviour. This is really PHP specific and I'm no PHP expert. From what you let us know it looks like you know how to override that behaviour (by using some error_log() function and php_admin_value[error_log] = /app/php-error.log property.
If the behaviour is overridden you should ensure the file app/php-error.log exists inside of the PHP container (i.e. get inside the container by something like docker exec -it my-container-id /bin/bash and then do ls /app/php-error.log and cat /app/php-error.log to see if the file is created.
Because you're mounting the ./app directory from the host to /app directory in container you already have them mirrored. Whatever is inside container's /app you will find in also your /path/to/docker/compose/app directory. You can check if file exists and some content is inside. If not you failed to override the default behaviour of where PHP is logging to.

Related

Access to docker container like an URL

I have an application developed with PHP, Nginx and dynamodb. I have create a simple docker-compose to work in local.
version: '3.7'
services:
nginx_broadway_demo:
container_name: nginx_broadway_demo
image: nginx:latest
ports:
- 8080:80
volumes:
- ./www:/var/www
- ./docker/nginx/vhost.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
links:
- php_fpm_broadway_demo
php_fpm_broadway_demo:
container_name: php_fpm_broadway_demo
build:
context: ./docker/php
ports:
- 9000:9000
volumes:
- .:/var/www/web
dynamodb:
image: amazon/dynamodb-local
ports:
- 8000:8000
expose:
- 8000
Now I need to add dynamodb URL params to allows PHP to make queries to the database.
So, if I make a ping from PHP docker container like this works fine:
ping dynamodb
This doesn't work.
ping http://dynamodb:8000
I need to use http://dynamodb:8000 because AWS needs a URI because I have this error if I use http://dynamodb:8000:
Endpoints must be full URIs and include a scheme and host
So: how can I call a docker container like an URL?
I have tried with docker-compose parameters like: depends, links, network without success
As discussed in the chat, the error come when dependency installed on the host and use inside the container as composer work base on the underlying platform.
So we investigate that the issue come due to above reason. installing dependency inside the container fix the issue.
docker exec -it php bash -c "cd web; composer install"

Using Laravel Websocker with docker/ docker-compose.yml is not working

I am developing a Laravel application. I am trying to use Laravel Websocket in my application, https://docs.beyondco.de/laravel-websockets. I am using Docker/ docker-compose.yml. Since the Laravel Websocket run locally on port 6001, I am having problem with integrating it with docker-compose. Searching solution I found this link, https://github.com/laradock/laradock/issues/2002. I tried it but not working. Here is what I did.
I created a folder called workspace under the project root directory. Inside that folder, I created a file called, Dockerfile.
This is the content of Dockerfile
EXPOSE 6001
In the docker-compose.yml file, I added this content.
workspace:
port:
- 6001:6001
My docker-compose.yml file looks something like this
version: "3"
services:
workspace:
port:
- 6001:6001
apache:
container_name: web_one_apache
image: webdevops/apache:ubuntu-16.04
environment:
WEB_DOCUMENT_ROOT: /var/www/public
WEB_ALIAS_DOMAIN: web-one.localhost
WEB_PHP_SOCKET: php-fpm:9000
volumes: # Only shared dirs to apache (to be served)
- ./public:/var/www/public:cached
- ./storage:/var/www/storage:cached
networks:
- web-one-network
ports:
- "80:80"
- "443:443"
php-fpm:
container_name: web-one-php
image: php-fpm-laravel:7.2-minimal
volumes:
- ./:/var/www/
- ./ci:/var/www/ci:cached
- ./vendor:/var/www/vendor:delegated
- ./storage:/var/www/storage:delegated
- ./node_modules:/var/www/node_modules:cached
- ~/.ssh:/root/.ssh:cached
- ~/.composer/cache:/root/.composer/cache:delegated
networks:
- web-one-network
When I run "docker-compose up --build -d", it is giving me the following error.
ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for services.workspace: 'port' (did you mean 'ports'?)
What is wrong and how can I fix it? How can I use Laravel Web Socket with docker-compose?
I tried changing from 'port' to 'ports', then I got the following error message instead.
ERROR: The Compose file is invalid because:
Service workspace has neither an image nor a build context specified. At least one must be provided.
Your Dockerfile is wrong. A Dockerfile must start with a FROM <image> directive as explained in the documentation. In your case it might be sufficient to run an existing php:<version>-cli image though, avoiding the whole Dockerfile stuff:
workspace:
image: php:7.3-cli
command: ["php", "artisan", "websockets:serve"]
Of course you will also need to add a volume with the application code and a suitable network. If you add a reverse proxy like Nginx in front of your services, you don't need to export the ports on your workspace either. Services may access other services as long as they are in the same network.

PhpStorm multi-docker hostname resolution

I have a fully set up docker environment furnished with Xdebug, properly set up with PhpStorm. My environment has multiple containers running for different functions. All appears to work great. CLI/Web interaction both stop at breakpoints as they should, no problems. However ...
I have a code snippet as follows:
// test.php
$host = gethostbyname('db'); //'db' is the name of the other docker box, created with docker-compose
echo $host;
If I run this through bash in the 'web' docker instance:
php test.php
172.21.0.2
If I run it through the browser:
172.21.0.2
If I run it via the PhpStorm run/debug button (Shift+F9):
docker://docker_web:latest/php -dxdebug.remote_enable=1 -dxdebug.remote_mode=req -dxdebug.remote_port=9000 -dxdebug.remote_host=172.17.0.1 /opt/project/test.php
db
It doesn't resolve! Why would that be, and how can I fix it?
As it happens, my docker environment is built with docker-compose, and all the relevant containers are on the same network, and have a proper depends_on hierarchy.
However. PHPStorm was actually set up to use plain docker, rather than docker-compose. It was connecting fine to the docker daemon, but because the container wasn't being build composer-aware, it wasn't leveraging the network layout that was defined in my docker-compose.yml. Once I told PHPStorm to use docker-compose, it worked fine.
As an aside, I noticed that after I run an in-IDE debug session after already loading my container, and causes the container to exit when the script ends. To get around this, I had to create a mirror debug container for PHPStorm to use on demand. My config is as follows:
version: '3'
services:
web: &web
build: ./web
container_name: dev_web
ports:
- "80:80"
volumes:
- ${PROJECTS_DIR}/project:/srv/project
- ./web/logs/httpd:/var/log/httpd
depends_on:
- "db"
networks:
- backend
web-debug:
<< : *web
container_name: dev_web_debug
ports:
- "8181:80"
command: php -v
db:
image: mysql
container_name: dev_db
ports:
- "3306:3306"
volumes:
- ./db/conf.d:/etc/mysql/conf.d
- ./db/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
networks:
- backend
networks:
backend:
driver: bridge
This allows me to be able to do in-IDE spot debuging on the fly without killing my main web container.

Docker - Pass a environment setting via docker-compose

I am new to Docker and have a working docker-compose file, apart from one part. What I want to achieve is to set an environment setting so that in my PHP application I can use some variables to determine which resources I load in.
In MAMP PRO, for instance, you can access environment settings on this page:
.
In my docker-compose file I have the following:
services:
webserver:
build: ./docker/webserver
image: perch
ports:
- "80:80"
- "443:443"
volumes:
- C:/websites/sitename/www:/var/www/html
links:
- db
environment:
- DEVELOPER_ENV=development
At the moment the variable - from what I can tell - isn't being set as my php variables to detect the environment, fail. Any pointers would be appreciated.
Apache by default removes most environment variables for security reasons.
But you can whitelist variables in the etc/apache2/conf-enabled/expose-env.conf file.
So I added theses commands to my dockerfile:
RUN
echo 'PassEnv DB_PW' >> /etc/apache2/conf-enabled/expose-env.conf \
&& echo 'PassEnv DB_USER' >> /etc/apache2/conf-enabled/expose-env.conf
Alternatively you can copy or mount the expose-env.conf.

Set symfony cache directory in parameters

I'm building a docker environment for a Symfony application. I have a container per application with an attached data only container for the web root that is linked to the application server. As part of the security hardening for the infrastructure these data containers are set to read only, to prevent any remote code exploits. Each application then also has a side car container that allows logs to be written to.
Symfony currently writes the cache to the default cache_dir location of
${web_root}/app/cache/${env}
Which is in the read-only data container
when trying to boot the application I get this error
Unable to write in the cache directory
Obviously as its in the write only container this will happen
I've set my log_path is set in parameters outside the read-only container in the read-write sidecar logging container of
/data/logs/symfony
which works fine.
I've read the Symfony cookbook on how to over ride the directory structure but it only advises on how to do this in AppKernal.php which I don't want to do as the paths may change dependant on if its in a local/uat/prod environment.
We feed Symfony different parameters from our build server depending on the environment we are deploying to so it makes sense to put this config in here.
does anyone know if its possible to override the cache dir in config rather than editing AppKernal.php
I'm creating the cache file outside the container and using -v to mount the directory into the container
$DIR is the current location
htdocs where the webfiles are
docker run -d \
-v $DIR/htdocs:/var/www/html \
-v $DIR/cache_folder:/var/www/html/app/cache
Then make sure that the container is allowed to write into cache_folder . The advantage is that you're not loosing any data if you recreate the container. This will also overwrite the folder /var/www/html/app/cache
Another way you can do this is inside every container, but loose the setting with every restart
chmod -R 777 ${web_root}/app/cache/${env}
Here's a simplified example of a docker-compose yml file i'm using, with a read only parent data container with 2 sidecar containers for caching and logging with :rw access that overrides a path that is contained with the read-only parent path
docker-compose-base.yml
version: '2.0'
# maintainer james.kirkby#sonyatv.com
# #big narstie said "dont f*** up the #base"
services:
# web server
pitchapp-web:
hostname: pitchapp-web
depends_on:
- pitchapp-dc
- pitchapp-log-sc
- pitchapp-cache-sc
- pitchapp-fpm
volumes_from:
- pitchapp-dc
- pitchapp-log-sc:rw
- pitchapp-cache-sc:rw
links:
- pitchapp-fpm
build:
args:
- APP_NAME=pitchapp
- FPM_POOL=pitchapp-fpm
- FPM_PORT=9001
- PROJECT=pitch
- APP_VOL_DIR=/data/www
- CONFIG_FOLDER=app/config
- ENVIRONMENT=dev
- ENV_PATH=dev
context: ./pitch
dockerfile: Dockerfile
ports:
- "8181:80"
extends:
file: "shared/dev-common.yml"
service: dev-common-env
env_file:
- env/dev.env
# web data-container
pitchapp-dc:
volumes:
- /data/tmp:/data/tmp:rw
- /Sites/pitch/pitchapp:/data/www/dev/pitch/pitchapp/current:ro
hostname: pitchapp-dc
container_name: pitchapp-dc
extends:
file: "shared/data-container-common.yml"
service: data-container-common-env
read_only: true
working_dir: /data/www
# web cache sidecar
pitchapp-cache-sc:
volumes:
- /data/cache/pitchapp:/data/www/dev/pitch/pitchapp/current/app/cache/dev:rw
hostname: pitchapp-cache-sc
container_name: pitchapp-cache-sc
extends:
file: "shared/data-container-common.yml"
service: data-container-common-env
read_only: false
working_dir: /data/cache
# web log sidecar
pitchapp-log-sc:
volumes:
- /data/log/pitchapp:/data/log:rw
- /data/log/pitchapp/symfony:/data/www/dev/pitch/pitchapp/current/app/logs:rw
build:
args:
- APP_NAME=pitchapp
- TARGET_SERVICE=pitchapp
hostname: pitchapp-log-sc
container_name: pitchapp-log-sc
extends:
file: "shared/logging-common.yml"
service: logging-common-env
data-container-common.yml
version: '2.0'
services:
data-container-common-env:
build:
context: ./docker-data-container
dockerfile: Dockerfile
image: jkirkby91/docker-data-container
env_file:
- env/data.env
restart: always
privileged: false
tty: false
shm_size: 64M
stdin_open: true
logging-common.yml
version: '2.0'
services:
logging-common-env:
build:
context: ./logging
dockerfile: Dockerfile
image: jkirkby91/docker-data-container
env_file:
- env/logging.env
restart: always
working_dir: /data/log
privileged: false
tty: false
shm_size: 64M
stdin_open: true
read_only: false

Categories