Laravel Development Using PostgreSQL and Laradock
Tags: laravel, laradock, postgres, docker
Published: 2019-06-13 20:23:31

---
title: "Laravel Development Using PostgreSQL and Laradock"
published: true
description: "Setting up a Laravel development environment using Laradock and PostgreSQL database"
tags: laravel, laradock, postgresql, docker  
cover_image: 
canonical_url: https://kags.me.ke/post/laravel-postgresql-laradock/
published: true
---

![](https://thepracticaldev.s3.amazonaws.com/i/twfp7l0i71loo8lkq525.png)

In this post, we setup a [Laravel](https://github.com/laravel/laravel) development environment using PostgreSQL and [Laradock](https://github.com/laradock/laradock). Laradock uses Docker to easily setup up a development environment for PHP projects. By using Docker,  you eliminate the need to install [PHP](https://github.com/php/php-src), [Composer](https://getcomposer.org/), Laravel or a database server on your local computer.

### Requirements

- [Git](https://git-scm.com/downloads) will be required in order to clone the Laradock repository. You can find out if Git is installed on your computer by running `git --version` on a terminal/command prompt. This will display the version number of the installed Git or an error if Git is not installed.
- For starting up requisite Laradock applications, [Docker](https://docs.docker.com/install/) will also be required. Laradock requires Docker version 17.12 or higher. To display the version of Docker installed on your computer, run `docker --version` on your terminal or command prompt.

### Installation Options

There are two ways of using Laradock within your projects:

- making LaraDock to be part of your project by installing Laradock within the root of your Laravel project, or
- installing a common Laradock anywhere on your computer to be used by all your projects. Using this approach, you will need to later create configuration files to point to your projects/domains and also make changes to your **hosts** file.

The first method requires minimal configuration. It is possible for various projects to have varying requirements and this approach would fit seamlessly to these requirements, therefore this method will be adopted in this post. For this post, we will be using **duka** and **duka-laradock** for the project folder and Laradock folder. You can replace these names to fit your project requirements.

### Installation

1. Create folder for your project and change to the newly created folder

        mkdir duka && cd duka

2. Initialize Git in your root project folder
    
        git init

3. Add Laradock submodule to your project and place the repository within **duka-laradock** folder

        git submodule add https://github.com/Laradock/Laradock.git duka-laradock

### Update PostgreSQL Environment Variables

1. Navigate to the **duka-laradock** folder using the following command:
     
        cd duka-laradock

2. Copy **env-example** file to **.env** 

        cp env-example .env

3. Open **.env** file using your favorite editor. Locate and update PostgreSQL section to reflect your PostgreSQL database requirements

        ### POSTGRES ##############################################

        POSTGRES_DB=duka-db
        POSTGRES_USER=homestead
        POSTGRES_PASSWORD=secret
        POSTGRES_PORT=5432

4. While at it, you may also optionally modify the PHP version to be used within your project by modifying `PHP_VERSION` variable within the **.env** file.

        ### PHP Version ###########################################

        PHP_VERSION=7.3

### Create Unique Docker Containers

By default, the containers will have **laradock_**  as the suffix. As we are using Laradock per individual project we need to make some  modifications to the **.env** file so that the containers created will be unique and reflect our project name. Locate **COMPOSE_PROJECT_NAME** variable and modify as follows:

        COMPOSE_PROJECT_NAME=duka-laradock

This will make our containers have a suffix of **duka-laradock_** instead of **laradock_**


### Provision Your Docker Containers

Laradock supports [various softwares](http://laradock.io/introduction/#supported-software-images) which you can work with. Each software selected will be provisioned in its own container

While still within **duka-laradock** folder, run docker-compose command and specify the software (images) you require to be provisioned for your project
    
        docker-compose up -d nginx postgres

If this is the first time images are being provisioned and depending on the software selected and your internet connection speed, the process of provisioning the containers may take a while.

After the process runs to completion, run **docker-compose ps** command to view the containers which were provisioned.

    docker-compose ps

The above command will provide an output similar to the following: 

```bash
              Name                            Command              State                    Ports                  
-------------------------------------------------------------------------------------------------------------------
duka-laradock_docker-in-docker_1   dockerd-entrypoint.sh           Up      2375/tcp                                
duka-laradock_nginx_1              /bin/bash /opt/startup.sh       Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
duka-laradock_php-fpm_1            docker-php-entrypoint php-fpm   Up      9000/tcp                                
duka-laradock_postgres_1           docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp                  
duka-laradock_workspace_1          /sbin/my_init                   Up      0.0.0.0:2222->22/tcp      
```

The output lists the containers that were provisioned for us. **Name** is the name that was assigned to each container, **Command** refers to the command that was used to provision the container while **Ports** refers to the ports which were opened for each container. Our web server **nginx** depends on **php-fpm** (duka-laradock_php-fpm_1). That is why it was provisioned even though we never specified this container in our docker compose command. The **workplace** (duka-laradock_workspace_1) container will have tools that we may require in our development workspace. Tools like **PHP CLI**, **Composer**, **Git**, **Yarn** among many others.

Now that we have verified our containers are up and running, we can test connectivity to our PostgreSQL database.

### Verify PostgreSQL Database Connectivity

Let's view the postgresql database logs by running the command **docker logs** and providing the name of our container.

    docker logs duka-laradock_postgres_1

This should provide an output similar to the following: 

```bash
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /var/lib/postgresql/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok

...

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data -l logfile start

...

server started
CREATE DATABASE

/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/createdb.sh.example

/usr/local/bin/docker-entrypoint.sh: sourcing /docker-entrypoint-initdb.d/init_gitlab_db.sh
CREATE ROLE
CREATE DATABASE
GRANT
ALTER ROLE

...

2019-06-06 18:09:35.771 UTC [1] LOG:  database system is ready to accept connections

```

Now that our PostgreSQL is ready to accept connections, let's try connecting the database server using credentials we updated in the **.env** file by running the following command:

    docker-compose exec postgres psql -U homestead -d duka-db

Even though the container name is **duka-laradock_postgres_1**, the service name of the container is **postgres** as defined within the **docker-compose.yml** file. You can think of the service name as the computer name.

```bash
### PostgreSQL ###########################################
    postgres:
      build: ./postgres
      volumes:
        - ${DATA_PATH_HOST}/postgres:/var/lib/postgresql/data
        - ${POSTGRES_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
      ports:
        - "${POSTGRES_PORT}:5432"
      environment:
        - POSTGRES_DB=${POSTGRES_DB}
        - POSTGRES_USER=${POSTGRES_USER}
        - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
        ...
      networks:
        - backend
```

This should present us with an output similar to the following:
 
 ```bash
psql (11.3)
Type "help" for help.

duka-db=# 
 ```

The output confirms that we can access our PostgreSQL database server container using credentials contained within our **.env** file. 

Type **\l** and press the **Return** key to display databases available within the container.


```bash
duka-db=# \l
                                            List of databases
        Name         |   Owner   | Encoding |  Collate   |   Ctype    |         Access privileges         
---------------------+-----------+----------+------------+------------+-----------------------------------
 duka-db             | homestead | UTF8     | en_US.utf8 | en_US.utf8 | 
 laradock_gitlab     | homestead | UTF8     | en_US.utf8 | en_US.utf8 | =Tc/homestead                    +
                     |           |          |            |            | homestead=CTc/homestead          +
                     |           |          |            |            | laradock_gitlab=CTc/homestead
 laradock_jupyterhub | homestead | UTF8     | en_US.utf8 | en_US.utf8 | =Tc/homestead                    +
                     |           |          |            |            | homestead=CTc/homestead          +
                     |           |          |            |            | laradock_jupyterhub=CTc/homestead
 postgres            | homestead | UTF8     | en_US.utf8 | en_US.utf8 | 
 sonar               | homestead | UTF8     | en_US.utf8 | en_US.utf8 | =Tc/homestead                    +
                     |           |          |            |            | homestead=CTc/homestead          +
                     |           |          |            |            | sonar=CTc/homestead
 template0           | homestead | UTF8     | en_US.utf8 | en_US.utf8 | =c/homestead                     +
                     |           |          |            |            | homestead=CTc/homestead
 template1           | homestead | UTF8     | en_US.utf8 | en_US.utf8 | =c/homestead                     +
                     |           |          |            |            | homestead=CTc/homestead
(7 rows)

duka-db=# 
```

Our database **duka-db** has been created and is owned by role **homestead** as per the changes we made in **.env** configuration file.

Type **\q** and press the **Return** key to log out of the container.


### Creating Our Laravel Project

Run the following command against **workspace** service

    docker-compose exec --user=laradock workspace bash

The workspace container has tools that we will require during development (PHP7-CLI, Git, Composer etc). **laradock** user is created when the **workspace** container is being provisioned.

After the above command is executed, we will be presented with a terminal prompt:

```bash
laradock@c9aa984b7bfa:/var/www$ 
```

We can verify that Composer is already installed on the workspace container by running `composer --version`. Running `composer create-project --prefer-dist laravel/laravel .` to create the project in the current folder location will throw an `[InvalidArgumentException] Project directory ./ is not empty.` error.

![](https://thepracticaldev.s3.amazonaws.com/i/5g60bcrkp3bil5j3fbx6.png)

To avoid the error, we need to first install the Laravel installer by running the following command

        composer global require laravel/installer

Next we create the project using the Laravel installer 

        /home/laradock/.composer/vendor/bin/laravel new --force .

After the installation is complete, exit out of the container by typing `exit` and you should be back within **laradock-duka** folder. 

 ```bash
laradock@c9aa984b7bfa:/var/www$ composer global require laravel/installer

laradock@c9aa984b7bfa:/var/www$ /home/laradock/.composer/vendor/bin/laravel new --force .

laradock@c9aa984b7bfa:/var/www$ exit
 ```

If you navigate to the root of your project and list files, you will note that the project files created within the container are available on the host computer.

```bash
cd ..

ls -la
```

### Running Our Project

Open your browser and navigate to http://localhost and you should see the Laravel welcome screen

![](https://thepracticaldev.s3.amazonaws.com/i/cjy7qw56eqapl1ulymaw.png)

Open **resources/views/welcome.blade.php** file, scroll down and change content title  **Laravel** to **Hello Laravel**. Save the file and refresh your http://localhost  web page and you should now see the page has been updated.

![](https://thepracticaldev.s3.amazonaws.com/i/6sfef2tfgsokqh0ksdj7.png)

### Migrate and Seed the Database

Open **.env** within the root of the Laravel project and update the following variables from 

        DB_CONNECTION=mysql
        DB_HOST=127.0.0.1
        DB_PORT=3306
        DB_DATABASE=laravel
        DB_USERNAME=root
        DB_PASSWORD=

to the following

        DB_CONNECTION=pgsql
        DB_HOST=postgres
        DB_PORT=5432
        DB_DATABASE=duka-db
        DB_USERNAME=homestead
        DB_PASSWORD=secret

and when you are done, save the file

Navigate to the root of **duka-laradock** if you are within the root of the Laravel project

For the changes we have made to take effect, we need to re-create the containers using the following commands

```
 docker-compose down

docker-compose up -d nginx postgres
```

After the containers have been recreated, log in to the **workspace** service

    docker-compose exec --user=laradock workspace bash

Then migrate and seed the database

```
php artisan migrate --seed
```

If the process of migrating and seeding the database completes successfully, you should an output similar to the following

```
laradock@565deba12e1c:/var/www$ php artisan migrate --seed
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Database seeding completed successfully.
laradock@565deba12e1c:/var/www$ 
```

### Conclusion

This post walked through the steps required in setting up a development environment for Laravel using PostgreSQL database and Laradock. Using this approach, we eliminate any need of installing PHP or other tools that would be required in setting up a development environment on a local computer. After following this approach, you only require to navigate to your Laradock folder and run `docker-compose up -d nginx postgres` from the terminal to spin up all required tools to continue your development process.