NestJS, PostgreSQL, and Docker are three powerful tools that can help you build robust web applications quickly and easily. NestJS is a modern, progressive Node.js framework that allows you to build server-side applications using TypeScript. PostgreSQL is a powerful open-source database management system that provides reliable data storage and retrieval. Docker is a containerization platform that simplifies the deployment and management of applications.
These three tools provide a powerful toolkit for building scalable and efficient web applications. This article will give a beginner-friendly guide to using NestJS, PostgreSQL, and Docker to build a web application.
Repository
A progressive Node.js framework for building efficient and scalable server-side applications.
Description
Nest framework TypeScript starter repository.
Installation
$ npm install
Running the app
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
Test
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
Stay in touch
- Author - Kamil Myśliwiec
- Website - https://nestjs.com
- Twitter - @nestframework
License
Nest is MIT licensed.
Prerequisite
- Basic understanding of TypeScript, PostgreSQL, and RESTful APIs
- Docker Desktop installed on your computer (run the
docker -v
command to verify the installation); if not, install it from here
Setting Up a NestJS Application
We need node and its package manager npm to initialize a new project.
To install Node, we go to the Nodejs website and follow the instructions. We verify Node.js’ installation using the terminal command below:
node -v
v18.15.0 //node version installed
The result shows the version of Node.js we installed on our computer.
Next we’ll install NestJS globally and initialise a new project by running the command below in our terminal:
$ npm i -g @nestjs/cli
$ nest new nest-docker-postgres
Make sure to choose npm
as the package manager from the prompt.
Start the development server using the command below and visit http://localhost:3000/ to see the application running:
$ npm run start:dev
Containerizing the Application
To containerize our NestJS application, we first create a file named Dockerfile
in the root of our project and then a docker-compose.yml
file also in the root of our project.
The Dockerfile
sets up a container for running the application. It installs the necessary dependencies, copies the application code into the container, builds the application, and starts the server using the production build.
The docker-compose
file sets up a multi-container environment. In it, we would run the NestJS app with PostgreSQL and pgAdmin.
Dockerfile
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD [ "npm", "run", "start:dev" ]
Here's what each command in this file does:
FROM node:18
: Specifies the base image for the Docker container. We use the official Node.js18.x
image as the base in this case.WORKDIR /app
: Sets the working directory inside the container to/app
. This is where the application code will be copied and where the container will run from.COPY package*.json ./
: Copies thepackage.json
andpackage-lock.json
files from the current directory on the host machine to the/app
directory in the container. The*
inpackage*.json
allows us to copy both files at once.RUN npm install
: Installs the application dependencies in the container. This step uses thenpm install
command to install the dependencies listed inpackage.json
.COPY . .
: Copies the application code from the host machine to the/app
directory in the container.RUN npm run build
: Thenpm run build
command is used to build the application in the container. This command will typically create adist
folder with the production build of the application.CMD ["npm", "run", "start:dev"]
: Specifies the command to run when the container starts. In this case, we're running thenpm run start:dev
command, which will start the server in development mode. This command watches for changes in the code and automatically rebuilds the container when changes are detected. This allows for faster development cycles, as changes to the code can be quickly tested in the container without manual rebuilding or restarting.
docker-compose.yml
version: '3.5'
services:
db:
image: postgres
restart: always
environment:
- POSTGRES_PASSWORD=postgres
container_name: postgres
volumes:
- ./pgdata:/var/lib/postgresql/data
ports:
- '5432:5432'
app:
build:
context: .
dockerfile: Dockerfile
container_name: nest-docker-postgres
environment:
- PORT=${PORT}
ports:
- '3000:3000'
depends_on:
- db
volumes:
- ./src:/app/src
pgadmin:
image: dpage/pgadmin4
restart: always
container_name: nest-pgadmin4
environment:
- PGADMIN_DEFAULT_EMAIL=admin@admin.com
- PGADMIN_DEFAULT_PASSWORD=pgadmin4
ports:
- '5050:80'
depends_on:
- db
In this file:
version
: This field at the beginning of a Docker Compose file specifies the version of the Compose file format we’re using.db
: This service sets up a PostgreSQL database using the officialpostgres
image from Docker Hub. It sets the password for thepostgres
user topostgres
, creates a named volumepgdata
for storing the database data, and maps the container port5432
to the host port5432
. Therestart: always
option ensures that the container will automatically restart if it crashes or is stopped.app
: This service builds a Docker image for the NestJS app using theDockerfile
in the current directory. It sets the container name tonest-docker-postgres
, sets the environment variablePORT
to the value of the hostPORT
environment variable, maps the container port3000
to the host port3000
, and mounts thesrc
directory on the host to the/app/src
directory in the container. Thedepends_on
option specifies that this service depends on thedb
service, meaning that thedb
container will be started before theapp
container.pgadmin
: This service sets up pgAdmin, a web-based PostgreSQL administration tool, using thedpage/pgadmin4
image from Docker Hub. It sets the container name tonest-pgadmin4
, sets the default email and password for the pgAdmin login, maps the container port80
to the host port5050
, and specifies that this service depends on thedb
service.
We also need to add a new file called .dockerignore
. It specifies files and directories that .dockerignore
should exclude from a Docker build context.
.dockerignore
Dockerfile
.dockerignore
node_modules
npm-debug.log
dist
Building the containers
The next thing we need to do is build to run our app in Docker - building the containers. Run the command below to containerize the application:
$ docker compose up
The command looks for the services specified in the docker-compose.yml
file and creates containers for them. If the images required by those services are unavailable locally, Docker will pull them from Docker Hub or any other configured registry. If the images are already available locally, Docker will use them instead of pulling them again.
Once the containers are up and running, we can access the NestJS application by visiting http://localhost:3000 in our web browser and pgAdmin by visiting http://localhost:5050 in our web browser.
Login to pgAdmin by using the email and password we specified earlier in the docker-compose.yml
file, and then we will see this:
Setting up pgAdmin and PostgreSQL Server
To connect to the PostgreSQL server from PgAdmin, we need to create a server object in PgAdmin with the details of the PostgreSQL server.
Here are the steps to create a server in PgAdmin:
- Open PgAdmin in the web browser by visiting http://localhost:5050 (assuming we're using the default configuration in the
docker-compose.yml
file). - Log in using your email and password in the
docker-compose.yml
file for thepgadmin
service. - In the left-hand sidebar, click
Servers
to expand theServers
menu. - Right-click on
Servers
and selectRegister
->Server
. - In the
General
tab of theCreate - Server
dialog, we can give the server a name of our choice. - In the
Connection
tab, fill in the following details:- Host name/address: db
- Port: 5432
- Maintenance database: postgres
- Username: postgres
- Password: postgres
- Click
Save
to save the server configuration.
Note: Since the PostgreSQL server is running in a Docker container, the hostname/address would be the name of the Docker service for the database container as defined in the
docker-compose.yml
file. By default, the name of the service becomes the hostname/address of the container within the Docker network.
We should now see the server we created in the left-hand sidebar of PgAdmin. We can expand the server to see the databases and other objects within it.
Connecting to PostgreSQL Server from NestJS
Nest provides the @nestjs/typeorm
package for integrating with SQL and NoSQL databases. Install the packages using the command below:
$ npm install --save @nestjs/typeorm typeorm pg
Next, in the app.module.ts
file, add the following code in the imports
array:
TypeOrmModule.forRoot({
type: 'postgres',
host: 'db',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'postgres',
entities: [],
synchronize: true,
autoLoadEntities: true,
}),
We import the TypeOrmModule
from the @nestjs/typeorm
package.
We pass an options
object to the TypeOrmModule
to configure the PostgreSQL connection details. The type
option specifies the database management system being used, PostgreSQL. The host
, port
, username
, password
, and database
options provide the connection details for the PostgreSQL server.
We use the entities
option to specify the entities that the application uses. Entities represent the data models in the application and can be used to query the database. We don't specify entities in this case because we dynamically load them by setting autoLoadEntities
to true
.
We set the synchronize
option to true
, which means that TypeORM will automatically generate database tables based on the entities. However, this option should be used with caution in production because it can cause data loss and conflicts.
To rebuild our app container because of the changes made, we execute the command below:
$ docker compose up --build
And voila, our app is connected to the PostgreSQL server running in Docker. We can now start to create entities and build APIs on top of them.
Conclusion
In conclusion, we have seen how to set up a NestJS application with Docker and PostgreSQL in a step-by-step guide. Using Docker and PostgreSQL in combination with NestJS can make your web application development faster and more efficient.
Top comments (9)
Great tut! I haven't touched Docker in a while, I did however encounter "file write permission" errors, I'm guessing this is due to using
/app
instead of/usr/src/
app as a working directory?Great article. Thanks for sharing!
It's my pleasure
thank you!
Really simple and easy to understand!
Thanks for sharing this with us!
Thank You. It was awesome. With some personal tweaking according to my application. I finally deployed my application to the docker server.
Really simple and easy to understand!
Thanks for sharing this with us!
I'm glad it helped you. My pleasure
Would you be able to highlight the changes needed to use mysql? That's all my company uses at this time.