DEV Community

Cover image for Getting Started with MongoDB and Laravel 13 on Ubuntu 24.04: A Practical Setup Guide
Md Abu Musa
Md Abu Musa

Posted on

Getting Started with MongoDB and Laravel 13 on Ubuntu 24.04: A Practical Setup Guide

Relational databases are the default for most Laravel projects, and for good reason. But many real systems also hold data that does not fit neatly into rows and columns: product catalogs with varying attributes, event logs, user activity feeds, and content with nested structures. MongoDB's document model handles these cases naturally, and the official Laravel integration lets you work with it using the Eloquent patterns you already know.

This guide walks through a complete, working practice environment on a fresh Ubuntu 24.04 machine: MongoDB 8.0, the PHP MongoDB extension, a new Laravel 13 project, and your first CRUD and aggregation queries. It also covers the one build error that trips up many developers during the extension install, so you can avoid losing an hour to it.

What You Will Build

By the end, you will have:

  • MongoDB 8.0 running as a system service
  • The PHP mongodb extension compiled and enabled
  • A Laravel 13 project connected to MongoDB through mongodb/laravel-mongodb
  • A Product model with create, read, update, and delete operations working
  • A first aggregation pipeline running from Laravel

Prerequisites: Ubuntu 24.04, a user with sudo access, and basic familiarity with PHP and the terminal. Ubuntu 24.04 ships with PHP 8.3, which satisfies Laravel 13's requirements.

Step 1: Install MongoDB 8.0

MongoDB is not in Ubuntu's default repositories, so add the official MongoDB repository first.

sudo apt-get update && sudo apt-get install -y gnupg curl

curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
  sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor

echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | \
  sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list

sudo apt-get update
sudo apt-get install -y mongodb-org
sudo systemctl enable --now mongod
Enter fullscreen mode Exit fullscreen mode

Verify that the service is running and responding:

systemctl status mongod --no-pager
mongosh --eval 'db.runCommand({ ping: 1 })'
Enter fullscreen mode Exit fullscreen mode

You should see Active: active (running) and { ok: 1 }. If mongod fails to start, sudo journalctl -u mongod -n 50 will show why.

Step 2: Prepare PHP

Install the PHP packages Laravel needs, plus the build tools required to compile the MongoDB extension.

sudo apt install -y php8.3-cli php8.3-xml php8.3-mbstring php8.3-curl \
  php8.3-zip php8.3-sqlite3 php8.3-dev php-pear libssl-dev pkg-config unzip
Enter fullscreen mode Exit fullscreen mode

Install Composer if you do not already have it:

sudo apt install -y composer
Enter fullscreen mode Exit fullscreen mode

Step 3: Install the PHP MongoDB Extension

The Laravel package is built on the official mongodb PHP extension, so nothing works without it. Install it through PECL:

sudo pecl channel-update pecl.php.net
yes '' | sudo pecl install mongodb
Enter fullscreen mode Exit fullscreen mode

Then enable it:

echo "extension=mongodb.so" | sudo tee /etc/php/8.3/mods-available/mongodb.ini
sudo phpenmod mongodb
php --ri mongodb
Enter fullscreen mode Exit fullscreen mode

If the last command prints MongoDB support => enabled along with a version number, the extension is ready.

The Pitfall: Do Not Answer "yes" to PECL's Prompts

During installation, PECL asks several configuration questions. The safe approach is to accept the default for every one of them by pressing Enter, which is exactly what yes '' does above.

A common mistake is answering yes to these three:

  • Enable developer flags? This turns on strict compiler settings that can turn harmless warnings into build failures.
  • Enable code coverage? Unnecessary for normal use.
  • Use system libraries for libbson, libmongoc, and libmongocrypt? This is the one that breaks most builds. Ubuntu's packaged libbson is older than the version the extension requires, so the build stops with an error like Could not find system library for libbson >= 2.5.6.

With the defaults, the extension compiles against its own bundled libraries and builds cleanly. If you already ran the install with the wrong answers, run sudo phpdismod mongodb to silence the load warnings, clear the cache with sudo pecl clear-cache, and reinstall with the defaults.

Also note that the PHP CLI and PHP-FPM read separate configuration. If you later serve the app through FPM or Apache, restart that service after enabling the extension.

Step 4: Create the Laravel Project

composer create-project laravel/laravel mongo-practice
cd mongo-practice
composer require mongodb/laravel-mongodb
Enter fullscreen mode Exit fullscreen mode

Composer selects a compatible version of the package automatically. If it reports a version conflict with Laravel 13, check the package's releases page for the supported version range.

Step 5: Configure the Connection

Add your connection details to .env:

MONGODB_URI=mongodb://127.0.0.1:27017
MONGODB_DATABASE=practice
Enter fullscreen mode Exit fullscreen mode

Then add a mongodb connection to the connections array in config/database.php:

'mongodb' => [
    'driver'   => 'mongodb',
    'dsn'      => env('MONGODB_URI', 'mongodb://127.0.0.1:27017'),
    'database' => env('MONGODB_DATABASE', 'practice'),
],
Enter fullscreen mode Exit fullscreen mode

Leave DB_CONNECTION set to sqlite for now. Laravel's sessions, cache, and migrations will keep using the default database, while only the models you explicitly point at MongoDB will use the mongodb connection. This separation keeps a practice project simple and avoids surprises.

Step 6: Create Your First Model

php artisan make:model Product
Enter fullscreen mode Exit fullscreen mode

Replace the generated class with a MongoDB-aware model:

<?php

namespace App\Models;

use MongoDB\Laravel\Eloquent\Model;

class Product extends Model
{
    protected $connection = 'mongodb';
    protected $collection = 'products';
    protected $fillable = ['name', 'price', 'category', 'tags', 'specs'];
}
Enter fullscreen mode Exit fullscreen mode

The key difference from a standard Eloquent model is the base class. Import MongoDB\Laravel\Eloquent\Model instead of Illuminate\Database\Eloquent\Model. Everything else, including $fillable, casts, and query builder methods, will feel familiar.

MongoDB creates the database and collection automatically on the first write, so there is no migration to run.

Step 7: Practice with Tinker

Open Laravel's REPL:

php artisan tinker
Enter fullscreen mode Exit fullscreen mode

Create

use App\Models\Product;

Product::create([
    'name'     => 'Laptop',
    'price'    => 85000,
    'category' => 'electronics',
    'tags'     => ['work', 'portable'],
    'specs'    => ['ram' => '16GB', 'storage' => '512GB'],
]);
Enter fullscreen mode Exit fullscreen mode

Notice that tags is an array and specs is a nested object. In a relational database, these would typically need extra tables or JSON columns. Here they are first-class values.

Read

Product::where('price', '>', 50000)->get();
Product::where('specs.ram', '16GB')->first();   // dot notation for nested fields
Product::whereIn('tags', ['work'])->get();      // match inside arrays
Enter fullscreen mode Exit fullscreen mode

Update and Delete

Product::where('name', 'Laptop')->update(['price' => 80000]);
Product::where('name', 'Laptop')->delete();
Enter fullscreen mode Exit fullscreen mode

Verify in the MongoDB Shell

Open a second terminal and inspect the raw documents:

mongosh
use practice
db.products.find().pretty()
Enter fullscreen mode Exit fullscreen mode

This is the most valuable habit for learning. Run a query in Laravel, then look at what actually landed in MongoDB. Seeing both sides builds an accurate mental model of how documents are stored.

Step 8: Your First Aggregation Pipeline

Aggregation is where MongoDB becomes a serious analytics tool. A pipeline passes documents through ordered stages, each transforming the data. This example calculates the average price per category:

Product::raw(fn ($collection) => $collection->aggregate([
    ['$group' => [
        '_id' => '$category',
        'avgPrice' => ['$avg' => '$price'],
        'count' => ['$sum' => 1],
    ]],
    ['$sort' => ['avgPrice' => -1]],
]))->toArray();
Enter fullscreen mode Exit fullscreen mode

The $group stage buckets documents by category and computes the aggregates, and $sort orders the results. From here, the stages worth learning next are $match (filtering early, which improves performance), $project (reshaping output), $unwind (flattening arrays), and $lookup (joining collections).

Troubleshooting Reference

Symptom Likely Cause and Fix
Class "MongoDB\Client" not found The extension is not enabled for the PHP binary you are using. Run sudo phpenmod mongodb and restart FPM if applicable.
pecl install fails with a libbson error You answered yes to the system-libraries prompt. Reinstall using the defaults.
PHP warns it cannot load mongodb.so The .ini file exists but the extension was never built. Run sudo phpdismod mongodb, then reinstall.
mongod will not start Check sudo journalctl -u mongod -n 50 for the specific error.
Queries return nothing Confirm the database name in .env matches the one you are inspecting in mongosh.

Where to Go Next

With a working environment, the most productive next steps are:

  1. Data modeling. Learn when to embed documents versus reference them. This decision shapes performance more than any other.
  2. Indexing. Create indexes for your query patterns and use explain() to confirm they are used.
  3. Deeper aggregation. Build multi-stage pipelines with $match, $lookup, and $unwind against realistic seeded data.
  4. Transactions and replica sets. Multi-document transactions require a replica set, even in local development.

Conclusion

Setting up MongoDB with Laravel on Ubuntu comes down to three moving parts: the database service, the PHP extension, and the Laravel package. Most of the friction sits in the extension build, and it disappears once you accept PECL's defaults. From there, you work with documents through the same Eloquent interface you already use every day, while gaining flexible schemas, nested data, and a powerful aggregation framework.

Top comments (0)