I have the following php service in docker-compse.yml
version: '3'
networks:
laravel:
driver: bridge
services:
nginx:
image: nginx:stable-alpine
restart: unless-stopped
ports:
- "${WEB_PORT}:80"
volumes:
- "${PROJECT_DIR}:/var/www/html"
- "${NGINX_CONFIG}:/etc/nginx/conf.d/default.conf"
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- php
- mysql
networks:
- laravel
mysql:
image: mysql:5.7.29
restart: unless-stopped
user: "${HOST_UID}:${HOST_GID}"
tty: true
ports:
- "${SQL_PORT}:3306"
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker/mysql:/var/lib/mysql
networks:
- laravel
php:
build:
context: ./docker
dockerfile: Dockerfile-php
user: "${HOST_UID}:${HOST_GID}"
volumes:
- "${PROJECT_DIR}:/var/www/html"
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
#- "${COMPOSER_CACHE_DIR}:/.composer/cache"
#- "${COMPOSER_CONFIG}:/.composer/config"
working_dir: /var/www/html
networks:
- laravel
npm:
image: node:13.7
user: "${HOST_UID}:${HOST_GID}"
volumes:
- "${PROJECT_DIR}:/var/www/html"
working_dir: /var/www/html
entrypoint: ['npm']
When I run whoami in the container, it returns:
whoami: cannot find name for user ID 1000
I think this is a problem because there is no home directory, docker-compose exec php ls ~ returns:
ls: cannot access '/home/clarg': No such file or directory
This then leads to docker-compose exec php php artisan tinker returning:
ErrorException
Writing to directory /.config/psysh is not allowed.
at vendor/psy/psysh/src/ConfigPaths.php:362
358▕ #\mkdir($dir, 0700, true);
359▕ }
360▕
361▕ if (!\is_dir($dir) || !\is_writable($dir)) {
➜ 362▕ \trigger_error(\sprintf('Writing to directory %s is not allowed.', $dir), \E_USER_NOTICE);
363▕
364▕ return false;
365▕ }
366▕
+20 vendor frames
21 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
From googling, I see this is in the home directory, which does not exist in the container.
How can I solve this?
EDIT:
Dockerfile-php:
FROM php:8.0-fpm
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions gd zip pdo_mysql
# check https://github.com/mlocati/docker-php-extension-installer#supported-php-extensions for more extensions
COPY --from=composer /usr/bin/composer /usr/bin/composer
php.ini
https://pastebin.com/T2iYTZz2
Your docker containers don't have any knowledge of the users that may or may not exist on the host machine, so unless you've built those in with their accompanying config and directory structure the only thing you're getting out of feeding docker your local UID and GID is "running the container as something other than root", which is good.
But generally you don't want to tie a docker container/image to the particular environment that it is launched from, eg: requiring a user with the same name as your local user exist within the container, plus all of its associated directories and such.
In this specific case it looks like artisan just wants to cache some config, and you can control where that lands with the environment variable:
XDG_CONFIG_HOME=/some/writeable/directory
Which you could set in the Dockerfile, docker-compose, or .env file of your project. I would suggest setting it to somewhere in your project directory, but outside of the docroot.
Ref: https://stackoverflow.com/a/62041096/1064767
This is well enough for local dev where you want to mount in your local work dir for testing, but will likely need a bit more consideration if you're going to build/deploy a final docker image.
Related
I'm facing an issue when opening files uploaded from my web app build with Laravel 7.
The files are well stored in my app.
I've also tried to run the project locally without using docker and everything is working fine, I can check the files without any issue.
In docker, I have three containers ( app, web , db )
I've created the symlink using php artisan storage:link
My static assets are accessible.
Here is my docker-compose.yml
version: '2'
services:
# The Application
app:
container_name: app
build:
context: ./
dockerfile: development/app.dockerfile
volumes:
- ./:/var/www
env_file: '.env.dev'
environment:
- "DB_HOST=database"
# The Web Server
web:
container_name: web
build:
context: ./
dockerfile: development/web.dockerfile
volumes:
- ./storage/logs/:/var/log/nginx
ports:
- 8990:80
# The Database
database:
container_name: db
image: mariadb:10.4
volumes:
- dbdata:/var/lib/mysql
environment:
- "MYSQL_DATABASE=database"
- "MYSQL_USER=...
- "MYSQL_PASSWORD=...
ports:
- 8991:3306
Grateful if someone could help me with this issue.
Try putting this line of code inside composer.json
"post-install-cmd": [
"ln -sr storage/app/public public/storage" ],
NB: For full article try out this link
https://github.com/laravel/ideas/issues/34#issuecomment-208895323
I have this docker stack running nginx, php, and mariadb.
Now I want to add NodeJS in order to migrate my platform to services, one at the time.
I'm trying to add node in the same way I added php,but when I run "docker-compose up", nodejs appears "Exited with code 254".
It appears to be a ENOET error related with my package.json file, but I'm already coping my file into the container, also if I run everything less nodejs, when I access my nginx container the package.json appears in the route it means to be, so I don't know why I'm seeing this error.
Here is my docker-compose.yml
nginx:
image: tutum/nginx
ports:
- "80:80"
- "8080:8080"
# - "8081:8081"
# - "8082:8082"
# - "8083:8083"
# - "8090:8090"
links:
- nodejs
- phpfpm
- mariadb
volumes:
- ./public/leal-api:/var/www
- ./nginx/default:/etc/nginx/sites-available/default
- ./nginx/default:/etc/nginx/sites-enabled/default
- ./public:/usr/share/nginx/html
nodejs:
command: npm start
build: ./node
ports:
- "3000:3000"
links:
- mariadb
volumes:
- ./public/leal-api:/var/www
phpfpm:
build: ./php
ports:
- "9000:9000"
links:
- mariadb
volumes:
- ./public:/usr/share/nginx/html
mariadb:
image: mariadb
environment:
MYSQL_DATABASE: leal
MYSQL_USER: lealadm
MYSQL_PASSWORD: leal2015*
MYSQL_ROOT_PASSWORD: LealColombia2017!
ports:
- "3306:3306"
And here is the Dockerfile of the nodejs
FROM node:7.10
VOLUME ["/var/www"]
# WORKDIR /src
WORKDIR /var/www
# COPY . /src
# RUN npm install
# RUN npm install -g nodemon #hmm idk
EXPOSE 3000
CMD ["npm", "start"]
Thanks in advance for any help that you can provide.
I have the following docker-compose.yml file which runs nginx with PHP support:
version: '3'
services:
nginx:
container_name: my-app-nginx
image: nginx:1.13.6
ports:
- 8080:80
volumes:
- ./nginx-default.conf:/etc/nginx/conf.d/default.conf
- ./my-app:/var/www/my-app
restart: always
depends_on:
- php
php:
container_name: my-app-php
image: php:7.1-fpm
volumes:
- ./my-app:/var/www/my-app
restart: always
The PHP application inside /var/www/my-app needs to communicate with a linux daemon (let's call it myappd).
The way I see it, I need to either:
Copy the myappd into the nginx container to /usr/local/bin, make it executable with chmod +x and run it in the background.
Create a different container, copy myappd to /usr/local/bin, make it executable with chmod +x and run it in the foreground.
Now, I'm new to Docker and I'm researching and learning about it but my best guess, given that I'm using Docker Composer, is that option 2 is probably the recommended one? Given my limited knowledge about Docker, I'd have to guess that this container would require some sort of linux-based image (like Ubuntu or something) to run this binary. So maybe option 1 is preferred? Or maybe option 2 is possible with a minimal Ubuntu image or maybe it's possible without such image?
Either way, I have no idea how would I implement that on the composer file. Especially option 2, how would the PHP application communicate with the daemon in a different container? Just "sharing" a volume (where the binary is located) like I did for nginx/php services would suffice? Or something else is required?
Simple answer is adding command entry to php service in docker-compose.yml.
Given that myappd is at ./my-app/ on host machine and at /var/www/my-app/, updated docker-compose.yml is something like following.
version: '3'
services:
nginx:
container_name: my-app-nginx
image: nginx:1.13.6
ports:
- 8080:80
volumes:
- ./nginx-default.conf:/etc/nginx/conf.d/default.conf
- ./my-app:/var/www/my-app
restart: always
depends_on:
- php
php:
container_name: my-app-php
image: php:7.1-fpm
volumes:
- ./my-app:/var/www/my-app
restart: always
command: ["/bin/sh", "/var/www/my-app/mappd", "&&", "php-fpm"]
Better answer is to create the third container which runs linux daemon.
New Dockerfile is something like following.
FROM debian:jessie
COPY ./myappd /usr/src/app/
EXPOSE 44444
ENTRYPOINT ['/bin/sh']
CMD ['/usr/src/app/myappd']
Build image and name it myapp/myappd.
Updated docker-compose.yml is something like following.
version: '3'
services:
nginx:
container_name: my-app-nginx
image: nginx:1.13.6
ports:
- 8080:80
volumes:
- ./nginx-default.conf:/etc/nginx/conf.d/default.conf
- ./my-app:/var/www/my-app
restart: always
depends_on:
- php
php:
container_name: my-app-php
image: php:7.1-fpm
volumes:
- ./my-app:/var/www/my-app
restart: always
networks:
- network1
depends_on:
- daemon
daemon:
container_name: my-app-daemon
image: myapp/myappd
restart: always
networks:
- network1
networks:
network1:
You can send request with hostname daemon from inside php. Docker container has capability to resolve hostname of another container in the same network.
I'm trying to setup a docker-compose system where I'd like to copy dev tools to /usr/local/bin/ on startup.
Thats my docker-compose.yml:
version: '3'
services:
web:
build: docker/container/nginx
ports:
- 4000:80
volumes: &m2volume
- ./src:/var/www/html/
- ./docker/data/bin/:/usr/local/bin/
- ~/.composer:/var/www/.composer
networks: &m2network
- www
links:
- "php"
- "mariadb:mysql"
mariadb:
image: mariadb
ports:
- 8001:3306
networks: *m2network
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: magento2
MYSQL_DATABASE: db
MYSQL_USER: magento2
MYSQL_PASSWORD: magento2
volumes:
- ./docker/container/db/docker-entrypoint-initdb.d/:/docker-entrypoint-initdb.d/
- ./docker/container/db/conf.d:/etc/mysql/conf.d
- ./docker/data/mariadb:/var/lib/mysql
php:
build: docker/container/fpm
volumes: *m2volume
networks: *m2network
networks:
www:
if I leave - ./docker/data/bin/:/usr/local/bin/ in it, I get an error:
ERROR: for m2_php_1 Cannot start service php: oci runtime error: container_linux.go:262: starting container process caused "exec: \"docker-php-entrypoint\": executable file not found in $PATH"
Starting m2_mariadb_1 ... done
ERROR: for php Cannot start service php: oci runtime error: container_linux.go:262: starting container process caused "exec: \"docker-php-entrypoint\": executable file not found in $PATH"
If I uncomment it, all works fine.
What am I doing wrong here?
If i understand this correctly, and mapping the volume ./docker/data/bin/:/usr/local/bin/ is causing an exception, then that's probably because of the entrypoint defined in the mariadb image.
More to the point, you're overwriting the /usr/local/bin container folder, which probably contains an executable used in the entrypoint. When that disappears, you get an error.
I use this to set up nginx for PHP:
nginx:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/site.conf
links:
- php
php:
image: php:7-fpm
volumes:
- ./code:/code
But how about Apache? How can I set up Apache + PHP in docker-compose.yml?
Following this guide:
version: '2'
services:
php:
build: php
ports:
- "80:80"
- "443:443"
volumes:
- ./php/www:/var/www/html
Error:
ERROR: In file './docker-compose.yml' service 'version' doesn't have any configuration options. All top level keys in your docker-compose.yml must map to a dictionary of configuration options.
Any ideas? I'm on Xubuntu 16.04.
EDIT:
After managing to upgrade docker-compose to 1.9, I try with this file below:
version: '2'
services:
php:
build: php
expose:
- 9000
volumes:
- ./php/www:/var/www/html
apache2:
image: webdevops/apache:latest
args:
- PHP_SOCKET=php:9000
volumes:
- ./php/www:/var/www/html
ports:
- 80:80
- 443:443
links:
- php
Error:
$ sudo docker-compose up -d
Building php
ERROR: Cannot locate specified Dockerfile: Dockerfile
Docker is such as pain!
Any ideas how to fix this?
I would choose webdevops dockerized apache, because it has simple configuration:
version: '2'
services:
php:
build: php
expose:
- 9000
volumes:
- ./php/www:/var/www/html
apache2:
image: webdevops/apache:latest
args:
- PHP_SOCKET=php:9000
volumes:
- ./php/www:/var/www/html
ports:
- 80:80
- 443:443
links:
- php
Since the example above does not work, here is a different approach:
docker-compose.yml
version: '3.1'
services:
php:
image: php:apache
ports:
- 80:80
volumes:
- ./php/www:/var/www/html/
Launch the server with
docker-compose up
We need to create a new folders /php/www in current path
Create a file under php folder save as "Dockerfile" which contains as below without quote
"FROM php:5.6-apache
RUN docker-php-ext-install mysqli"
Copy your docker-compose.yml file in your current folder where your "php" folder has.
Create a sample file "index.php" under www folder (/php/www/index.php)
Run in command prompt docker-compose up -d
Open your browser type "localhost" you can see your sample file results.
Note: Above steps as per above mentioned docker-compose.yml file.
You can check this question.
If you use build instead of image, then you need "Dockerfile". Dockerfile would be use as configuration file for building image.
You maybe miss part in guide, where you should create file with name "Dockerfile" inside directory "php". Directory "php" must be in the same directory, where your "docker-compose.yml". In "docker-compose.yml" you have this line.
build: php
The line mean, that configuration file (by default: "Dockerfile") is inside of directory "php". So you should create directory "php" and file "Dockerfile" inside of it.
This is "Dockerfile" from your guide.
FROM php:5.6-apache
RUN docker-php-ext-install mysqli
docker-compose.yml reference version 2
Dockerfile reference
I found an elegant way to dynamically configure the ports and other parameters: In apache2's configuration files you can reference environment variables.
#/etc/apache2/ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
#APACHE_HTTP_PORT_NUMBER:80
#APACHE_HTTPS_PORT_NUMBER:443
Listen ${APACHE_HTTP_PORT_NUMBER}
<IfModule ssl_module>
Listen ${APACHE_HTTPS_PORT_NUMBER}
</IfModule>
<IfModule mod_gnutls.c>
Listen ${APACHE_HTTPS_PORT_NUMBER}
</IfModule>
you can set the variables in Dockerfile or docker-compose.yml
You can set a directory with diferente Dockerfiles an declare in each service:
...
image: php:custom
build:
context: .
dockerfile: ./dockerfiles/Dockerfile-php
...
I have created a working example of PHP, APACHE, MYSQL, and PHPMYADMIN for PHP developers. You may find it useful if you need the original old-school working style. Please note that I am using port 8080 for my website and port 8081 for PHPMyAdmin. You can change these as you like.
version: '3.8'
services:
php-apache-environment:
container_name: php-apache
image: php:7.4-apache
volumes:
- ./php/src:/var/www/html/
ports:
- 8080:80
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: ezapi
MYSQL_USER: root
MYSQL_PASSWORD: password
ports:
- "6033:3306"
volumes:
- dbdata:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
links:
- mysql
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_ARBITRARY: 1
restart: always
ports:
- 8081:80
volumes:
dbdata: