Full-Stack To-Do List application with Node, NestJS, Angular 2+, Postgres, Liquibase and Docker (Part 1 of 9)


This multi-part series will cover how to build a Full-Stack To-Do List application with Node, NestJS, Angular 2+, Postgres, Liquibase and Docker.

This also might be a good time to coin a new acronym in the Dev world, ‘cause that’s what all the cool kids do. You might have heard of the MEAN stack, or maybe the MERN stack. Well let me introduce you to the ✨ PLANN stack ✨.

The Stack

Our API Framework of choice will be NestJS, a robust and ‘Angular-like’ framework for building server side applications. We’ll let Angular 2+ and the Angular Material UI component library help us build a Client-Side application quickly and efficiently. All of this will be backed by a dead-simple Postgres database spun up in a Docker container for ease of use. And we’ll let Liquibase make sure that our Database is portable, stable, consistent, and 🎉 easy 🎉.

As Node developers, you’ve probably never heard of the Database Migration tool Liquibase. If you have ✨ y o u w i n ✨. You also might not have ever heard of Database Migrations in general, especially if you use an ORM like TypeORM. Tools like this try to hide the Database Migration problem behind a Developer-Friendly interface. But these tools are only as flexible as they can be, and there is a pretty good chance that eventually you will reach the end of your ORM rope. This is where Liquibase really shines 🌞.

GitHub Repo

Be sure to check out my GitHub Repo for this project. There is a *-start and *-finish branch for each phase of the process. Also a working and finished POC can be found on the master branch.

💪 Before we get started let’s clone that repo! 💪

git clone git@github.com:tabuckner/fullstack-todo-angular-nest-postgres-liquibase.git

Database Setup

If you haven’t heard by now, Docker is the way all us cool kids easily create and destroy services of all shapes and sizes. For this project we’ll use it to quickly spin up a couple of containers. One for our Postgres Database and another for pgAdmin, a slick browser based tool that allows us to peek into our Database in real time. Check out this article from my CTO, R2, for another approach to starting a Postgres docker container.

The Branch

The branch we’ll start with for this section is called db-setup . Let’s check it out with:

git checkout origin db-setup

Then since we’re going to be doing work on our DB service in our Monorepo, let’s change into that directory with:

cd ./db

The Fast Track

If you’re impatient like myself, or if you don’t want to spend too much time learning how to set the Postgres Database and pgAdmin manually, feel free to use the start-up.sh and clean-up.sh scripts located in ./db of the project repo linked above.

These scripts will take care of starting and stopping the Postgres Database and pgAdmin services.

If you’d like to dive a little deeper into how to set this up on your own, be sure to read the next few sections

Docker Network

We’re going to make use of a named Docker Network to let our Postgres and pgAdmin containers talk to each other more easily.

To create the network run:

docker network create --driver bridge fullstack-todo-pgnetwork

Postgres Container

Now that we have our network, let’s build our Postgres container:

docker build -t fullstack-todo/db 

Once that completes, we’ll then need to run the container:

docker run --publish 5432:5432 --network=fullstack-todo-pgnetwork fullstack-todo/db

🚀 Now we should have a Postgres container running on our newly created fullstack-todo-pgnetwork network.

pgAdmin Container

pgAdmin can be used to take a peek into any number of Postgres Databases using a browser based interface. Luckily, we can spin up a container for this too! We’ll use our newly created docker network, fullstack-todo-pgnetwork and pass in a number of other arguments.

docker run --publish 5050:5050 \
--volume=fullstack-todo-pga4volume:/var/lib/pgadmin \
--env-file=pgadmin-env.list \
--name="fullstack-todo-pgadmin4" \
--hostname="fullstack-todo-pgadmin4" \
--network="fullstack-todo-pgnetwork" \
--detach \

Here we grab an existing pgadmin4 container, publish its internal port 5050 externally as 5050, map a docker volume to a persistence layer inside the container, and pass in some other doo-dads to get this puppy up and running! 🏃

Now we should be able to hit in our browser, use the following login credentials:

# From pgadmin-env.list or start-up.sh

and see something like this:

pgAdmin Web Based UI

😎 Okay, sweet! 😎

So we’ve got access to our pgAdmin UI, and we’ve got our Postgres Database running in a container. Let’s see if we can get the two to talk to each other.

First click “Add New Server”

Name the Connection:

Create Server Dialog Tab 1

Add in our connection details with the following Postgres Database username and password:

# From pg-env.list or start-up.sh

After clicking “Save” you should see something like this in the tree to the left of pgAdmin:

Successfully adding our Postgres Database to pgAdmin.

Here we can see that we’ve connected to our fullstack-todo-db Postgres Container and we’ve accessed the dev database within. In our Schemas list we can see the app_schema that was created by the SQL script ./db/postgres-init.sql. This will give us a playground for our application development.

Now let’s get the Liquibase CLI set up!


So thus far we have:

  • A containerized Postgres Database
  • A containerized pgAdmin service wired up to our Postgres Database

Focusing on the Front End.