Backend Development Plan
In this article, we'll guide you through our backend development plan, focusing on three key areas to ensure a smooth setup with Docker:
- Framework Choice: We selected NestJS as our framework because it's efficient and scalable, perfect for building a solid foundation.
- User Authentication: We're using Keycloak to manage user roles effectively, ensuring secure and streamlined access for all users.
- Containerization: To make everything run smoothly, we'll be dockerizing our backend. Docker helps maintain consistency across environments, simplifying development, deployment, and scaling.
Project setup
I started by creating a project directory and setting up a Docker environment for the application. Despite limited Docker experience, I successfully configured the containers and got the app running. Below are the steps I followed.
Creating the Dockerfile
First, I created a Dockerfile with the following content:
# Use the official Node.js image
FROM node:20-alpine
# Set the working directory
WORKDIR /usr/src/app
# Copy package.json and package-lock.json
COPY app/package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code
COPY app .
# Expose the application port
EXPOSE 3000
# Command to run the application
CMD ["npm", "run", "start:dev"]
This Dockerfile pulls an official Node.js image, sets the working directory, installs the necessary dependencies, and finally copies the application code. The application is then exposed on port 3000.
Creating Docker-compose
Next, I created a docker-compose.yaml file to manage the services, with the following content:
services:
postgres:
image: postgres:16.3
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
networks:
- keycloak_network
keycloak:
image: quay.io/keycloak/keycloak:25.0.2
command: start-dev
environment:
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 8080
KC_HOSTNAME_STRICT_BACKCHANNEL: false
KC_HTTP_ENABLED: true
KC_HOSTNAME_STRICT_HTTPS: false
KC_HEALTH_ENABLED: true
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres/${POSTGRES_DB}
KC_DB_USERNAME: ${POSTGRES_USER}
KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
KC_LOG_LEVEL: DEBUG # development
ports:
- 8080:8080
restart: always
depends_on:
- postgres
networks:
- keycloak_network
pgadmin:
image: dpage/pgadmin4:latest
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
ports:
- 5050:80
depends_on:
- postgres
networks:
- keycloak_network
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./app:/usr/src/app # used for hot reloading only in development
ports:
- 3000:3000
depends_on:
- postgres
networks:
- keycloak_network
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_HOST: postgres
volumes:
postgres_data:
driver: local
networks:
keycloak_network:
driver: bridge
This configuration defines multiple services: PostgreSQL for database management, Keycloak for authentication, pgAdmin for database administration, and the application itself. The services are connected via a shared Docker network, keycloak_network, and necessary environment variables are defined to maintain security and flexibility.
Creating .env file
To manage sensitive information and configuration settings, I created a .env file. This file allows easy modification of settings without hardcoding them in the configuration files:
POSTGRES_DB=lovecdb
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=adminpassword
[email protected]
PGADMIN_DEFAULT_PASSWORD=adminpassword
Storing credentials and other environment-specific variables in a .env file helps keep your configuration clean and secure. Since this project is running locally, there's no immediate need to include the .env file in your .gitignore. However, if you plan to share or deploy the project, it's a good practice to add it to your .gitignore to prevent sensitive information from being exposed.
Running the Application
Create a New NestJS project
I began by creating a new NestJS project using the NestJS CLI. I navigated to the directory and ran the following command:
nest new app
This initialized a new NestJS project inside the app directory, setting up the basic structure and files I needed to get started.
Running the containers
With the NestJS project in place, I then focused on setting up my Docker environment. I ensured that Docker was running on my machine and returned to the root directory containing the docker-compose.yaml file.
To launch all the necessary services, including PostgreSQL, Keycloak, pgAdmin, and the application itself, I ran:
docker compose up -d
This command started all the services in detached mode, allowing them to run in the background.
Once everything was up and running, I could access the various services through my browser:
- The main app can be accessed at localhost:3000.
- Keycloak can be accessed at localhost:8080.
- pgAdmin can be accessed at localhost:5050.
Conclusion
This is how I did our backend setup, ensuring a consistent, scalable, and secure environment using Docker, NestJS, and Keycloak. I hope you find this helpful!
In the next article, I'll guide you through configuring Keycloak with NestJS, connecting it to PostgreSQL, and exploring some other exciting features.
Happy coding!