Installing and customizing Postgres and Redis in a Docker Laravel environment

A free screencast (video) course is available for this post but you need to be signed in order to view it, you can sign in here if you already have an account or register here if you don't have one.

Let's configure Postgresql and Redis in our docker-compose.yml and our Laravel application so we can use Postgresql as a database backend and Redis as a cache server.

  • Add the two new services (Postgres and Redis) to the docker-compose.yml file:
version: "3.7"
# creates the volumes to use with postgres and redis so we have data persistence
volumes:
    postgres-data:
    redis-data:
networks:
    frontend:
    backend:
services:
    proxy:
        image: nginx:latest
        ports:
            - "8080:80"
        volumes:
            - ./:/var/www/app
            - ./docker/nginx/nginx-site.conf:/etc/nginx/conf.d/default.conf
        networks:
            - frontend
            - backend
    php:
        build:
            context: ./docker/php
            dockerfile: Dockerfile
        image: laravelgis-php:latest
        volumes:
            - ./:/var/www/app
        networks:
            - backend
# the postgres service using the latest official image, it also maps the postgres-data volume
# to /var/lib/postgresql/data in the container, maps the local port 5432 to the container 
# port 5432 and specifies the database, user and password to use (they will be created the first time
# the container is run).
     postgres:
         image: postgres:latest
         volumes:
             - postgres-data:/var/lib/postgresql/data
         ports:
             - "5432:5432"
         environment:
             POSTGRES_PASSWORD: 12345
             POSTGRES_USER: laravelgis
             POSTGRES_DB: laravelgis
             PGDATA: /var/lib/postgresql/data
         networks:
             - backend
# the redis service using the latest official image and mapping the redis-data volume to
# /data in the container as well as local port 6379 to container port 6379.
     redis:
         image: redis:latest
         sysctls:
             - net.core.somaxconn=511
         ports:
             - "6379:6379"
         volumes:
             - redis-data:/data
         networks:
             - backend

The last changes to the docker-compose.yml file will:

  • create two local docker volumes to store database and cache files;
  • add a Postgres service based on the latest official docker image, using the postgres-data volume and create a database called laravelgis and a user called laravelgis with password 12345 (security is not an issue as it's a development environment, never use weak passwords in production!);
  • add a Redis service based on the latest docker official image using the redis-data volume.

Now, when you run "docker-compose up" again, you should be able to access Postgres on your development host on port 5432 and Redis on port 6379 with any cli/gui client.

  • Now lets ajust our .env file with the new services:
APP_NAME=Laravel
APP_NAME="Laravel GIS Project"
APP_ENV=local
APP_KEY={YOUR_APP_KEY}
APP_DEBUG=true
APP_URL=http://localhost
APP_URL=http://localhost:8080

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=laravelgis
DB_USERNAME=laravelgis
DB_PASSWORD=12345

BROADCAST_DRIVER=log
CACHE_DRIVER=file
CACHE_DRIVER=redis
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

(...)

  • Rerun "docker-compose up" and then run "docker exec -it laravel-gis_php_1 php artisan migrate", the initial Laravel migrations should now run correctly against our postgres service:

Laravel, Postgres and Redis

Note, you can run "docker-compose up -d" to have your stack running in the background and then "docker-compose stop" or "docker-compose down" to stop or altogether remove the containers.

  • You can probably see the pattern, you can run "docker exec -it laravel-gis_php_1" and then any command you would typically run in a Laravel application; knowing this, we can add it in our ~/.bash_aliases file:
alias dr="docker exec -it laravel-gis_php_1"
  • After saving the file, run "source ~/.bashrc" (or relaunch your terminal) and you should be able to install the frontend dependencies like this (pretty much like you would do with Laravel Sail):
dr npm install
  • Finally, we will install Laravel Jetstream which will provide us with a terrific authentication boilerplate and most of the libraries we will use (Laravel Livewire, Alpine.js and Tailwind CSS):
dr composer require laravel/jetstream
dr php artisan jetstream:install livewire
dr npm install
dr npm run build
dr php artisan migrate
  • You can now browse to "http://localhost:8080/register" you should see the Jetstream Register form like the screen below. You can register a user to use for development.

Laravel, Postgres and Redis

We now have a fully functional Laravel / php development environment running in docker with Postgres as a database and Redis as a cache repository; in the next post, we will leave the backend a little and peak into the frontend with OpenLayers.

The commit for this post is available here (the content of the .env file is commited in the .env.example file: laravel-postgres-and-redis

First published 2 years ago
Latest update 1 year ago
wim debbaut
Posted by wim debbaut 1 year ago

in running "sudo docker exec -it laravel-gis_php_1 php artisan migrate" I get the error:

Illuminate\Database\QueryException

SQLSTATE[08006] [7] could not translate host name "postgres" to address: Temporary failure in name resolution (SQL: select * from information_schema.tables where table_catalog = laravelgis and table_schema = public and table_name = migrations and table_type = 'BASE TABLE')

at vendor/laravel/framework/src/Illuminate/Database/Connection.php:760 756▕ // If an exception occurs when attempting to run a query, we'll format the error 757▕ // message to include the bindings with SQL, which will make this exception a 758▕ // lot more helpful to the developer instead of just the database's errors. 759▕ catch (Exception $e) { ➜ 760▕ throw new QueryException( 761▕ $query, $this->prepareBindings($bindings), $e 762▕ ); 763▕ } 764▕ }

  +39 vendor frames 

40 artisan:35 Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Anu ideas ?


wim debbaut
Posted by wim debbaut 1 year ago

I got the previos error solved by now, but stumbling on the last dr command "dr php artisan migrate" now. The thrown error is:

INFO Running migrations.

2023_01_30_114338_create_sessions_table ................................................................................................. 2ms FAIL

Illuminate\Database\QueryException

SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "sessions" already exists (SQL: create table "sessions" ("id" varchar(255) not null, "user_id" bigint null, "ip_address" varchar(45) null, "user_agent" text null, "payload" text not null, "last_activity" integer not null))

at vendor/laravel/framework/src/Illuminate/Database/Connection.php:760 756▕ // If an exception occurs when attempting to run a query, we'll format the error 757▕ // message to include the bindings with SQL, which will make this exception a 758▕ // lot more helpful to the developer instead of just the database's errors. 759▕ catch (Exception $e) { ➜ 760▕ throw new QueryException( 761▕ $query, $this->prepareBindings($bindings), $e 762▕ ); 763▕ } 764▕ }

  +9 vendor frames 

10 database/migrations/2023_01_30_114338_create_sessions_table.php:16 Illuminate\Support\Facades\Facade::__callStatic("create")

  +26 vendor frames 

37 artisan:35 Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

webgisdev
Posted by webgisdev 1 year ago

Hello wim,

Try running:

dr php artisan migrate:fresh

instead of

dr php artisan migrate

Cheers!

wim debbaut
Posted by wim debbaut 1 year ago

Spot on !

Works like a charm, moving on to the next step-by-step by now: OL - a lot front-end appbuilding. Great tutorial by the way and up to date.

webgisdev
Posted by webgisdev 1 year ago

Thank you!

Kyle
Posted by Kyle 1 year ago

Hi all,

    I'm having some issues getting connected to the postgres container. I have set my environment variables, but I keep getting messages that the authentication failed because the Role "laravelgis" does not exist. I have tried from outside and inside the container. It seems to create the database and it says it's ready to accept connections, but no love. Any ideas?

webgisdev
Posted by webgisdev 1 year ago

Hi Kyle,

Is the POSTGRES_USER variable properly configured in the environment sections of the postgres service in your docker-compose.yml file?

You can try to do:


docker-compose down

docker volume rm laravel-gis_postgres-data

docker-compose up -d

Hope it helps!

Kyle
Posted by Kyle 1 year ago

That worked! Thank you! I was having issues with fat fingering some of the login information so I updated my docker-compose to use variables from my .env file.

environment:

  	 POSTGRES_USER: ${DB_USERNAME}

	 	 POSTGRES_PASSWORD: ${DB_PASSWORD}

	   POSTGRES_DB: ${DB_DATABASE}

	 	 PGDATA: /var/lib/postgresql/data

It still didn't work though. I tried closing everything down, building a fresh image. This is what did the trick though. Now on to the rest!

You need to be signed in to post comments, you can sign in here if you already have an account or register here if you don't.