I'm trying to dockerize an angular application with a spring boot one and setting a postgres Database. I setup everything but I'm having problems with nginx I suppose it doesn't forward the request to the backend application(spring boot), even though pinging works fine.
So I created a Dockerfile for the spring boot application :
# Use a base image with JDK and Maven installed
FROM maven:3.8.4-openjdk-17-slim AS build
# Set the working directory
WORKDIR /app
# Copy the pom.xml file to the working directory
COPY pom.xml .
# Copy the entire project to the working directory
COPY src ./src
# Build the application with Maven
RUN mvn clean package -DskipTests
# Use a smaller base image for the runtime environment
FROM amazoncorretto:17-alpine-jdk
# Set the working directory
WORKDIR /app
# Copy the built JAR file from the build stage to the runtime image
COPY --from=build /app/target/restaurant.jar ./app.jar
RUN mkdir /app/storage
# Expose the port that your Spring Boot application listens on (if applicable)
EXPOSE 8081
# Command to run the application
CMD ["java", "-jar", "app.jar"]
And I have setup as well application.properties to get environment variables like follows :
spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWD}
# Hibernate settings
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
# Application's server port
#server.port=8081
server.port=${SERVER_PORT}
spring.servlet.multipart.max-file-size=5GB
spring.servlet.multipart.max-request-size=5GB
files.folder=${STORAGE}
front.address=${FRONT_ADDR}
# Application's name
spring.application.name=NapolitanaBack
I have setup cors :
package com.napolitana.restaurant.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig {
@Value("${front.address}")
String frontAddress;
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(frontAddress)
//.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH")
.allowedHeaders("*");
}
};
}
}
For the angular application I have setup a Dockerfile :
# Base image with Node.js installed
FROM node:18.20.2 AS build
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json (if present) to the working directory
COPY package.json package-lock.json ./
# Install dependencies
RUN npm install
# Copy the entire project to the working directory
COPY . .
# Build the Angular app for production
RUN npm run build --prod
# Use NGINX base image for serving Angular application
FROM nginx:alpine
# Copy build artifacts from the build stage to NGINX public directory
COPY --from=build /app/dist/napolitana-front /usr/share/nginx/html
# Copy nginx.conf to configure the server
COPY default.conf /etc/nginx/conf.d/default.conf
# Expose the port that NGINX listens on
EXPOSE 80
# Command to start NGINX and serve the Angular app
CMD ["nginx", "-g", "daemon off;"]
with this default.conf configuration file in nginx server :
server {
listen 80;
server_name frontend;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:8081;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
location /admin/ {
alias /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /admin/index.html;
}
location ~ ^/admin/([a-zA-Z0-9\-_]+)/(.*)$ {
alias /usr/share/nginx/html/admin/$1/;
index index.html;
try_files $uri $uri/ /admin/$1/index.html;
}
}
While this is the base url used by services in this angular application :
export const environment = {
BASE_URL: 'http://backend:8081/api'
}
and finally this is the docker-compose.yml :
version: '3.8'
services:
postgres:
image: postgres:latest
restart: always
environment:
POSTGRES_DB: napolitana
POSTGRES_USER: gduser
POSTGRES_PASSWORD: gduser
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- napolitana-network
backend:
build:
context: ./NapolitanaBack
dockerfile: Dockerfile
image: backend-image:latest
ports:
- "8081:8081"
volumes:
- C:\Users\mr\Desktop\storage:/app/storage # Bind mount to local folder for shared data
environment:
- DB_URL=jdbc:postgresql://postgres:5432/napolitana
- DB_USERNAME=gduser
- DB_PASSWD=gduser
- SERVER_PORT=8081
- STORAGE=/app/storage
- FRONT_ADDR=http://frontend:80
depends_on:
- postgres
networks:
- napolitana-network
frontend:
build:
context: ./NapolitanaFront
dockerfile: Dockerfile
image: frontend-image:latest
ports:
- "80:80" # Map port 80 of the container to port 80 of the host
volumes:
- C:\Users\mr\Desktop\storage:/usr/share/nginx/html/assets/storage # Bind mount to local folder for shared data
depends_on:
- backend # Ensure backend service starts first
networks:
- napolitana-network
volumes:
postgres_data:
networks:
napolitana-network:
when I'm testing everything turns out the angular application can't resolve backend:8081, I mean I always get ERR_NAME_NOT_RESLOVED for each request made by angular like this :
I have tried lots of things but couldn't resolve the problem because I don't get it , is it a problem with nginx or CORS error or something else ?
And thanks in advance for anyone who is helping.
ERR_NAME_NOT_RESLOVED is a DNS error meaning that the hostname could not be resolved to an IP address. The issue likely is that even though your Angular app is hosted in a container, the code is actually running in your browser when you navigate to the app and the hostname is only resolved within the container network. See this related question, net::ERR_NAME_NOT_RESOLVED in browser using docker-compose.