Solved. From the default/ directory, had to create symlink as follows:
ln -s /home/forge/default/storage/app/public public/storage
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
My app saves profile image files into storage/app/public/avatars/ (which is a directory I created to store user avatars). It works fine on localhost (Mac), but on my new Digital Ocean droplet, which I manage through Forge, the app won't store images when Saved through the UI, and it won't read images in the browser if I push an image file to the Digital Ocean server through Transmit.
With the file update function (shown below), the function stores the file path into the database, and that works fine, so I know the route is working, and database access is working.
The entire page loads correctly, except for images in this one directory. Images display fine from the public/ directory.
'forge' is the owner for all directories in the file path, and for the files.
Permissions for all directories in the file path are the same for the public/ directory and the storage/app/public/avatars/ directory, as well as the image files in both locations.
I created a symlink as follows: ln -s storage/app/public public/storage
My code is below:
***********************************************************************************
SAVE THE IMAGE FILE AND STORE THE FILE PATH TO THE DATABASE
***********************************************************************************
public function update(Request $request , Capsule $capsule)
{
// Store the avatar image
$file_url = request()->file('avatar')->store('public/avatars');
// Save the path to the image in the capsule table
$affected = DB::update('update capsules set avatar_path = ? where id = ?',
[$file_url , $capsule->id]);
return back();
}
***********************************************************************************
FILESYSTEMS.PHP
***********************************************************************************
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => 'local',
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => 's3',
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "s3", "rackspace"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => 'your-key',
'secret' => 'your-secret',
'region' => 'your-region',
'bucket' => 'your-bucket',
],
],
];
Thanks so much!
Solved. From the default/ directory, had to create symlink as follows:
ln -s /home/forge/default/storage/app/public public/storage
Please or to participate in this conversation.