I have a problem with configuring the Nginx base image (any version),
-the application from stage one needs to be copied to the HTTP server and set to be the default launched and displayed as the default (start) page
- operation correctness checking is to be included (HEALTHCHECK)
My Dockerfile:
# Stage 1: Build Stage
FROM node:alpine AS builder
# Install build dependencies
RUN apk add --update curl && \
rm -rf /var/cache/apk/*
WORKDIR /usr/app
# Copy package.json and install dependencies
COPY ./package.json ./
RUN npm install
# Copy application code
COPY ./index.js ./
# Stage 2: Runtime Stage
FROM nginx:latest
# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
# Copy built files from the builder stage
COPY --from=builder /usr/app /usr/share/nginx/html
# Set working directory
WORKDIR /usr/share/nginx/html
# Expose port
EXPOSE 80
# Define version argument
ARG VERSION
ENV VERSION=production.${VERSION:-v1.0}
# Health check configuration
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:80/ || exit 1
# Command to run the application
CMD ["nginx", "-g", "daemon off;"]
My nginx.conf:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# Health check
location /healthcheck {
access_log off;
return 200 'OK';
}
}
Rest of code:
const express = require('express');
const os = require('os');
const app = express();
const port = 8084;
app.get('/', (req, res) => {
let response = `Adres IP serwera: ${getIPAddress()}\n`;
response += `Nazwa serwera (hostname): ${os.hostname()}\n`;
response += `Wersja aplikacji: ${process.env.VERSION}\n`;
res.send(response);
});
app.listen(port, () => {
console.log(`Aplikacja jest dostępna na porcie ${port}`);
});
function getIPAddress() {
const interfaces = os.networkInterfaces();
for (const dev in interfaces) {
const iface = interfaces[dev].filter(details => details.family === 'IPv4' && !details.internal);
if (iface.length > 0) return iface[0].address;
}
return '0.0.0.0';
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Web App</title>
</head>
<body>
<h1>Welcome to Simple Web App</h1>
<p>This is a simple web application.</p>
<p>Server IP Address: [SERVER_IP_ADDRESS]</p>
<p>Server Hostname: [SERVER_HOSTNAME]</p>
<p>Application Version: [APP_VERSION]</p>
</body>
</html>
I use this commands to run image:
docker build --build-arg VERSION=3.0.0 -f Dockerfile10 -t local/base:v10 . -> created successfully
docker run -d -p 8093:8080 --name web13 local/base:v10 -> (health: starting)
curl http://localhost:8093 -> curl: (52) Empty reply from server
docker logs -> The error message "directory index of '/usr/share/nginx/html/' is forbidden" indicates that Nginx is trying to serve the root directory but cannot find an index file to display. ( i have index.html in my directory with rest of files)
There are no HTML files in your image.
You should be able to verify this by running
docker run --rm local/base:v10 \
ls /usr/share/nginx/html
What is in your image? I only see this setup
WORKDIR /usr/app
COPY ./package.json ./
RUN npm install
COPY ./index.js ./
FROM nginx:latest
COPY --from=builder /usr/app /usr/share/nginx/html
That is: the only things in the base image's /usr/app
directory are package.json
, a node_modules
directory, and index.js
. Those things get copied into the final image. But none of those are HTML files. This means there's not an index.html
file in the final image, which results in the permission error you're getting.
If your local tree has a matching index.html
file, then it's enough to COPY
it into your build image.
COPY index.html index.js ./
# ^^^^^^^^^^ add?
If you have a single-page application that you build with a tool like Webpack, you need to make sure you run the build step in the base image. In the final image you'd need to copy the built directory and not the base source tree.
FROM node:alpine AS builder
WORKDIR /usr/app
COPY ./package*.json ./
RUN npm ci
COPY ./index.js ./
RUN npm run build # <-- add
FROM nginx:latest
COPY --from=builder /usr/app/dist /usr/share/nginx/html
# ^^^^