Skip to content

Installing FFmpeg on Laravel Cloud

Laravel Cloud is out, and I’ve already been using it for a few projects. Recently, I ran into a limitation: Laravel Cloud doesn’t allow installing persistent dependencies like FFmpeg. While they might offer this feature in the future, for now, we need to get creative.

Using Build Commands to Install FFmpeg

Laravel Cloud provides a Build Commands feature that lets you execute shell scripts during the build process. We’ll leverage this to install FFmpeg every time the app is deployed.

Initial Build Commands

By default, your build commands should look something like this:

composer install --no-dev

# npm ci --audit false
# npm run build

Now, let’s modify these steps to install FFmpeg.

Installing FFmpeg

We’ll download and install FFmpeg into the project’s home directory ($HOME/bin) so that it’s available during runtime.

# Install & Setup FFmpeg

# Create a `bin` directory for custom binaries
mkdir -p $HOME/bin
cd $HOME/bin

# Download the FFmpeg binaries
curl -L -o ffmpeg.tar.xz https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz

# Extract the archive
tar -xf ffmpeg.tar.xz

# Rename the extracted directory
mv ffmpeg-*-static ffmpeg

# Grant execution permissions
chmod +x $HOME/bin/ffmpeg/ffmpeg

# Move back to the project root
cd $HOME/html

# Composer installation
composer install --no-dev

# npm ci --audit false
# npm run build

Using the Correct Binaries

Now that FFmpeg is installed, you can use it in your Laravel application. If you’re using the php-ffmpeg/php-ffmpeg package, configure it like this:

$ffmpeg = FFMpeg\FFMpeg::create([
  'ffmpeg.binaries'  => '/var/www/bin/ffmpeg/ffmpeg',
  'ffprobe.binaries' => '/var/www/bin/ffmpeg/ffprobe',
]);

Refactoring the Installation Script

While adding the installation steps directly into your build commands works, it’s cleaner and more maintainable to move them into a dedicated script.

Creating a Deployment Script

Let’s create a file at ./deploy/ffmpeg.sh to handle the installation.

#!/bin/bash
set -e  # Exit immediately if any command fails

# Define the target directory
BIN_DIR="$HOME/bin"

# Ensure the bin directory exists
mkdir -p "$BIN_DIR"

# Change to the bin directory
(
    cd "$BIN_DIR"

    # Download FFmpeg
    echo "Downloading FFmpeg..."
    curl --silent --show-error --fail -L -o ffmpeg.tar.xz "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz"

    # Extract the archive
    echo "Extracting FFmpeg..."
    tar -xf ffmpeg.tar.xz

    # Rename the extracted directory
    mv ffmpeg-*-static ffmpeg

    # Set execute permissions
    chmod +x ffmpeg/ffmpeg

    # Clean up
    rm -f ffmpeg.tar.xz
)

echo "FFmpeg installation completed successfully!"

Updating Build Commands

Now, update your Laravel Cloud Build Commands to use the script:

# Install & Setup FFmpeg
./deploy/ffmpeg.sh

# Composer installation
composer install --no-dev

# npm ci --audit false
# npm run build

Deploying & Verifying

Push your code and trigger a new deployment. If everything works correctly, your build logs should contain something like this:

00:00:48 Running build commands ————————————————————— Finished
         Downloading FFmpeg...
         Extracting FFmpeg...
         FFmpeg installation completed successfully!
         Setting up Composer...
         ... Composer logs ...

And that’s it! You now have FFmpeg installed and running on Laravel Cloud. 🎉