Laravel Development Using PostgreSQL and Laradock

alt=Laradock image

In this post, we setup a Laravel development environment using PostgreSQL and Laradock. Laradock uses Docker to easily setup up a development environment for PHP projects. By using Docker, you eliminate the need to install PHP, Composer, Laravel or a database server on your local computer.

Requirements

  • Git 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 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 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:

              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:

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.

### 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:

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.

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:

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.

alt=

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.

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.

cd ..

ls -la

Running Our Project

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

alt=Laravel Welcome Screen

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.

alt=Laravel Welcome Screen

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.