I am learning deployment. I want to map my subdomain to my IP address with port 3010 which is AWS EC2 IP.
I have two applications:
- ReactJS Front end app running on port 3000,
- NestJs Backend app running on port 3010
I have an EC2 instance with IP 1.2.33.44
I have a domain - mydomain.com and a subdomain api.mydomain.com
I have successfully mapped my EC2 IP 1.2.33.44 to my FE app on port 3000 with the nginx server (mydomain.conf)
Now I am struggling to map my subdomain (api.mydomain.com) to my backend app which is running on port 3010
Here are my server files:
docker-compose.yaml
version: '3' # Use version 3 or higher
services: # Use 'services' (plural) to define your services
backend:
container_name: api_mydomain_container
image: api_mydomain_image
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 300M
build:
context: .
target: production
dockerfile: ./Dockerfile
command: npm run start:prod
environment:
- APP_ENV=PROD
env_file: .env
ports:
- '3010:3010'
volumes:
- .:/user/src/app
- /usr/src/app/node_modules
restart: unless-stopped
Dockerfile
# Build Stage
FROM node:18-alpine AS production
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install -g @nestjs/cli
RUN npm install --only=production
COPY . .
RUN npm run build
# Prod Stage
FROM node:18-alpine
WORKDIR /usr/src/app
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
ARG APP_ENV=PROD
ENV APP_ENV=${APP_ENV}
COPY --from=production /usr/src/app/dist ./dist
COPY package*.json ./nest-cli.json ./tsconfig.build.json ./tsconfig.json config ./
RUN npm install --only=production
CMD ["node", "dist/main.js"]
api.mydomain.conf (nginx config for api.mydomain.conf which is running on port 3010):
server {
listen 80;
server_name api.mydomain.com;
location / {
proxy_pass http://localhost:3010;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
mydomain.conf ( nginx config for mydomain.com which is running on port 3000):
server {
listen 80;
server_name mydomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Using the above configuration, when I try to open api.mydomain.com in the browser, it opens the FE app which is running on port 3000. I want, when I open http://api.mydomain.com it should hit my BE app APIs, as this is my API endpoint base URL. Please help me where I am doing wrong.
Thanks
There is something you are missing about the way DNS, IPs, and Ports work:
So, there is no direct way to map names to ports, they can only map to IP Addresses.
Here are a few approaches that I think accomplish your goal:
Simple but wonky: Map both of your domain names to the same IP. This will make the 2 names actually interchangeable and it its actually just the port number that controls whether you get the frontend responding or the backend responding.
Use More IPs. Either by giving the host 2 IPs and configuring each service to listen to a separate IP, or by splitting the task onto two hosts. Then you would map the DNS names to the 2 IPs and you would get what you need.
Use Name-based Routing. By using an Application Load Balancer, you can create a rule that routes traffic based on the name that was given in the request. You can have one domain name route to one port and the other domain name route to another port. This method is the most flexible and "correct" way, IMO.