Laravel Works with Doltgres
What is Doltgres? It sounds like Postgres. Doltgres is a Postgres compatible version-controlled relational database. For example, you can commit and merge tables between branches. We have been integrating Doltgres with different tools to help with testing and improving it.
Today, we'll go over how to build a Laravel web application powered by a Doltgres database. Laravel and Doltgres combined is a full-featured web application framework backed by a database that tracks every change with commits, branches, diffs, and all the other version control features you know and love from Git.
Tim previously wrote a great blog demonstrating a sample Laravel web application step-by-step using a Dolt server. In case you are not familiar with Dolt, it is a MySQL compatible version of Doltgres. This blog will use that same application, but it will be configured to connect to Doltgres server instead.
Before we start, make sure to have doltgres
, php
and composer
installed. You can follow this installation guide in Tim's blog.
If you'd rather dive straight into the Chirper app with config already set up, you can find the full code in this GitHub repository. Make sure to check out doltgres
branch in this repo after cloning for Doltgres specific set up. Then, you can follow the steps on getting the app running in this part of Tim's blog.
Step 1: Run local Doltgres server
First, we create directory that the database will live on and start a Doltgres server in it:
$ cd ~/laravel
$ doltgres --data-dir=.
You can customize the server with configuration options later. For now, we will stick with the basics. This runs Doltgres on port 5432 with default credentials:
- User:
postgres
- Password:
password
This starts Doltgres server, so we can create the laravel
database to work on. Creating a laravel
database
will result in creating a laravel
directory in the directory that the server is running in. This means our database
now lives in ~/laravel/laravel
.
Step 2: Clone the Chirper
Laravel Project
Since we are using an existing Laravel sample application, you can clone the chirper
repository.
If you want to learn more about the steps to create the app from scratch, please follow the detailed guide in Tim's blog.
$ git clone https://github.com/dolthub/chirper.git
$ cd chirper
This demo is written for using dolt
server, so in the next step we will update some files to make it work with doltgres
server.
Step 3: Configure Laravel to Use Doltgres
- Laravel uses a
.env
file to manage database credentials. Update it to point to Doltgres:
--- a/.env.example
+++ b/.env.example
@@ -8,12 +8,12 @@ LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
-DB_CONNECTION=mysql
+DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
-DB_PORT=3306
+DB_PORT=5432
DB_DATABASE=laravel
-DB_USERNAME=root
-DB_PASSWORD=
+DB_USERNAME=postgres
+DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
- Next is in
app/Http/Middleware/setActiveBranch.php
to ensure we makepgsql
connection:
--- a/app/Http/Middleware/setActiveBranch.php
+++ b/app/Http/Middleware/setActiveBranch.php
@@ -24,8 +24,8 @@ public function handle(Request $request, Closure $next): Response
$database .= "/$active_branch";
}
- config(['database.connections.mysql.database' => $database]);
- DB::purge('mysql');
+ config(['database.connections.pgsql.database' => $database]);
+ DB::purge('pgsql');
return $next($request);
}
This part is responsible for checking out between branches. Laravel creates new connection to database every request.
The issue can arise if we use dolt checkout
command. More details on the reason for this change can be found here
- The last set of changes are updating how dolt commands are in sql context.
Originally, we use stored procedures to do version control commands, which looks like CALL DOLT_MERGE(...)
because in MySQL, procedures return results. However, PostgreSQL does not return results for stored procedures, so we use functions instead, which looks like SELECT DOLT_MERGE(...)
.
That's it. These are all the changes that are needed to get the same application written for Dolt to work with Doltgres.
Step 4: Run the application
Now, we have a working set up for connecting the Laravel application to Doltgres server. We'll follow the steps in Tim's blog to get the application running. Then register and log in. You will see the dashboard like this:
In terminal, we commit the migrated tables, so we start from a clean working set.
$ cd ~/laravel/laravel/
$ psql -U postgres
Password for user postgres:
psql (15.10 (Homebrew), server 15.0)
Type "help" for help.
postgres=> select dolt_commit('-Am','Commit after migration');
dolt_commit
------------------------------------
{97ci3u8si6vbv3992n8bfbt7fqd18al0}
(1 row)
postgres=>
Step 5: The fun part!
Now, we have the application running, we can play around with it. Let's try creating a new branch to make some changes and merge it into main
branch an in the application.
- We add a chirp in
main
branch.
- Checkout a new
dev
branch and add a chrip ondev
branch.
- Merge
dev
branch tomain
branch.
Here, we can see the change we made in dev
now in main
branch.
laravel=> select active_branch();
active_branch
---------------
main
(1 row)
laravel=> select * from chirps;
id | user_id | message | created_at | updated_at
----+---------+---------------------------------+---------------------+---------------------
1 | 1 | Hello! (this is on main branch) | 2025-05-27 23:57:04 | 2025-05-27 23:57:04
2 | 1 | Hi! (this is on dev branch) | 2025-05-27 23:58:26 | 2025-05-27 23:58:26
(2 rows)
Integrating various tools with Doltgres is very beneficial, as it helps identify bugs and uncover missing features needed to support the application. With this Laravel application, we found a couple of bugs and fixed them.
Issue #1:
The first issue we found is that Doltgres server sends a constant byte, I
for idle
, in ReadyForQuery
messages.
This byte indicates the current transaction status. Laravel uses BEGIN and COMMIT queries during migrations to safely create tables.
After a BEGIN query, the ReadyForQuery message should include the status byte T, indicating that the session is in a transaction block.
Once the transaction is committed (using the COMMIT query), the status byte should switch to I, indicating that the session is idle.
If an error occurs during the transaction, the status byte should be E
, representing a failed transaction block.
Issue #2:
This one was a regression where querying a table, the column name displayed table name as well:
postgres=> select name from dolt_branches;
dolt_branches.name
--------------------
main
(1 row)
In this application, we use Branch
model to display branches with check out, merge or delete options. We query on dolt_branches
system table to get branch names. Since we pre-define the column name to get the branch names from. It expects name
to retrieve the row results. The correct result should look like:
postgres=> select name from dolt_branches;
name
------
main
(1 row)
Wrap Up
With Laravel and Doltgres, you get the best of both worlds:
- Laravel’s cool web development
- Doltgres’ Git-style database versioning
This setup is great for collaborative apps, internal tooling, audit trails, or anything that benefits from change tracking.
We've published series of Dolt integration blogs. Similarly, integrating Doltgres with various tools helps us understand what users experience and need from our product. We also encourage users to try connecting Doltgres to their favorite tools.
Found any bugs? Report them to us, we'll work them resolved as soon as possible.
Have a tool you'd like us to cover in a demo blog? Let us know—we’re on Discord!