Showing NginX welcome page after Dockerizing - docker

I have Dockerized my Nextjs App. It builds fine. But after building, it keep showing the nginx welcome page, not the actual home page of my application. Tried many things, it doesn't fix. It remains the same on server too. What is the problem in my setup.
Here I am attaching my files.
This is my Dockerfile
FROM node:14.16.0 as builder
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY ./package.json /app/
RUN npm install
COPY . /app
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]
This is my Docker-compose.yml
version: "3.8"
services:
app:
container_name: kup-frontend
image: kup-frontend
build:
context: .
dockerfile: ./Dockerfile
ports:
- 3000:3000
volumes:
- .:/app
- /app/node_modules
- /app/build
restart: unless-stopped
environment:
- PORT=3000
This is my nginx.conf file
server {
listen 3000;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

Related

Upload file to dockerized app on the fly, then serve

I've got a Python web app that runs inside two Docker containers, one for the FastAPI backend, the other for the Vue.JS front-end (and there's besides a third one, with the Postgres Db). Now my task is to upload a file from inside the front-end client to the server, store it permanently and serve, so that I can use static URLs in my img tags.
A possible similar question is here: How to upload file outside Docker container in Flask app But it concerns an approach where the server must be restarted upon upload to reflect the changes. I need to do everything on the fly, as the app is running.
Dockerfile for front-end:
FROM node:16.14.2 as builder
WORKDIR /admin
COPY package*.json ./
COPY vite.config.js ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:1.21
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /admin/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Dockerfile for backend:
FROM tiangolo/uvicorn-gunicorn:python3.9
EXPOSE 8000
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY ./requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt
WORKDIR /app
COPY . /app
I can certainly transfer a file (as raw bytes stream) from the front-end to the backend via Axios and receive it on the backend Python side. I can then process it however I like. But how can I store it in the location where the front-end container could read it and serve statically?
UPDATE (Use Docker Volumes)
As suggested in this question, I've tried to use a shared volume for my purpose. My COMPOSE file now looks like this:
version: "3.8"
services:
use_frontend:
container_name: 'use_frontend'
# --> ADDED <--
volumes:
- 'myshare:/etc/nginx'
- 'myshare:/usr/share/nginx/html'
build:
context: ./admin
dockerfile: Dockerfile
restart: always
depends_on:
- use_backend
ports:
- 8090:80
use_db:
container_name: use_db
image: postgres:14.2
# etc etc...
use_backend:
container_name: 'use_backend'
volumes:
# --> ADDED <--
- 'myshare:/usr/share/nginx/html'
build:
context: ./api
dockerfile: Dockerfile
restart: always
depends_on:
- use_db
# etc etc...
# --> ADDED <--
volumes:
myshare:
driver: local
The Dockerfile for use_frontend hasn't changed (must it?)
FROM node:16.14.2 as builder
WORKDIR /admin
# copy out files for npm
COPY package*.json ./
COPY vite.config.js ./
# install and build Vue.js
RUN npm install
COPY . .
RUN npm run build
# Nginx image
FROM nginx:1.21
# copy Nginx conf file to VOLUME mounted folder
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# clean everything in VOLUME mounted folder (app entry point)
RUN rm -rf /usr/share/nginx/html/*
# copy compiled app to to VOLUME mounted folder (app entry point)
COPY --from=builder /admin/dist /usr/share/nginx/html
# expose port 80 for HTTP access
EXPOSE 80
# run Nginx
CMD ["nginx", "-g", "daemon off;"]
The Nginx conf file hasn't changed either:
events {}
http {
server {
listen 80;
# app entry point
root /usr/share/nginx/html;
# MIME types
include /etc/nginx/mime.types;
client_max_body_size 20M;
location / {
try_files $uri /index.html;
}
# etc etc...
}
}
But after doing
docker compose build
docker compose up
I'm getting file not found errors from Nginx:
use_frontend | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
use_frontend | /docker-entrypoint.sh: Configuration complete; ready for start up
use_frontend | 2022/07/24 23:21:32 [emerg] 1#1: open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
use_frontend | nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
What exactly am I doing wrong with the Docker volume mounting?

Unable to load Vue app's js and css files with Nginx

I'm trying to deploy a Vue js app using docker-compose and Nginx. I'm pretty beginner with Nginx and after searching through StackOverflow and blogs, the website returns blank page (containing vue's index.html page, but unable to load any js or CSS file).
Here is my config:
# docker-compose.yml
version: "3.8"
services:
web:
build: ./web
ports:
- 8080:8080
volumes:
- ./dist:/app
depends_on:
- nginx
nginx:
build: ./nginx
ports:
- 80:80
volumes:
- ./dist:/app
restart: always
# ./web/Dockerfile
FROM node:lts-alpine as build-stage
RUN npm install -g http-server
WORKDIR /app
COPY package*.json ./
RUN npm cache clean --force && npm install
COPY . .
RUN npm run build
EXPOSE 8080
CMD [ "http-server", "dist" ]
# ./nginx/Dockerfile
FROM nginx:1.21-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
upstream client {
server web:8080;
}
server {
listen 80;
include /etc/nginx/mime.types;
location / {
proxy_pass http://client;
root /app;
index index.html;
try_files $uri $uri/ /index.html;
include /etc/nginx/mime.types;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
}
Brower console when I open the website:
And nginx log show the following error:
[error] 22#22: *12 open() "/etc/nginx/html/css/app.68c1e752.css" failed (2: No such file or directory),
What should I do to fix this issue?
What you'd typically do is have a single, multi-stage frontend image like in the Dockerize Vue.js App Real-World Example that builds your app and copies the dist contents into NGINX's webroot. You don't need separate NGINX and http-server images because NGINX is already a server (and a much better one)
# docker-compose.yml
version: "3.8"
services:
nginx:
build: ./nginx
ports:
- 80:80
restart: always
# ./nginx/Dockerfile
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Your NGINX config really only needs the try_files declaration for HTML5 History Mode.

Using docker to deploy Vue frontend and .net backend, frontend not resolving backend container name

I am trying to deploy a Vue app in the frontend and the .net core api in the backend. Using docker-compose file I have been to able to spin up the network and containers but I am struggling to have them communicate. I am pretty new to docker however, do understand that the Vue app dockerfile uses an Nginx base to feed the web app but it seems that may be affecting the network communication as the frontend container does not resolve the backend container name though it should since they are in the same virtual private network with the default bridge driver. When executing a bash shell in the frontend container and doing a curl to the backend container, I do get the correct response.
I did try to expose the backend container to the host and then use the server IP to reach it from the frontend and that does work however, I was hoping to not have to expose my api this way and wanted to make it work through the docker virtual private network if possible.
Example url I am trying in the frontend which encounters a name not resolved error: littlepiggy-api/api or littlepiggy-api:5000/api
Frontend Dockerfile
FROM node:14.18-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Backend Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 5000
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["LittlePiggy.Api/LittlePiggy.Api.csproj", "LittlePiggy.Api/"]
RUN dotnet restore "LittlePiggy.Api/LittlePiggy.Api.csproj"
COPY . .
WORKDIR "/src/LittlePiggy.Api"
RUN dotnet build "LittlePiggy.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "LittlePiggy.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "LittlePiggy.Api.dll"]
Docker-compose file
version: '3'
services:
front:
container_name: littlepiggy-front
image: josh898/angie-app-front:latest
ports:
- 80:80
networks:
- littlepiggy
depends_on:
- api
api:
container_name: littlepiggy-api
image: josh898/angie-app-backend:latest
networks:
- littlepiggy
networks:
littlepiggy:
driver: bridge
You need to configure Nginx to pass requests that match the /api route on to the backend service.
If you create a nginx configuration file like this, called nginx.conf and place it in your frontend directory
server {
listen 80;
location / {
index index.html;
root /usr/share/nginx/html;
try_files $uri $uri/ $uri.html =404;
}
location /api/ {
proxy_pass http://littlepiggy-api/;
}
}
Then copy it into your frontend container by changing your frontend Dockerfile to
FROM node:14.18-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Then requests to http://localhost/api/xxxx should be passed on to the backend and requests to http://localhost/index.html should be served by the Nginx container directly.

Building multi-container docker-compose fails to build frontend

this is my first time deploying a MERN stack application using docker-compose. The backend (Express Server & MongoDB) is working well. I can post data with Postman and fetch data successfully. But my React app with NGINX conf proxy is returning an error during build.
production_frontend_1 exited with code 127
frontend_1 | /docker-entrypoint.sh: exec: line 38: yarn: not found
frontend_1 | /docker-entrypoint.sh: exec: line 38: yarn: not found
Here's my React Dockerfile
FROM node:12.18.2 as build
# RUN npm install -g yarn
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN yarn install && yarn cache clean
COPY . /app
ARG SERVER_APP_API
ARG SERVER_REST_API
ENV SERVER_REST_API ${SERVER_REST_API:-http://localhost:7000/api/v1/}
RUN SERVER_REST_API=${SERVER_REST_API} yarn run build
# ------------------------------------------------------
# Production Build
# ------------------------------------------------------
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Here's my NGINX.conf
server {
listen 80;
server_name localhost;
location / {
# This would be the directory where your React app's static files are stored at
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Here's my docker-compose.yml
version: '3.8'
services:
backend:
ports:
- 5555:5555
build:
context: ./backend
dockerfile: ./Dockerfile
restart: unless-stopped
networks:
- developer-tier
depends_on:
- db
command: npm run start
env_file: ./backend/.env
environment:
- CLIENT_URL=http://localhost:3001/
- NODE_ENV=production
- DATABASE_URL=mongodb://db:27017/developer
frontend:
stdin_open: true
build:
context: ./frontend
dockerfile: ./Dockerfile
ports:
- 3001:3001
restart: unless-stopped
depends_on:
- backend
env_file: ./frontend/.env
networks:
- developer-tier
volumes:
- ./frontend/:/frontend/src/app
- /app/node_modules/
command: yarn start
db:
image: mongo:latest
ports:
- 27017:27017
restart: always
networks:
- developer-tier
volumes:
- dev-data:/data/db
volumes:
dev-data:
driver: local
networks:
developer-tier:
driver: bridge

Nginx is not working with docker-compose for react app

I have created nginx config, DockerFile, Docker-compose file for the same.
nginx/nginx.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
DockerFile
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm ci --silent
RUN npm install react-scripts#3.4.1 -g --silent
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
docker-compose.yml
version: "3.7"
services:
client:
container_name: client
build:
context: .
dockerfile: Dockerfile
ports:
- 3001:3000
Now after doing docker-compose up --build
I get the logs as
client | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
client | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
client | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
client | 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
client | 10-listen-on-ipv6-by-default.sh: error: /etc/nginx/conf.d/default.conf differs from the packages version
client | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
client | /docker-entrypoint.sh: Configuration complete; ready for start up
I am not sure, if the problem is due to different packages version or something else but when tried to visit the url it says this site can’t be reached.
You didn't specify which url you are using, but it looks like your nginx is exposed on port 80. You need to expose that port in docker compose. Include under the ports:
- 80:80

Resources