When I was working on my website using wsl2’s environment (using ./vendor/bin/sail up
), some helper such as public_path()
and storage_path()
are not pointed to the original project folder, below are the output when dump them with dump()
.
Route::get('/', function () {
dump(public_path());
dump(storage_path());
});
^ "/var/www/html/public"
^ "/var/www/html/storage"
This makes me have some problems when dealing with the file uploading function.
Some solutions I tried:
-
Recreate a brand new laravel project and test it out with the
public_path()
andstorage_path()
. -
Try it in other device.
Kinda weird when come to the storage link
$ php artisan storage:link
The [/home/ahming/example-app/public/storage] link has been connected to [/home/ahming/example-app/storage/app/public].
The links have been created.
Also it works on the tinker
$ php artisan tinker
Psy Shell v0.11.5 (PHP 8.1.7 - cli) by Justin Hileman
>>> public_path()
=> "/home/ahming/example-app/public"
Edit:
Just find out that using php artisan serve
do not have the problem on returning wrong directory, so the problem might be focus on the docker.
When using the sail
on running the tinker command, it also returned the same result:
$ ./vendor/bin/sail artisan tinker
Psy Shell v0.11.5 (PHP 8.1.7 — cli) by Justin Hileman
>>> public_path()
=> "/var/www/html/public"
docker-compose.yml
:
# For more information: https://laravel.com/docs/sail
version: '3'
services:
laravel.test:
build:
context: ./vendor/laravel/sail/runtimes/8.1
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-8.1/app
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${HMR_PORT:-8080}:8080'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
mysql:
image: 'mysql/mysql-server:8.0'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- 'sail-mysql:/var/lib/mysql'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
networks:
- sail
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
retries: 3
timeout: 5s
phpmyadmin:
image: 'phpmyadmin/phpmyadmin'
links:
- mysql:mysql
ports:
- '8000:80'
environment:
MYSQL_USERNAME: "${DB_USERNAME}"
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
PMA_HOST: mysql
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
2
Answers
Since docker environment declare that the storage for the project is under
/var/www/html/
:docker-compose.yml
Everything need to deal in
/var/www/html
, so when creating symbolic link for public storage, use./vendor/bin/sail artisan storage:link
instead.It is because by calling the function
public_path()
you will get the path of that directory. Instead you should get the URL or the domain of that directory; for that it is better to use:asset()
to get public directory URL