Configuring MongoDB with Laravel Sail
Tags: laravel, mongodb, docker
Published: 2023-10-12 03:18:17

Recently, I set out on a mission to integrate MongoDB with Laravel, my all-time favorite framework. One challenge I faced was the desire to experiment without tampering with my local development setup. After all, nobody wants the chaos of having to fix a compromised local environment every time they test something new.

Enter Laravel’s latest offering to its expansive ecosystem: a seamless way to establish a virtual development environment, commonly referred to as "containers" using [laravel sail](https://laravel.com/docs/9.x/sail) With this feature, I could conveniently dive into new concepts and tools without affecting my main setup.

Initially, I was optimistic about the process, assuming it would be straightforward. However, I hit several unexpected obstacles along the way. There were moments of doubt where I contemplated seeking out alternative providers that might offer a more direct path to my goal.

Nevertheless, my passion for Laravel fueled my determination. I pressed on, seeking solutions and learning from each hiccup. I'm proud to report that, after some effort, I successfully set up the environment and overcame the challenges that nearly derailed my project.

With that backstory out of the way, let’s roll up our sleeves and delve into the technical details!

**Steps**

To start, you can create a new project using either the composer create-project or the laravel new command. However, as of the date of this writing, only Laravel version 9 and below are compatible with jenssegers/mongodb. While this might seem limiting, it's not a significant issue – or as some might say, "it's no biggie."
 
Next, open your project in your preferred code editor and ensure you have the terminal or command prompt active.

Then, before using Laravel Sail, you must first install it. Execute the following command:

```
php artisan sail:install
```

Then, since mongodb is still not included in the extension, for now select any that you think you will going to need in your project. And the we will add the mongodb later.

Then, after successfully building Sail, try if everything is fine by running the commands below:
```
./vendor/bin/sail up -d
./vendor/bin/sail composer --version
```

Next, add MongoDB into your **`docker-compose.yml`** file to enable its use in your project.
```yml
services:
    mongo:
        _image: 'mongo:6.0'
        restart: always
        environment:
            MONGO_INITDB_ROOT_USERNAME: '${MDB_USERNAME}'
            MONGO_INITDB_ROOT_PASSWORD: '${MDB_PASSWORD}'
            MONGO_INITDB_DATABASE: '${MDB_DATABASE}'
        volumes:
            - 'sailmongo:/data/mdb'
        networks:
            - sail
volumes:
    sailmongo:
        driver: local
```

Then, after checking all is well then you we can now install jenssegers' mongodb that we are going to use to connect to mongodb and use it as our database.

```
./vendor/bin/sail composer require jenssegers/mongodb
```

Unfortunately, you might encounter error messages similar to those below. This is because the MongoDB binary hasn't been installed in our container and hasn't been enabled in the php.ini file.
```
    - jenssegers/mongodb[v3.9.0, ..., v3.9.5] require mongodb/mongodb ^1.11 -> satisfiable by mongodb/mongodb[1.11.0, ..., 1.15.0].
    - jenssegers/mongodb[v1.0.0, ..., v1.0.8] require illuminate/support 4.0.x -> found illuminate/support[v4.0.0, .......
```

To resolve this issue, we'll need to install the MongoDB binary in our container. However, before doing so, initiate a bash session. This allows us to execute specific shell commands within the container.

```
./vendor/bin/sail root-shell
Then in root run the following commands:
#Install binary
pecl install mongodb

#Add extension to php.ini
echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```

Then, type exit to proceed in installing mongodb php extension. 

But before you decided to install it manually, how about we add it in our setup so we can always be sure that it is always included and automatically installed when we build the sail.

Next, run sail artisan sail:publish and you will see a new folder will be created named docker. Open it and you will see a folders named with version numbers that corresponds to your PHP version that you are using in your container.

Since I am using PHP v8.2, I will only change the files on this folder. But this is pretty simple if you are working on different PHP version as you will only change the files that are the same with your version number.

Okay, then open the Dockerfile and add our mongodb php extension inside, after **swoole** like what shown below so it will be included and installed automatically during build. And don't forget to change it to your PHP version.
```
php8.2-swoole php8.2-mongodb \
```

Next, build the container again. To do this, run the following commands:
```
#Stop sail
./vendor/bin/sail stop

#Rebuild container
/vendor/bin/sail build

#Start sail
/vendor/bin/sail sail up -d

#Install the mongodb package
./vendor/bin/sail composer require jenssegers/mongodb
```

We can now install the jenssegers's mongodb package and expect that it will be installed successfully.🤞

**Enjoy!**