Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jonwarshaw's avatar

'Failed to load PDF document' from symlinked public storage directory on AWS Elastic Beanstalk deploy of Laravel application (works locally)

I am having trouble retrieving for download a pdf file stored on the public disk using Laravel's Storage facade on a deployed version of my application. It works as expected locally.

Here is the function that retrieves the file from S3, then stores it to the disk, then returns a file download response.

public function downloadAddendum($id)
{    
    $addendum = Addendum::find($id);
    $path = Storage::disk('s3')->url($addendum->filename);
    $file = file_get_contents($path);
    Storage::disk('public')->put($addendum->filename, $file);
    return response()->download(storage_path("app/public/{$addendum->filename}"))->deleteFileAfterSend();
}

In order to make the locally stored files publicly accessible I have created a symbolic link as described in Laravel's docs. Locally, I run the php artisan storage:link command. For deployment, I have a .ebextension/01_deploy.config file which makes use of elastic beanstalk's post deploy hook to create the symlink in the var/app/current directory.

files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/99_symlink_public_storage.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
        #!/usr/bin/env bash
        sudo php /var/app/current/artisan storage:link

(The whitespace is off on the above yml code block because I lack markdown skills. The actual file is spaced correctly)

On the deployed environment when the user clicks the download button a pdf file downloads. Here is the javascript.

handleDownload(id) {
    axios({
        url: '/api/download/addendum/' + id,
        method: 'GET',
        responseType: 'blob',
    }).then((response) => {
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', 'addendum.pdf');
        document.body.appendChild(link);
        link.click();
    })
}

But when the file is opened I see the following error: Error Failed to load PDF document

During local development, I got this same error because I had not yet created a symbolic link between the /storage directory and the /public/storage directory. Once I created that link the download process was successful.

The symbolic link appears to be working on the deployed instance. When I ssh into it and navigate to the public directory and list the contents I see this:

storage -> /var/app/current/storage/app/public

And I see the pdf files added to the /public/storage folder after they are downloaded from S3.

Am I misunderstanding something about the elastic beanstalk directory structure? Or symbolic links? How can I retrieve a publicly accessible file for download?

0 likes
0 replies

Please or to participate in this conversation.