From 04dfaa3bd5c4f1bbc1687db88f865ae18c74c7dc Mon Sep 17 00:00:00 2001 From: pawan-59 Date: Mon, 10 Feb 2025 15:05:52 +0530 Subject: [PATCH 01/15] updated golang version to 1.23 --- sample-docker-templates/go/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-docker-templates/go/Dockerfile b/sample-docker-templates/go/Dockerfile index d868e7c930..df2846bafa 100644 --- a/sample-docker-templates/go/Dockerfile +++ b/sample-docker-templates/go/Dockerfile @@ -1,6 +1,6 @@ ################################# Build Container ############################### -FROM golang:1.16 as builder +FROM golang:1.23 as builder # Setup the working directory WORKDIR /app From e09f6adde5635186e33f4c9524239fbadee98cf2 Mon Sep 17 00:00:00 2001 From: pawan-59 Date: Mon, 10 Feb 2025 15:16:53 +0530 Subject: [PATCH 02/15] updated go sample dockerfile --- sample-docker-templates/go/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sample-docker-templates/go/Dockerfile b/sample-docker-templates/go/Dockerfile index df2846bafa..d3471013af 100644 --- a/sample-docker-templates/go/Dockerfile +++ b/sample-docker-templates/go/Dockerfile @@ -1,6 +1,6 @@ ################################# Build Container ############################### -FROM golang:1.23 as builder +FROM golang:1.23 AS builder # Setup the working directory WORKDIR /app @@ -17,11 +17,10 @@ ADD . /app/ # Build the source RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main app.go - ################################# Prod Container ################################# # Use a minimal alpine image -FROM alpine:3.7 +FROM alpine:3.21 # Add ca-certificates in case you need them RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/* From 5e0cb7bcd811e1b9e5a25ec0b149e20e029ba2de Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Tue, 18 Mar 2025 18:43:40 +0530 Subject: [PATCH 03/15] modified versions to java-21 LTS --- sample-docker-templates/java/Gradle_Dockerfile | 13 +++++++------ sample-docker-templates/java/Maven_Dockerfile | 12 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/sample-docker-templates/java/Gradle_Dockerfile b/sample-docker-templates/java/Gradle_Dockerfile index 30945dc67d..0fd259a9a6 100644 --- a/sample-docker-templates/java/Gradle_Dockerfile +++ b/sample-docker-templates/java/Gradle_Dockerfile @@ -1,7 +1,7 @@ ################################# Build Container ############################### # Base Image of Build Container -FROM gradle:4.7.0-jdk8-alpine AS build +FROM gradle:8.13.0-jdk21-alpine AS build # Changing the ownership of file and copying files in container COPY --chown=gradle:gradle . /home/gradle/src @@ -9,13 +9,14 @@ COPY --chown=gradle:gradle . /home/gradle/src # Moving into workdir WORKDIR /home/gradle/src -# Compiling & building the code -RUN gradle build --no-daemon +# Compiling & building the code +RUN gradle build --no-daemon ################################# Prod Container ################################# # Base Image for Prod Container -FROM openjdk:8-jre-slim +FROM openjdk:21-jdk-slim + # Exposing Port of this container EXPOSE 8080 @@ -24,7 +25,7 @@ EXPOSE 8080 RUN mkdir /app # Copying only the jar files created before -COPY --from=build /home/gradle/src/build/libs/*.jar /app/my-app.jar +COPY --from=build /home/gradle/src/build/libs/*.jar /app/demo.jar # Uncomment if you want to run default commands during the initialization of this container -# CMD exec java -jar /app/my-app.jar \ No newline at end of file +# CMD ["java","-jar","/app/demo.jar"] \ No newline at end of file diff --git a/sample-docker-templates/java/Maven_Dockerfile b/sample-docker-templates/java/Maven_Dockerfile index 52d7181417..84c4e062e1 100644 --- a/sample-docker-templates/java/Maven_Dockerfile +++ b/sample-docker-templates/java/Maven_Dockerfile @@ -1,7 +1,7 @@ ################################# Build Container ############################### # Base Image for Build Container -FROM maven:3.5.3-jdk-8-alpine as base +FROM maven:3.9.9-amazoncorretto-21-debian as base # Moving into working directory WORKDIR /build @@ -16,18 +16,18 @@ RUN mvn dependency:go-offline COPY src/ /build/src/ # Building package -RUN mvn package +RUN mvn clean package ################################# Prod Container ################################# # Base Image for Prod Container -FROM openjdk:8-jre-alpine +FROM openjdk:21-jdk-slim # Exposing Port of this new container -EXPOSE 4567 +EXPOSE 8080 # Copying the executable jar file build on previous container -COPY --from=base /build/target/*.jar /app/my-app.jar +COPY --from=base /build/target/*.jar /app/demo.jar # Uncomment if you want to run default commands during the initialization of this container -# CMD exec java -jar /app/my-app.jar \ No newline at end of file +# CMD ["java","-jar","/app/demo.jar"] \ No newline at end of file From a6434a2eeab77b39698c2b16d57199437fb65977 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Tue, 18 Mar 2025 18:47:15 +0530 Subject: [PATCH 04/15] modified versions to node v22.14.0 LTS --- sample-docker-templates/node/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sample-docker-templates/node/Dockerfile b/sample-docker-templates/node/Dockerfile index 123a903771..a233a8952d 100644 --- a/sample-docker-templates/node/Dockerfile +++ b/sample-docker-templates/node/Dockerfile @@ -1,5 +1,5 @@ # Base Image -From node:12.18.1 +FROM node:22.14.0 # Seeting up env as production ENV NODE_ENV=production @@ -32,5 +32,4 @@ RUN npm install --production RUN npm i -g pm2 # Starting Server -CMD ["sh", "-c", "service nginx start ; pm2-runtime src/index.js -i 0"] - +CMD ["sh", "-c", "service nginx start ; pm2-runtime src/index.js -i 0"] \ No newline at end of file From b3928e0230011b950908e777abedcc9771a4d95a Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Tue, 8 Apr 2025 13:40:12 +0530 Subject: [PATCH 05/15] modified versions to node v22.14.0 LTS --- sample-docker-templates/react/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sample-docker-templates/react/Dockerfile b/sample-docker-templates/react/Dockerfile index c89eb45a94..37adc438cf 100644 --- a/sample-docker-templates/react/Dockerfile +++ b/sample-docker-templates/react/Dockerfile @@ -1,7 +1,7 @@ ###### BUILD ENVIRONMENT ###### # Base Image -FROM node:12.18.1 as build +FROM node:22.14.0 as build # Moving into working directory WORKDIR /app @@ -30,3 +30,4 @@ EXPOSE 80 # Command to run CMD ["nginx", "-g", "daemon off;"] + From 5e60dadc4d24075ddb4727231592511feaced2d8 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Thu, 10 Apr 2025 18:08:31 +0530 Subject: [PATCH 06/15] updated base images versions --- sample-docker-templates/django/Dockerfile | 2 +- sample-docker-templates/flask/Dockerfile | 2 +- sample-docker-templates/php/php7.4/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sample-docker-templates/django/Dockerfile b/sample-docker-templates/django/Dockerfile index b84c90ebe6..688abbccc0 100644 --- a/sample-docker-templates/django/Dockerfile +++ b/sample-docker-templates/django/Dockerfile @@ -1,7 +1,7 @@ # Dockerfile # Base Image -FROM python:3.8 +FROM python:3.13 # set default environment variables ENV PYTHONUNBUFFERED 1 diff --git a/sample-docker-templates/flask/Dockerfile b/sample-docker-templates/flask/Dockerfile index ad20d787cc..6d121d760d 100644 --- a/sample-docker-templates/flask/Dockerfile +++ b/sample-docker-templates/flask/Dockerfile @@ -1,5 +1,5 @@ #Base Image -FROM python:3.8 +FROM python:3.13 #Getting System Ready to install dependencies RUN apt-get clean \ diff --git a/sample-docker-templates/php/php7.4/Dockerfile b/sample-docker-templates/php/php7.4/Dockerfile index ddff47d9fe..5d70e73c79 100644 --- a/sample-docker-templates/php/php7.4/Dockerfile +++ b/sample-docker-templates/php/php7.4/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM ubuntu:24.04 RUN apt-get update RUN apt-get -y upgrade From 30b5b0547007acc98d67bc7d628e3bda272f209d Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Fri, 23 May 2025 16:16:44 +0530 Subject: [PATCH 07/15] update Dockerfile for non-root user and update latest stable --- sample-docker-templates/django/Dockerfile | 49 +++++++------ .../django/start-server.sh | 33 ++++----- sample-docker-templates/flask/Dockerfile | 71 +++++++++++-------- sample-docker-templates/flask/start.sh | 26 ++----- sample-docker-templates/flask/uwsgi.ini | 9 +-- sample-docker-templates/go/Dockerfile | 44 +++++++----- .../java/Gradle_Dockerfile | 36 ++++++---- sample-docker-templates/java/Maven_Dockerfile | 38 ++++++---- sample-docker-templates/kotlin/Dockerfile | 51 ++++++------- sample-docker-templates/node/Dockerfile | 53 +++++++------- sample-docker-templates/php/Apache_Dockerfile | 21 +++--- sample-docker-templates/php/Nginx_Dockerfile | 30 ++------ sample-docker-templates/php/php7.4/Dockerfile | 24 ++++--- sample-docker-templates/react/Dockerfile | 31 ++++---- sample-docker-templates/rust/Dockerfile | 29 +++++--- 15 files changed, 288 insertions(+), 257 deletions(-) diff --git a/sample-docker-templates/django/Dockerfile b/sample-docker-templates/django/Dockerfile index 688abbccc0..cdd532c72e 100644 --- a/sample-docker-templates/django/Dockerfile +++ b/sample-docker-templates/django/Dockerfile @@ -1,13 +1,12 @@ -# Dockerfile - # Base Image -FROM python:3.13 +# Using official python 3.13-slim for smaller footprint and latest stable version +FROM python:3.13-slim -# set default environment variables -ENV PYTHONUNBUFFERED 1 -ENV LANG C.UTF-8 +# Set environment variables for Python behavior +ENV PYTHONUNBUFFERED=1 +ENV LANG=C.UTF-8 -# to take runtime arguments and set env variables +# Accept build arguments for Django superuser creation ARG DJANGO_SUPERUSER_USERNAME ENV DJANGO_SUPERUSER_USERNAME=${DJANGO_SUPERUSER_USERNAME} @@ -17,32 +16,40 @@ ENV DJANGO_SUPERUSER_PASSWORD=${DJANGO_SUPERUSER_PASSWORD} ARG DJANGO_SUPERUSER_EMAIL ENV DJANGO_SUPERUSER_EMAIL=${DJANGO_SUPERUSER_EMAIL} -# create and set working directory +# Create app directory and assign ownership later to non-root user RUN mkdir /app + WORKDIR /app -RUN chown -R www-data:www-data /app +# Install system dependencies and nginx with minimal packages, no recommends +RUN apt-get update && apt-get install -y --no-install-recommends nginx vim && \ + rm -rf /var/lib/apt/lists/* -# Add current directory code to working directory +# Copy app source code COPY . /app/ -# install environment dependencies -RUN pip install -r requirements.txt +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt -# install nginx -RUN apt-get update && apt-get install nginx vim -y --no-install-recommends +# Create a non-root user 'nonroot' and group, change ownership of /app and nginx logs +RUN groupadd -r nonroot && useradd -r -g nonroot nonroot && \ + chown -R nonroot:nonroot /app /var/log/nginx -#Refer https://github.com/devtron-labs/devtron/blob/main/sample-docker-templates/django/nginx.default for sample nginx.default file +# Copy nginx config file COPY nginx.default /etc/nginx/sites-available/default -RUN ln -sf /dev/stdout /var/log/nginx/access.log \ - && ln -sf /dev/stderr /var/log/nginx/error.log +# Symlink nginx logs to stdout/stderr for container logging +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log - -# start server +# Expose port 8000 for Django/gunicorn and nginx EXPOSE 8000 +# Use non-root user for better security +USER nonroot + +# Set stop signal for graceful shutdown STOPSIGNAL SIGTERM -# Refer https://github.com/devtron-labs/devtron/blob/main/sample-docker-templates/django/start-server.sh for sample start-server.sh file -CMD ["/app/start-server.sh"] \ No newline at end of file +# Start server script (migrations, superuser creation, gunicorn & nginx) +CMD ["/app/start-server.sh"] diff --git a/sample-docker-templates/django/start-server.sh b/sample-docker-templates/django/start-server.sh index fa9671fede..5e59ce4446 100755 --- a/sample-docker-templates/django/start-server.sh +++ b/sample-docker-templates/django/start-server.sh @@ -1,22 +1,15 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2024. Devtron Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# +#!/bin/sh -# start-server.sh -python manage.py migrate -python manage.py createsuperuser --no-input +# Apply DB migrations +python manage.py migrate -(gunicorn DjangoApp.wsgi --user www-data --bind 0.0.0.0:8000 --workers 3) && nginx -g "daemon off;" +# Create superuser if details provided (non-interactive) +if [ -n "$DJANGO_SUPERUSER_USERNAME" ] && [ -n "$DJANGO_SUPERUSER_PASSWORD" ] && [ -n "$DJANGO_SUPERUSER_EMAIL" ]; then + python manage.py createsuperuser --no-input || true +fi + +# Start gunicorn as non-root user binding on all interfaces port 8000, 3 workers +gunicorn DjangoApp.wsgi --user nonroot --bind 0.0.0.0:8000 --workers 3 & + +# Start nginx in foreground +nginx -g "daemon off;" diff --git a/sample-docker-templates/flask/Dockerfile b/sample-docker-templates/flask/Dockerfile index 6d121d760d..bcdcbc6d6b 100644 --- a/sample-docker-templates/flask/Dockerfile +++ b/sample-docker-templates/flask/Dockerfile @@ -1,39 +1,50 @@ -#Base Image -FROM python:3.13 - -#Getting System Ready to install dependencies -RUN apt-get clean \ - && apt-get -y update - -#Installing nginx -RUN apt-get -y install nginx \ - && apt-get -y install python3-dev \ - && apt-get -y install build-essential - -#Creating symbolic link for access and error log from nginx -RUN ln -sf /dev/stdout /var/log/nginx/access.log \ - && ln -sf /dev/stderr /var/log/nginx/error.log - -#Creating a dir in Container -RUN mkdir /app - -#Moving into the directory created +# Base Image - Using python:3.13-slim for reduced image size +FROM python:3.13-slim + +# Set environment variables +ENV PYTHONUNBUFFERED=1 +ENV LANG=C.UTF-8 + +# Install system dependencies (nginx, build tools) without recommended packages to keep image small +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + nginx \ + python3-dev \ + build-essential \ + # Clean up to reduce image size + && rm -rf /var/lib/apt/lists/* + +# Symlink nginx logs to stdout/stderr for containerized log access +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log + +# Create application directory +RUN mkdir -p /app + +# Set working directory WORKDIR /app -#Changing ownership of files in /app -RUN chown -R www-data:www-data /app +# Add application code +COPY . /app/ -#Adding the complete project in dir created -ADD . /app/ +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt -#Installing dependencies -RUN pip3 install -r requirements.txt - -# Refer https://raw.githubusercontent.com/devtron-labs/devtron/main/sample-docker-templates/flask/nginx.default for sample nginx.default file +# Copy nginx config COPY nginx.default /etc/nginx/sites-available/default -#Refer https://raw.githubusercontent.com/devtron-labs/devtron/main/sample-docker-templates/flask/start.sh for sample start.sh file -#Making start.sh executable +# Make start.sh executable RUN chmod +x ./start.sh +# Create a non-root user and change ownership of /app to that user +RUN groupadd -r nonroot && useradd -r -g nonroot nonroot && \ + chown -R nonroot:nonroot /app /var/log/nginx + +# Expose port 80 (used by nginx) +EXPOSE 80 + +# Switch to non-root user for better container security +USER nonroot + +# Run app with start.sh CMD ["./start.sh"] diff --git a/sample-docker-templates/flask/start.sh b/sample-docker-templates/flask/start.sh index ef72c97d44..777905edea 100644 --- a/sample-docker-templates/flask/start.sh +++ b/sample-docker-templates/flask/start.sh @@ -1,22 +1,8 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2024. Devtron Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -service nginx start -# Refer https://raw.githubusercontent.com/devtron-labs/devtron/main/sample-docker-templates/flask/uwsgi.ini for sample uwsgi.ini file -uwsgi --ini uwsgi.ini +#!/bin/bash +set -e +# Start nginx in the background +nginx +# Start uwsgi with provided ini config +exec uwsgi --ini uwsgi.ini diff --git a/sample-docker-templates/flask/uwsgi.ini b/sample-docker-templates/flask/uwsgi.ini index 9d73c94025..df30ced52f 100644 --- a/sample-docker-templates/flask/uwsgi.ini +++ b/sample-docker-templates/flask/uwsgi.ini @@ -1,14 +1,15 @@ [uwsgi] module = app:app -uid = www-data -gid = www-data + master = true processes = 5 socket = /tmp/uwsgi.socket -chmod-sock = 664 +chmod-socket = 664 vacuum = true die-on-term = true - +# Run as non-root user +uid = nonroot +gid = nonroot diff --git a/sample-docker-templates/go/Dockerfile b/sample-docker-templates/go/Dockerfile index d3471013af..5cb93d47bd 100644 --- a/sample-docker-templates/go/Dockerfile +++ b/sample-docker-templates/go/Dockerfile @@ -1,35 +1,41 @@ -################################# Build Container ############################### +################################# Build Container ################################# -FROM golang:1.23 AS builder +# Use the latest stable Go image for building +FROM golang:1.22.3 AS builder -# Setup the working directory +# Set working directory inside the container WORKDIR /app -# COPY go module -COPY go.mod go.sum /app/ - -# Download go modules and cache for next time build +# Copy Go module files and download dependencies +COPY go.mod go.sum ./ RUN go mod download -# Add source code -ADD . /app/ +# Copy the entire source code into the container +COPY . . -# Build the source +# Build the Go binary with CGO disabled for static linking RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main app.go -################################# Prod Container ################################# +################################# Production Container ############################ + +# Use a minimal and secure Alpine base image +FROM alpine:3.20 -# Use a minimal alpine image -FROM alpine:3.21 +# Install CA certificates (for HTTPS calls) +RUN apk --no-cache add ca-certificates -# Add ca-certificates in case you need them -RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/* +# Create a non-root user and switch to it +RUN adduser -D -g '' nonroot +USER nonroot # Set working directory -WORKDIR /root +WORKDIR /home/nonroot -# Copy the binary from builder +# Copy the compiled binary from the builder stage COPY --from=builder /app/main . -# Run the binary -CMD ["./main"] \ No newline at end of file +# Expose port if your app serves over a specific port (optional) +# EXPOSE 8080 + +# Start the application +CMD ["./main"] diff --git a/sample-docker-templates/java/Gradle_Dockerfile b/sample-docker-templates/java/Gradle_Dockerfile index 0fd259a9a6..ed7a69fed3 100644 --- a/sample-docker-templates/java/Gradle_Dockerfile +++ b/sample-docker-templates/java/Gradle_Dockerfile @@ -1,31 +1,37 @@ ################################# Build Container ############################### -# Base Image of Build Container +# Use latest Gradle with JDK 21 and Alpine for minimal size and speed FROM gradle:8.13.0-jdk21-alpine AS build -# Changing the ownership of file and copying files in container +# Set working directory and ensure proper permissions COPY --chown=gradle:gradle . /home/gradle/src - -# Moving into workdir WORKDIR /home/gradle/src -# Compiling & building the code +# Build the application without using the Gradle daemon RUN gradle build --no-daemon ################################# Prod Container ################################# -# Base Image for Prod Container -FROM openjdk:21-jdk-slim - +# Use a minimal JDK base image for production +FROM eclipse-temurin:21-jdk-jammy -# Exposing Port of this container -EXPOSE 8080 +# Create a non-root user to run the app securely +RUN useradd -m -s /bin/bash nonroot -# Creating a dir -RUN mkdir /app +# Set the working directory +WORKDIR /app -# Copying only the jar files created before +# Copy the JAR file from the build stage COPY --from=build /home/gradle/src/build/libs/*.jar /app/demo.jar -# Uncomment if you want to run default commands during the initialization of this container -# CMD ["java","-jar","/app/demo.jar"] \ No newline at end of file +# Set ownership of the jar file +RUN chown nonroot:nonroot /app/demo.jar + +# Switch to non-root user +USER nonroot + +# Expose the application port +EXPOSE 8080 + +# Run the jar file +CMD ["java", "-jar", "/app/demo.jar"] diff --git a/sample-docker-templates/java/Maven_Dockerfile b/sample-docker-templates/java/Maven_Dockerfile index 84c4e062e1..774d485afd 100644 --- a/sample-docker-templates/java/Maven_Dockerfile +++ b/sample-docker-templates/java/Maven_Dockerfile @@ -1,33 +1,45 @@ ################################# Build Container ############################### -# Base Image for Build Container +# Use latest Maven with Amazon Corretto 21 on Debian for consistent build environment FROM maven:3.9.9-amazoncorretto-21-debian as base -# Moving into working directory +# Set working directory inside container WORKDIR /build -# Copying pom.xml file initially for caching +# Copy pom.xml separately to leverage Docker cache for dependencies COPY pom.xml . -# Downloading Dependencies +# Download dependencies for offline use RUN mvn dependency:go-offline -# Copying files to /build/src/ inside container +# Copy the source code to container COPY src/ /build/src/ -# Building package +# Build the project and package the application RUN mvn clean package ################################# Prod Container ################################# -# Base Image for Prod Container -FROM openjdk:21-jdk-slim +# Use a slim OpenJDK 21 image based on Debian for production +FROM eclipse-temurin:21-jdk-jammy -# Exposing Port of this new container -EXPOSE 8080 +# Create a non-root user 'nonroot' for security best practices +RUN useradd -m -s /bin/bash nonroot + +# Set working directory +WORKDIR /app -# Copying the executable jar file build on previous container +# Copy the built jar from build stage COPY --from=base /build/target/*.jar /app/demo.jar -# Uncomment if you want to run default commands during the initialization of this container -# CMD ["java","-jar","/app/demo.jar"] \ No newline at end of file +# Change ownership to non-root user +RUN chown nonroot:nonroot /app/demo.jar + +# Switch to non-root user +USER nonroot + +# Expose the port the app listens on +EXPOSE 8080 + +# Default command to run the jar file +CMD ["java", "-jar", "/app/demo.jar"] diff --git a/sample-docker-templates/kotlin/Dockerfile b/sample-docker-templates/kotlin/Dockerfile index 198db63704..ca63ec6ce2 100644 --- a/sample-docker-templates/kotlin/Dockerfile +++ b/sample-docker-templates/kotlin/Dockerfile @@ -1,41 +1,44 @@ -# Using Base image -FROM alpine:latest +# Use specific Alpine version (3.21) for stability and reproducibility +FROM alpine:3.21 -# Build args +# Metadata args for build info (optional) ARG VCS_REF ARG BUILD_DATE -# Setting resource quota +# Setting resource quota args (optional, for your usage) ARG MIN_MEM=2G ARG MAX_MEM=2G -RUN apk add --update bash && \ - apk fetch openjdk8 && \ - apk add --no-cache openjdk8; +# Install required packages: bash, openjdk8, unzip, build-base, wget +RUN apk add --no-cache bash openjdk8 unzip build-base wget -RUN apk add --no-cache build-base wget && \ - cd /usr/lib && \ - # Installing Kotlin compiler in zip file - wget 'https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip' && \ - # Unzipping the downloaded zip file - unzip kotlin-compiler-*.zip && \ - rm kotlin-compiler-*.zip && \ - rm -f kotlinc/bin/*.bat; +# Download and install Kotlin compiler +RUN cd /usr/lib && \ + wget https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip && \ + unzip kotlin-compiler-1.3.72.zip && \ + rm kotlin-compiler-1.3.72.zip && \ + rm -f kotlinc/bin/*.bat -# Setting up environmental variable path -ENV PATH $PATH:/usr/lib/kotlinc/bin +# Add Kotlin compiler to PATH +ENV PATH="/usr/lib/kotlinc/bin:${PATH}" -# Making a directory named 'app' in the container -RUN mkdir app +# Create app directory and set permissions +RUN mkdir /app -# Copying 'app.kt' from 'app' folder on host to recently created 'app' folder in container -COPY app/app.kt /app +# Copy source code into container +COPY app/app.kt /app/ # Set working directory WORKDIR /app -# Compiling source +# Create a non-root user 'nonroot' and assign ownership of /app to it +RUN adduser -D nonroot && chown -R nonroot:nonroot /app + +# Switch to non-root user +USER nonroot + +# Compile Kotlin source to jar RUN kotlinc app.kt -include-runtime -d app.jar -# Execution -CMD ["java","-jar","./app.jar"] \ No newline at end of file +# Run the compiled jar +CMD ["java", "-jar", "./app.jar"] diff --git a/sample-docker-templates/node/Dockerfile b/sample-docker-templates/node/Dockerfile index a233a8952d..86ef2d9c20 100644 --- a/sample-docker-templates/node/Dockerfile +++ b/sample-docker-templates/node/Dockerfile @@ -1,35 +1,38 @@ -# Base Image -FROM node:22.14.0 +# Use a smaller, secure, and stable Node.js image +FROM node:22-alpine -# Seeting up env as production +# Set environment as production ENV NODE_ENV=production -#Getting System Ready to install dependencies -RUN apt-get clean \ - && apt-get -y update - -# Installing nginx -RUN apt-get -y install nginx \ - && apt-get -y install python3-dev \ - && apt-get -y install build-essential +# Install necessary packages: nginx only +RUN apk update && apk add --no-cache nginx -# Creating symbolic link for access and error log from nginx -RUN ln -sf /dev/stdout /var/log/nginx/access.log \ - && ln -sf /dev/stderr /var/log/nginx/error.log +# Create app directory and give access to non-root user +WORKDIR /app +# Copy app files +COPY . /app/ -# Making /app dir as working dir -WORKDIR /app +# Use COPY instead of ADD (best practice) +COPY nginx.default /etc/nginx/http.d/default.conf + +# Install production dependencies +RUN npm install --production && \ + npm i -g pm2 + +# Create non-root user and assign directory +RUN addgroup -S nonroot && adduser -S nonroot -G nonroot && \ + chown -R nonroot:nonroot /app /var/log/nginx -# Adding complete files and dirs in app dir in container -ADD . /app/ +# Expose port 80 for nginx +EXPOSE 80 -# Refer https://raw.githubusercontent.com/devtron-labs/devtron/main/sample-docker-templates/node/nginx.default for sample nginx.default -COPY nginx.default /etc/nginx/sites-available/default +# Use non-root user for container execution +USER nonroot -# Installing dependencies -RUN npm install --production -RUN npm i -g pm2 +# Create symlinks for nginx logs (optional, but helpful for logging) +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log -# Starting Server -CMD ["sh", "-c", "service nginx start ; pm2-runtime src/index.js -i 0"] \ No newline at end of file +# Start nginx and node app properly +CMD ["sh", "-c", "nginx && pm2-runtime src/index.js -i 0"] diff --git a/sample-docker-templates/php/Apache_Dockerfile b/sample-docker-templates/php/Apache_Dockerfile index 66d9b684b8..b5dfe4133a 100644 --- a/sample-docker-templates/php/Apache_Dockerfile +++ b/sample-docker-templates/php/Apache_Dockerfile @@ -1,16 +1,17 @@ -# Base Image -FROM php:7-apache +# Using latest stable PHP with Apache (8.2) +FROM php:8.2-apache -# Enabling modules from /etc/apache2/mods-available to /etc/apache2/mods-enabled +# Enable apache mod_rewrite RUN a2enmod rewrite -# Restarting apache2 server -RUN /etc/init.d/apache2 restart +# Give ownership of /var/www/html to non-root user +RUN useradd -m nonroot && chown -R nonroot:www-data /var/www/html -# Giving ownship of html dir to www-data user -RUN chown -R www-data:www-data /var/www/html +# Copy application source code +COPY --chown=nonroot:www-data . /var/www/html/ +# Switch to non-root user for security +USER nonroot -# Copy application source -COPY . /var/www/html/ - +# Apache runs as www-data internally, so no need to restart here +# CMD is inherited from base image and will run apache2 in foreground by default diff --git a/sample-docker-templates/php/Nginx_Dockerfile b/sample-docker-templates/php/Nginx_Dockerfile index 1a925599af..5e4cb4edc7 100644 --- a/sample-docker-templates/php/Nginx_Dockerfile +++ b/sample-docker-templates/php/Nginx_Dockerfile @@ -1,31 +1,15 @@ -# base image -FROM ubuntu:16.04 +# Use Ubuntu 24.04 LTS as base image for latest stable environment +FROM ubuntu:24.04 -# update & install system -RUN apt-get update -RUN apt-get -y upgrade +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y php8.2 php8.2-cli php8.2-fpm nginx && \ + apt-get clean && rm -rf /var/lib/apt/lists/* -# installing packages -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing php7.0 \ - php7.0-cli \ - php-fpm - -RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y nginx-full - -# copying nginx conf to its path +# Copy configs, code, etc. COPY nginx-site.conf /etc/nginx/sites-available/default - -# setting working dir WORKDIR /var/www/html/ - -# creating nested dir where fpm service would be found -RUN mkdir -p /run/php - -# copying static files to location COPY . /var/www/html -# service exposed EXPOSE 80 -# executing command -CMD ["/bin/bash", "-c", "service php7.0-fpm start && nginx -g \"daemon off;\""] \ No newline at end of file +CMD ["/bin/bash", "-c", "service php8.2-fpm start && nginx -g 'daemon off;'"] diff --git a/sample-docker-templates/php/php7.4/Dockerfile b/sample-docker-templates/php/php7.4/Dockerfile index 5d70e73c79..8a2fd72567 100644 --- a/sample-docker-templates/php/php7.4/Dockerfile +++ b/sample-docker-templates/php/php7.4/Dockerfile @@ -1,16 +1,18 @@ FROM ubuntu:24.04 -RUN apt-get update -RUN apt-get -y upgrade +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get -y upgrade && \ + apt-get install -y --no-install-recommends \ + php8.2 \ + php8.2-cli \ + php8.2-fpm \ + php8.2-mysql \ + php8.2-curl \ + net-tools \ + nginx && \ + apt-get clean && rm -rf /var/lib/apt/lists/* -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing php7.4 \ - php7.4-cli \ - php-fpm \ - php7.4-mysql \ - php7.4-curl \ - net-tools - -RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y nginx-full ADD nginx-site.conf /etc/nginx/sites-available/default WORKDIR /var/www/html/ @@ -21,4 +23,4 @@ COPY . /var/www/html EXPOSE 80 -CMD ["/bin/bash", "-c", "service php7.4-fpm start && nginx -g \"daemon off;\""] \ No newline at end of file +CMD ["/bin/bash", "-c", "service php8.2-fpm start && nginx -g 'daemon off;'"] diff --git a/sample-docker-templates/react/Dockerfile b/sample-docker-templates/react/Dockerfile index 37adc438cf..d2a5b9be22 100644 --- a/sample-docker-templates/react/Dockerfile +++ b/sample-docker-templates/react/Dockerfile @@ -1,33 +1,40 @@ ###### BUILD ENVIRONMENT ###### -# Base Image +# Use official Node.js LTS base image for building React app FROM node:22.14.0 as build -# Moving into working directory +# Set working directory WORKDIR /app -# Adding all files and dirs to /app inside container -ADD . /app/ +# Copy all source files to container +COPY . /app/ -# Installing dependencies +# Install dependencies RUN npm install -# Creating Production build for react-app +# Create production build of React app RUN npm run build -# In this dockerfile using the concept of docker multistage build ###### PRODUCTION ENVIRONMENT ###### -# Base Image for prod env +# Use official stable nginx Alpine image (small and secure) FROM nginx:stable-alpine -# Adding the build files from previous container to nginx/html +# Create a non-root user and group 'nonroot' for security best practice +RUN addgroup -S nonroot && adduser -S nonroot -G nonroot + +# Copy React build files from build stage to nginx html folder COPY --from=build /app/build /usr/share/nginx/html -# Exposing port 80 to listen http requests +# Change ownership to nonroot user to avoid running as root inside container +RUN chown -R nonroot:nonroot /usr/share/nginx/html + +# Switch to non-root user +USER nonroot + +# Expose port 80 for HTTP EXPOSE 80 -# Command to run +# Run nginx in foreground CMD ["nginx", "-g", "daemon off;"] - diff --git a/sample-docker-templates/rust/Dockerfile b/sample-docker-templates/rust/Dockerfile index 97e7454de0..720322d5bf 100644 --- a/sample-docker-templates/rust/Dockerfile +++ b/sample-docker-templates/rust/Dockerfile @@ -1,25 +1,34 @@ -# Using Base image -FROM alpine:latest +# Use a specific Alpine version for stability instead of 'latest' +FROM alpine:3.21 -#Build args +# Build args for metadata (optional, can be used for labels) ARG VCS_REF ARG BUILD_DATE -# Setting resource quota +# Set resource quota as environment variables (optional usage) ARG MIN_MEM=2G ARG MAX_MEM=2G -# Installing rust and making a folder named 'src' into it -RUN apk add --no-cache rust && mkdir /src +# Install rust compiler and related tools, and create working dir +RUN apk add --no-cache rust && mkdir /src -# Copying 'main.rs' from 'src' folder on host to recently created 'src' folder in container +# Copy source code into container COPY src/main.rs /src # Set working directory WORKDIR /src -#Compiling source +# Compile Rust source to binary 'main' RUN rustc main.rs -#Execution -CMD ["./main"] \ No newline at end of file +# Create non-root user for security +RUN addgroup -S nonroot && adduser -S nonroot -G nonroot + +# Change ownership of the compiled binary +RUN chown nonroot:nonroot /src/main + +# Switch to non-root user +USER nonroot + +# Run the compiled binary +CMD ["./main"] From 474826da34db2d25a75420ac3afc032e0fe1dc48 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Fri, 23 May 2025 19:13:41 +0530 Subject: [PATCH 08/15] update dockerfile and nginx.conf --- .../java/Gradle_Dockerfile | 2 +- sample-docker-templates/java/Maven_Dockerfile | 2 +- sample-docker-templates/node/Dockerfile | 39 ++++++++------ .../node/nginx-default.conf | 34 ++++++++++++ sample-docker-templates/node/nginx.conf | 23 ++++++++ sample-docker-templates/node/nginx.default | 17 ------ sample-docker-templates/react/Dockerfile | 53 ++++++++++--------- 7 files changed, 109 insertions(+), 61 deletions(-) create mode 100644 sample-docker-templates/node/nginx-default.conf create mode 100644 sample-docker-templates/node/nginx.conf delete mode 100644 sample-docker-templates/node/nginx.default diff --git a/sample-docker-templates/java/Gradle_Dockerfile b/sample-docker-templates/java/Gradle_Dockerfile index ed7a69fed3..96df2f0f79 100644 --- a/sample-docker-templates/java/Gradle_Dockerfile +++ b/sample-docker-templates/java/Gradle_Dockerfile @@ -16,7 +16,7 @@ RUN gradle build --no-daemon FROM eclipse-temurin:21-jdk-jammy # Create a non-root user to run the app securely -RUN useradd -m -s /bin/bash nonroot +RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot # Set the working directory WORKDIR /app diff --git a/sample-docker-templates/java/Maven_Dockerfile b/sample-docker-templates/java/Maven_Dockerfile index 774d485afd..ce8e6398bf 100644 --- a/sample-docker-templates/java/Maven_Dockerfile +++ b/sample-docker-templates/java/Maven_Dockerfile @@ -24,7 +24,7 @@ RUN mvn clean package FROM eclipse-temurin:21-jdk-jammy # Create a non-root user 'nonroot' for security best practices -RUN useradd -m -s /bin/bash nonroot +RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot # Set working directory WORKDIR /app diff --git a/sample-docker-templates/node/Dockerfile b/sample-docker-templates/node/Dockerfile index 86ef2d9c20..746403165d 100644 --- a/sample-docker-templates/node/Dockerfile +++ b/sample-docker-templates/node/Dockerfile @@ -1,38 +1,43 @@ -# Use a smaller, secure, and stable Node.js image +# Use a minimal Node.js base image FROM node:22-alpine -# Set environment as production +# Set environment for production ENV NODE_ENV=production # Install necessary packages: nginx only RUN apk update && apk add --no-cache nginx -# Create app directory and give access to non-root user +# Set working directory WORKDIR /app -# Copy app files -COPY . /app/ +# Copy application code +COPY . . -# Use COPY instead of ADD (best practice) -COPY nginx.default /etc/nginx/http.d/default.conf +# Main global config +COPY nginx.conf /etc/nginx/nginx.conf + +# Default server/site config +COPY nginx-default.conf /etc/nginx/http.d/default.conf # Install production dependencies -RUN npm install --production && \ +RUN npm install --production --prefer-offline --no-audit && \ npm i -g pm2 -# Create non-root user and assign directory -RUN addgroup -S nonroot && adduser -S nonroot -G nonroot && \ - chown -R nonroot:nonroot /app /var/log/nginx +# Create non-root user and set permissions +RUN addgroup -g 2002 nonroot && \ + adduser -u 2002 -G nonroot -S nonroot && \ + mkdir -p /var/lib/nginx/tmp/client_body && \ + chown -R nonroot:nonroot /app /var/log/nginx /var/lib/nginx -# Expose port 80 for nginx -EXPOSE 80 +# Expose port 8080 +EXPOSE 8080 -# Use non-root user for container execution +# Switch to non-root user USER nonroot -# Create symlinks for nginx logs (optional, but helpful for logging) +# Link logs to stdout/stderr RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ ln -sf /dev/stderr /var/log/nginx/error.log -# Start nginx and node app properly -CMD ["sh", "-c", "nginx && pm2-runtime src/index.js -i 0"] +# Start your app listening on port 8080 +CMD ["sh", "-c", "nginx && pm2-runtime src/index.js -i 0 --port=8080"] \ No newline at end of file diff --git a/sample-docker-templates/node/nginx-default.conf b/sample-docker-templates/node/nginx-default.conf new file mode 100644 index 0000000000..fd1cac68a1 --- /dev/null +++ b/sample-docker-templates/node/nginx-default.conf @@ -0,0 +1,34 @@ +# This contains a server block defining how a specific domain/route should be handled. +# nginx-default.conf + +# To allow a non-root container process to bind to privileged ports (e.g., 80 or 443), +# you need to add the NET_BIND_SERVICE capability to the security context: +# +# securityContext: +# allowPrivilegeEscalation: false +# capabilities: +# add: +# - NET_BIND_SERVICE +# drop: +# - ALL +# +# Since adding capabilities may reduce security or require extra setup in Kubernetes, +# it's simpler and safer to use an unprivileged port like 8080 for your app. + + +server { + listen 8080; + listen [::]:8080; + root /app; + server_name localhost; + + + location / { + 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; + proxy_pass http://127.0.0.1:3000; + } + +} \ No newline at end of file diff --git a/sample-docker-templates/node/nginx.conf b/sample-docker-templates/node/nginx.conf new file mode 100644 index 0000000000..40a22b8fa2 --- /dev/null +++ b/sample-docker-templates/node/nginx.conf @@ -0,0 +1,23 @@ +# This is the global Nginx configuration file (typically contains user, worker_processes, http block, etc.) +# /etc/nginx/nginx.conf + +# user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log notice; +pid /tmp/nginx.pid; +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + sendfile on; + keepalive_timeout 65; + + include /etc/nginx/http.d/*.conf; +} diff --git a/sample-docker-templates/node/nginx.default b/sample-docker-templates/node/nginx.default deleted file mode 100644 index 831c838473..0000000000 --- a/sample-docker-templates/node/nginx.default +++ /dev/null @@ -1,17 +0,0 @@ -# nginx.default - -server { - listen 80; - listen [::]:80; - server_name example.org; - root /app; - - location / { - 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; - proxy_pass http://127.0.0.1:3000; - } - -} diff --git a/sample-docker-templates/react/Dockerfile b/sample-docker-templates/react/Dockerfile index d2a5b9be22..746403165d 100644 --- a/sample-docker-templates/react/Dockerfile +++ b/sample-docker-templates/react/Dockerfile @@ -1,40 +1,43 @@ -###### BUILD ENVIRONMENT ###### +# Use a minimal Node.js base image +FROM node:22-alpine -# Use official Node.js LTS base image for building React app -FROM node:22.14.0 as build +# Set environment for production +ENV NODE_ENV=production + +# Install necessary packages: nginx only +RUN apk update && apk add --no-cache nginx # Set working directory WORKDIR /app -# Copy all source files to container -COPY . /app/ - -# Install dependencies -RUN npm install - -# Create production build of React app -RUN npm run build - +# Copy application code +COPY . . -###### PRODUCTION ENVIRONMENT ###### +# Main global config +COPY nginx.conf /etc/nginx/nginx.conf -# Use official stable nginx Alpine image (small and secure) -FROM nginx:stable-alpine +# Default server/site config +COPY nginx-default.conf /etc/nginx/http.d/default.conf -# Create a non-root user and group 'nonroot' for security best practice -RUN addgroup -S nonroot && adduser -S nonroot -G nonroot +# Install production dependencies +RUN npm install --production --prefer-offline --no-audit && \ + npm i -g pm2 -# Copy React build files from build stage to nginx html folder -COPY --from=build /app/build /usr/share/nginx/html +# Create non-root user and set permissions +RUN addgroup -g 2002 nonroot && \ + adduser -u 2002 -G nonroot -S nonroot && \ + mkdir -p /var/lib/nginx/tmp/client_body && \ + chown -R nonroot:nonroot /app /var/log/nginx /var/lib/nginx -# Change ownership to nonroot user to avoid running as root inside container -RUN chown -R nonroot:nonroot /usr/share/nginx/html +# Expose port 8080 +EXPOSE 8080 # Switch to non-root user USER nonroot -# Expose port 80 for HTTP -EXPOSE 80 +# Link logs to stdout/stderr +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log -# Run nginx in foreground -CMD ["nginx", "-g", "daemon off;"] +# Start your app listening on port 8080 +CMD ["sh", "-c", "nginx && pm2-runtime src/index.js -i 0 --port=8080"] \ No newline at end of file From afcb0fba280c0cb2e3044e790d387433f3b789d2 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Wed, 28 May 2025 13:58:31 +0530 Subject: [PATCH 09/15] added dockerfile for react --- sample-docker-templates/react/Dockerfile | 59 +++++++++++++----------- sample-docker-templates/react/nginx.conf | 32 +++++++++++++ 2 files changed, 64 insertions(+), 27 deletions(-) create mode 100644 sample-docker-templates/react/nginx.conf diff --git a/sample-docker-templates/react/Dockerfile b/sample-docker-templates/react/Dockerfile index 746403165d..51811c54b4 100644 --- a/sample-docker-templates/react/Dockerfile +++ b/sample-docker-templates/react/Dockerfile @@ -1,43 +1,48 @@ -# Use a minimal Node.js base image -FROM node:22-alpine +###### BUILD ENVIRONMENT ###### -# Set environment for production -ENV NODE_ENV=production - -# Install necessary packages: nginx only -RUN apk update && apk add --no-cache nginx +# Use official Node.js LTS base image for building React app +FROM node:22.14.0 as build # Set working directory WORKDIR /app -# Copy application code -COPY . . +# Copy all source files to container +COPY . /app/ -# Main global config -COPY nginx.conf /etc/nginx/nginx.conf +# Install dependencies +RUN npm install -# Default server/site config -COPY nginx-default.conf /etc/nginx/http.d/default.conf +# Create production build of React app +RUN npm run build -# Install production dependencies -RUN npm install --production --prefer-offline --no-audit && \ - npm i -g pm2 -# Create non-root user and set permissions -RUN addgroup -g 2002 nonroot && \ - adduser -u 2002 -G nonroot -S nonroot && \ - mkdir -p /var/lib/nginx/tmp/client_body && \ - chown -R nonroot:nonroot /app /var/log/nginx /var/lib/nginx +###### PRODUCTION ENVIRONMENT ###### -# Expose port 8080 -EXPOSE 8080 +# Use official stable nginx Alpine image (small and secure) +FROM nginx:stable-alpine -# Switch to non-root user -USER nonroot +# Create non-root user and group +RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot + +# Copy React build files from build stage to nginx html folder +COPY --from=build /app/build /usr/share/nginx/html + +# Give permissions to nonroot user for required nginx folders +RUN chown -R nonroot:nonroot /usr/share/nginx/html /var/cache/nginx /var/log/nginx/ + +# Copy custom NGINX config file +COPY nginx.conf /etc/nginx/nginx.conf # Link logs to stdout/stderr RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ ln -sf /dev/stderr /var/log/nginx/error.log -# Start your app listening on port 8080 -CMD ["sh", "-c", "nginx && pm2-runtime src/index.js -i 0 --port=8080"] \ No newline at end of file + +# Switch to non-root user +USER nonroot + +# Expose port 8080 (non-root) +EXPOSE 8080 + +# Run nginx in foreground +CMD ["nginx", "-g", "daemon off;"] diff --git a/sample-docker-templates/react/nginx.conf b/sample-docker-templates/react/nginx.conf new file mode 100644 index 0000000000..a874a4849d --- /dev/null +++ b/sample-docker-templates/react/nginx.conf @@ -0,0 +1,32 @@ +worker_processes auto; +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + sendfile on; + keepalive_timeout 65; + + server { + listen 8080; + server_name localhost; + + root /usr/share/nginx/html; + index index.html index.htm; + + location / { + try_files $uri $uri/ /index.html; + } + + error_page 404 /index.html; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + } +} From 7750781babbeddf02736726b821343fb6ffcf060 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Thu, 29 May 2025 16:20:10 +0530 Subject: [PATCH 10/15] refactor --- sample-docker-templates/django/Dockerfile | 59 ++++++--------- sample-docker-templates/django/nginx.conf | 36 +++++++++ sample-docker-templates/django/nginx.default | 15 ---- .../django/start-server.sh | 14 ++-- sample-docker-templates/flask/Dockerfile | 74 ++++++++----------- sample-docker-templates/flask/nginx.conf | 35 +++++++++ sample-docker-templates/flask/nginx.default | 23 ------ sample-docker-templates/flask/start.sh | 11 ++- sample-docker-templates/flask/uwsgi.ini | 12 +-- .../java/Gradle_Dockerfile | 3 +- sample-docker-templates/java/Maven_Dockerfile | 2 +- 11 files changed, 145 insertions(+), 139 deletions(-) create mode 100644 sample-docker-templates/django/nginx.conf delete mode 100644 sample-docker-templates/django/nginx.default create mode 100644 sample-docker-templates/flask/nginx.conf delete mode 100644 sample-docker-templates/flask/nginx.default diff --git a/sample-docker-templates/django/Dockerfile b/sample-docker-templates/django/Dockerfile index cdd532c72e..7232599ce6 100644 --- a/sample-docker-templates/django/Dockerfile +++ b/sample-docker-templates/django/Dockerfile @@ -1,55 +1,44 @@ -# Base Image -# Using official python 3.13-slim for smaller footprint and latest stable version +# Base Image - slim Python FROM python:3.13-slim -# Set environment variables for Python behavior -ENV PYTHONUNBUFFERED=1 -ENV LANG=C.UTF-8 +# Environment settings +ENV PYTHONUNBUFFERED=1 LANG=C.UTF-8 -# Accept build arguments for Django superuser creation +# Django superuser build args ARG DJANGO_SUPERUSER_USERNAME -ENV DJANGO_SUPERUSER_USERNAME=${DJANGO_SUPERUSER_USERNAME} - ARG DJANGO_SUPERUSER_PASSWORD -ENV DJANGO_SUPERUSER_PASSWORD=${DJANGO_SUPERUSER_PASSWORD} - ARG DJANGO_SUPERUSER_EMAIL +ENV DJANGO_SUPERUSER_USERNAME=${DJANGO_SUPERUSER_USERNAME} +ENV DJANGO_SUPERUSER_PASSWORD=${DJANGO_SUPERUSER_PASSWORD} ENV DJANGO_SUPERUSER_EMAIL=${DJANGO_SUPERUSER_EMAIL} -# Create app directory and assign ownership later to non-root user -RUN mkdir /app - +# Set workdir WORKDIR /app -# Install system dependencies and nginx with minimal packages, no recommends +# Install system dependencies and nginx, then install Python deps +COPY requirements.txt . RUN apt-get update && apt-get install -y --no-install-recommends nginx vim && \ + pip install --no-cache-dir -r requirements.txt && \ rm -rf /var/lib/apt/lists/* -# Copy app source code -COPY . /app/ - -# Install Python dependencies -RUN pip install --no-cache-dir -r requirements.txt - -# Create a non-root user 'nonroot' and group, change ownership of /app and nginx logs -RUN groupadd -r nonroot && useradd -r -g nonroot nonroot && \ - chown -R nonroot:nonroot /app /var/log/nginx - -# Copy nginx config file -COPY nginx.default /etc/nginx/sites-available/default +# Copy app code, nginx.conf, and start script +COPY app/ ./ +COPY nginx.conf /etc/nginx/nginx.conf +COPY start-server.sh ./ +RUN chmod +x start-server.sh -# Symlink nginx logs to stdout/stderr for container logging -RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ - ln -sf /dev/stderr /var/log/nginx/error.log +# Create non-root user and set permissions +RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /tmp/nginx-logs && chown -R nonroot:nonroot /app /tmp/nginx-logs -# Expose port 8000 for Django/gunicorn and nginx -EXPOSE 8000 +# Expose port 8080 +EXPOSE 8080 -# Use non-root user for better security +# Switch to non-root USER nonroot -# Set stop signal for graceful shutdown +# Stop signal for graceful shutdown STOPSIGNAL SIGTERM -# Start server script (migrations, superuser creation, gunicorn & nginx) -CMD ["/app/start-server.sh"] +# Start server (migrations, superuser, gunicorn, nginx) +CMD ["/app/start-server.sh"] \ No newline at end of file diff --git a/sample-docker-templates/django/nginx.conf b/sample-docker-templates/django/nginx.conf new file mode 100644 index 0000000000..a657db03c5 --- /dev/null +++ b/sample-docker-templates/django/nginx.conf @@ -0,0 +1,36 @@ +worker_processes auto; +error_log /tmp/nginx-logs/error.log warn; +pid /tmp/nginx-logs/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + access_log /tmp/nginx-logs/access.log; + + client_body_temp_path /tmp/nginx-logs/client_temp; + proxy_temp_path /tmp/nginx-logs/proxy_temp; + fastcgi_temp_path /tmp/nginx-logs/fastcgi_temp; + uwsgi_temp_path /tmp/nginx-logs/uwsgi_temp; + scgi_temp_path /tmp/nginx-logs/scgi_temp; + + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /static/ { + root /app; + } + } +} diff --git a/sample-docker-templates/django/nginx.default b/sample-docker-templates/django/nginx.default deleted file mode 100644 index 952503a128..0000000000 --- a/sample-docker-templates/django/nginx.default +++ /dev/null @@ -1,15 +0,0 @@ -# nginx.default - -server { - listen 8020; - server_name example.org; - - location / { - proxy_pass http://127.0.0.1:8000; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - location /static { - root /app; - } -} diff --git a/sample-docker-templates/django/start-server.sh b/sample-docker-templates/django/start-server.sh index 5e59ce4446..a571b37dae 100755 --- a/sample-docker-templates/django/start-server.sh +++ b/sample-docker-templates/django/start-server.sh @@ -1,15 +1,13 @@ #!/bin/sh # Apply DB migrations -python manage.py migrate +python /app/manage.py migrate -# Create superuser if details provided (non-interactive) -if [ -n "$DJANGO_SUPERUSER_USERNAME" ] && [ -n "$DJANGO_SUPERUSER_PASSWORD" ] && [ -n "$DJANGO_SUPERUSER_EMAIL" ]; then - python manage.py createsuperuser --no-input || true -fi +# create superuser +python /app/manage.py createsuperuser --no-input -# Start gunicorn as non-root user binding on all interfaces port 8000, 3 workers -gunicorn DjangoApp.wsgi --user nonroot --bind 0.0.0.0:8000 --workers 3 & +# Start gunicorn as non-root user binding on port 8000 +gunicorn demo-project.wsgi:application --user nonroot --bind 0.0.0.0:8000 --workers 3 & -# Start nginx in foreground +# Start nginx (already configured to run without root) nginx -g "daemon off;" diff --git a/sample-docker-templates/flask/Dockerfile b/sample-docker-templates/flask/Dockerfile index bcdcbc6d6b..7d1dcfdba0 100644 --- a/sample-docker-templates/flask/Dockerfile +++ b/sample-docker-templates/flask/Dockerfile @@ -1,50 +1,40 @@ -# Base Image - Using python:3.13-slim for reduced image size +# Base Image - slim Python FROM python:3.13-slim -# Set environment variables -ENV PYTHONUNBUFFERED=1 -ENV LANG=C.UTF-8 +# Environment settings +ENV PYTHONUNBUFFERED=1 LANG=C.UTF-8 -# Install system dependencies (nginx, build tools) without recommended packages to keep image small -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - nginx \ - python3-dev \ - build-essential \ - # Clean up to reduce image size - && rm -rf /var/lib/apt/lists/* - -# Symlink nginx logs to stdout/stderr for containerized log access -RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ - ln -sf /dev/stderr /var/log/nginx/error.log - -# Create application directory -RUN mkdir -p /app - -# Set working directory +# Set workdir WORKDIR /app -# Add application code -COPY . /app/ - -# Install Python dependencies -RUN pip install --no-cache-dir -r requirements.txt - -# Copy nginx config -COPY nginx.default /etc/nginx/sites-available/default +COPY requirements.txt requirements.txt -# Make start.sh executable -RUN chmod +x ./start.sh - -# Create a non-root user and change ownership of /app to that user -RUN groupadd -r nonroot && useradd -r -g nonroot nonroot && \ - chown -R nonroot:nonroot /app /var/log/nginx - -# Expose port 80 (used by nginx) -EXPOSE 80 - -# Switch to non-root user for better container security +# Install system dependencies and nginx, then install Python deps +RUN apt-get update && \ + apt-get install -y --no-install-recommends nginx gcc python3-dev musl-dev build-essential libexpat1 && \ + pip install --no-cache-dir -r requirements.txt && \ + apt-get purge -y --auto-remove gcc python3-dev musl-dev build-essential && \ + rm -rf /var/lib/apt/lists/* + +# Copy app code, configs, and start script +COPY app.py ./ +COPY uwsgi.ini ./ +COPY nginx.conf /etc/nginx/nginx.conf +COPY start.sh ./ +RUN chmod +x start.sh + +# Create non-root user and set permissions +RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /tmp/nginx-logs && chown -R nonroot:nonroot /app /tmp/nginx-logs + +# Expose port 8080 +EXPOSE 8080 + +# Switch to non-root USER nonroot -# Run app with start.sh -CMD ["./start.sh"] +# Stop signal for graceful shutdown +STOPSIGNAL SIGTERM + +# Start server (migrations, superuser, gunicorn, nginx) +CMD ["/app/start.sh"] \ No newline at end of file diff --git a/sample-docker-templates/flask/nginx.conf b/sample-docker-templates/flask/nginx.conf new file mode 100644 index 0000000000..8b7f64cdf6 --- /dev/null +++ b/sample-docker-templates/flask/nginx.conf @@ -0,0 +1,35 @@ +worker_processes auto; +error_log /tmp/nginx-logs/error.log warn; +pid /tmp/nginx-logs/nginx.pid; + +events {} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /tmp/nginx-logs/access.log; + + client_body_temp_path /tmp/nginx-logs/client_temp; + proxy_temp_path /tmp/nginx-logs/proxy_temp; + fastcgi_temp_path /tmp/nginx-logs/fastcgi_temp; + uwsgi_temp_path /tmp/nginx-logs/uwsgi_temp; + scgi_temp_path /tmp/nginx-logs/scgi_temp; + + server { + listen 8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:5000; + 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; + } + + location /static/ { + alias /app/static/; + } + } +} diff --git a/sample-docker-templates/flask/nginx.default b/sample-docker-templates/flask/nginx.default deleted file mode 100644 index c2fbc75164..0000000000 --- a/sample-docker-templates/flask/nginx.default +++ /dev/null @@ -1,23 +0,0 @@ -# nginx.default - -server { - listen 8000 default_server; - listen [::]:8000 default_server; - server_name example.org; - root /app; - - location / { - include uwsgi_params; - uwsgi_pass unix:/tmp/uwsgi.socket; - } - - location /static { - root /app; - } - - # For https uncomment the below lines - - # listen 443 ssl; - # give your ssl_certificate in this block - -} \ No newline at end of file diff --git a/sample-docker-templates/flask/start.sh b/sample-docker-templates/flask/start.sh index 777905edea..cbfafbf0f4 100644 --- a/sample-docker-templates/flask/start.sh +++ b/sample-docker-templates/flask/start.sh @@ -1,8 +1,7 @@ -#!/bin/bash -set -e +#!/bin/sh -# Start nginx in the background -nginx +# Start uWSGI in the background +uwsgi --ini /app/uwsgi.ini & -# Start uwsgi with provided ini config -exec uwsgi --ini uwsgi.ini +# Start Nginx in the foreground +nginx -g "daemon off;" \ No newline at end of file diff --git a/sample-docker-templates/flask/uwsgi.ini b/sample-docker-templates/flask/uwsgi.ini index df30ced52f..42d2601f34 100644 --- a/sample-docker-templates/flask/uwsgi.ini +++ b/sample-docker-templates/flask/uwsgi.ini @@ -1,15 +1,11 @@ [uwsgi] module = app:app - master = true processes = 5 -socket = /tmp/uwsgi.socket -chmod-socket = 664 -vacuum = true - -die-on-term = true - -# Run as non-root user +http = 127.0.0.1:5000 uid = nonroot gid = nonroot + +vacuum = true +die-on-term = true \ No newline at end of file diff --git a/sample-docker-templates/java/Gradle_Dockerfile b/sample-docker-templates/java/Gradle_Dockerfile index 96df2f0f79..060dcc79fd 100644 --- a/sample-docker-templates/java/Gradle_Dockerfile +++ b/sample-docker-templates/java/Gradle_Dockerfile @@ -16,7 +16,8 @@ RUN gradle build --no-daemon FROM eclipse-temurin:21-jdk-jammy # Create a non-root user to run the app securely -RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot +RUN addgroup --gid 2002 nonroot && adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" + # Set the working directory WORKDIR /app diff --git a/sample-docker-templates/java/Maven_Dockerfile b/sample-docker-templates/java/Maven_Dockerfile index ce8e6398bf..bdd1db76f9 100644 --- a/sample-docker-templates/java/Maven_Dockerfile +++ b/sample-docker-templates/java/Maven_Dockerfile @@ -24,7 +24,7 @@ RUN mvn clean package FROM eclipse-temurin:21-jdk-jammy # Create a non-root user 'nonroot' for security best practices -RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot +RUN addgroup --gid 2002 nonroot && adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" # Set working directory WORKDIR /app From 8bb420995b67e1bc0d948ec619924cdc361a5cfc Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Thu, 29 May 2025 17:05:11 +0530 Subject: [PATCH 11/15] refactor --- sample-docker-templates/go/Dockerfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sample-docker-templates/go/Dockerfile b/sample-docker-templates/go/Dockerfile index 5cb93d47bd..77fd0836ad 100644 --- a/sample-docker-templates/go/Dockerfile +++ b/sample-docker-templates/go/Dockerfile @@ -24,8 +24,10 @@ FROM alpine:3.20 # Install CA certificates (for HTTPS calls) RUN apk --no-cache add ca-certificates -# Create a non-root user and switch to it -RUN adduser -D -g '' nonroot +# Create a non-root user with UID/GID 2002 +RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot + +# Switch to the non-root user USER nonroot # Set working directory @@ -34,8 +36,8 @@ WORKDIR /home/nonroot # Copy the compiled binary from the builder stage COPY --from=builder /app/main . -# Expose port if your app serves over a specific port (optional) -# EXPOSE 8080 +# Expose port 8080 for the application +EXPOSE 8080 # Start the application CMD ["./main"] From fbdd41e357bc215f82aa436a6283579c840573a3 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Thu, 29 May 2025 18:27:51 +0530 Subject: [PATCH 12/15] refactor --- sample-docker-templates/rust/Dockerfile | 40 +++++++++++-------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/sample-docker-templates/rust/Dockerfile b/sample-docker-templates/rust/Dockerfile index 720322d5bf..34d251889b 100644 --- a/sample-docker-templates/rust/Dockerfile +++ b/sample-docker-templates/rust/Dockerfile @@ -1,34 +1,30 @@ -# Use a specific Alpine version for stability instead of 'latest' -FROM alpine:3.21 +# --- Build Stage --- +FROM rust:1.77-alpine AS builder -# Build args for metadata (optional, can be used for labels) -ARG VCS_REF -ARG BUILD_DATE +WORKDIR /src -# Set resource quota as environment variables (optional usage) -ARG MIN_MEM=2G -ARG MAX_MEM=2G +# Copy your Rust source code +COPY src/main.rs . -# Install rust compiler and related tools, and create working dir -RUN apk add --no-cache rust && mkdir /src +# Build the Rust binary +RUN rustc main.rs -o app -# Copy source code into container -COPY src/main.rs /src +# --- Final Stage --- +FROM alpine:3.21 -# Set working directory -WORKDIR /src +# Create a non-root user for security +RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot -# Compile Rust source to binary 'main' -RUN rustc main.rs +WORKDIR /app -# Create non-root user for security -RUN addgroup -S nonroot && adduser -S nonroot -G nonroot +# Copy the compiled Rust binary from the builder stage +COPY --from=builder /src/app . -# Change ownership of the compiled binary -RUN chown nonroot:nonroot /src/main +# Expose the port your Rust app uses (adjust as needed) +EXPOSE 8080 # Switch to non-root user USER nonroot -# Run the compiled binary -CMD ["./main"] +# Command to run the app +CMD ["./app"] From 8e354427e4b8c221880c9d54ce0e84a048a684ba Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Thu, 29 May 2025 19:05:26 +0530 Subject: [PATCH 13/15] refactor --- sample-docker-templates/kotlin/Dockerfile | 54 ++++++++----------- sample-docker-templates/php/Apache_Dockerfile | 9 ++-- sample-docker-templates/php/Nginx_Dockerfile | 15 ++++-- sample-docker-templates/php/nginx-site.conf | 6 +-- sample-docker-templates/php/php7.4/Dockerfile | 19 ++++--- .../php/php7.4/nginx-site.conf | 6 +-- 6 files changed, 53 insertions(+), 56 deletions(-) diff --git a/sample-docker-templates/kotlin/Dockerfile b/sample-docker-templates/kotlin/Dockerfile index ca63ec6ce2..863e3d1fd9 100644 --- a/sample-docker-templates/kotlin/Dockerfile +++ b/sample-docker-templates/kotlin/Dockerfile @@ -1,44 +1,32 @@ -# Use specific Alpine version (3.21) for stability and reproducibility -FROM alpine:3.21 +# --- Build stage --- +FROM gradle:8.13.0-jdk21-alpine AS builder -# Metadata args for build info (optional) -ARG VCS_REF -ARG BUILD_DATE +WORKDIR /src -# Setting resource quota args (optional, for your usage) -ARG MIN_MEM=2G -ARG MAX_MEM=2G +# Copy Gradle build files +COPY build.gradle.kts . +COPY settings.gradle.kts . -# Install required packages: bash, openjdk8, unzip, build-base, wget -RUN apk add --no-cache bash openjdk8 unzip build-base wget +# Create directory structure and copy source code +RUN mkdir -p src/main/kotlin +COPY app.kt src/main/kotlin/App.kt -# Download and install Kotlin compiler -RUN cd /usr/lib && \ - wget https://github.com/JetBrains/kotlin/releases/download/v1.3.72/kotlin-compiler-1.3.72.zip && \ - unzip kotlin-compiler-1.3.72.zip && \ - rm kotlin-compiler-1.3.72.zip && \ - rm -f kotlinc/bin/*.bat +# Build the Kotlin JAR +RUN gradle installDist --no-daemon --parallel -# Add Kotlin compiler to PATH -ENV PATH="/usr/lib/kotlinc/bin:${PATH}" +# --- Final stage --- +FROM eclipse-temurin:21-jre-jammy -# Create app directory and set permissions -RUN mkdir /app +# Add a non-root user for security +RUN addgroup --gid 2002 nonroot && adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" -# Copy source code into container -COPY app/app.kt /app/ +WORKDIR /home/nonroot -# Set working directory -WORKDIR /app +# Copy the built distribution from the builder stage +COPY --from=builder /src/build/install/app ./ -# Create a non-root user 'nonroot' and assign ownership of /app to it -RUN adduser -D nonroot && chown -R nonroot:nonroot /app - -# Switch to non-root user USER nonroot +EXPOSE 8080 -# Compile Kotlin source to jar -RUN kotlinc app.kt -include-runtime -d app.jar - -# Run the compiled jar -CMD ["java", "-jar", "./app.jar"] +# Run the application +CMD ["bin/app"] \ No newline at end of file diff --git a/sample-docker-templates/php/Apache_Dockerfile b/sample-docker-templates/php/Apache_Dockerfile index b5dfe4133a..5965c42912 100644 --- a/sample-docker-templates/php/Apache_Dockerfile +++ b/sample-docker-templates/php/Apache_Dockerfile @@ -1,11 +1,12 @@ -# Using latest stable PHP with Apache (8.2) -FROM php:8.2-apache +# Using latest stable PHP with Apache (8.3) +FROM php:8.3-apache # Enable apache mod_rewrite RUN a2enmod rewrite -# Give ownership of /var/www/html to non-root user -RUN useradd -m nonroot && chown -R nonroot:www-data /var/www/html +# Create non-root user with UID/GID 2002 and set ownership +RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -m nonroot && \ + chown -R nonroot:www-data /var/www/html # Copy application source code COPY --chown=nonroot:www-data . /var/www/html/ diff --git a/sample-docker-templates/php/Nginx_Dockerfile b/sample-docker-templates/php/Nginx_Dockerfile index 5e4cb4edc7..22357f96d6 100644 --- a/sample-docker-templates/php/Nginx_Dockerfile +++ b/sample-docker-templates/php/Nginx_Dockerfile @@ -1,15 +1,24 @@ # Use Ubuntu 24.04 LTS as base image for latest stable environment FROM ubuntu:24.04 +ENV DEBIAN_FRONTEND=noninteractive + RUN apt-get update && apt-get upgrade -y && \ - apt-get install -y php8.2 php8.2-cli php8.2-fpm nginx && \ + apt-get install -y --no-install-recommends \ + php8.3 php8.3-cli php8.3-fpm nginx && \ apt-get clean && rm -rf /var/lib/apt/lists/* -# Copy configs, code, etc. +# Create non-root user and set permissions +RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /run/php && chown -R nonroot:nonroot /var/www/html /run/php + COPY nginx-site.conf /etc/nginx/sites-available/default + WORKDIR /var/www/html/ COPY . /var/www/html EXPOSE 80 -CMD ["/bin/bash", "-c", "service php8.2-fpm start && nginx -g 'daemon off;'"] +USER nonroot + +CMD ["/bin/bash", "-c", "php-fpm8.3 --daemonize && nginx -g 'daemon off;'"] diff --git a/sample-docker-templates/php/nginx-site.conf b/sample-docker-templates/php/nginx-site.conf index ad094bf4f6..dfd383d0fa 100644 --- a/sample-docker-templates/php/nginx-site.conf +++ b/sample-docker-templates/php/nginx-site.conf @@ -1,6 +1,6 @@ server { - listen 80; ## listen for ipv4; this line is default and implied - listen [::]:80 default ipv6only=on; ## listen for ipv6 + listen 8080; # listen for ipv4 as non-root + listen [::]:8080 default ipv6only=on; # listen for ipv6 as non-root root /var/www/html; index index.php index.html index.htm; @@ -40,7 +40,7 @@ server { location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/run/php/php7.0-fpm.sock; + fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_index index.php; diff --git a/sample-docker-templates/php/php7.4/Dockerfile b/sample-docker-templates/php/php7.4/Dockerfile index 8a2fd72567..1955b99d3e 100644 --- a/sample-docker-templates/php/php7.4/Dockerfile +++ b/sample-docker-templates/php/php7.4/Dockerfile @@ -2,25 +2,24 @@ FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get -y upgrade && \ +RUN apt-get update && \ apt-get install -y --no-install-recommends \ - php8.2 \ - php8.2-cli \ - php8.2-fpm \ - php8.2-mysql \ - php8.2-curl \ - net-tools \ + php8.3-cli \ + php8.3-fpm \ nginx && \ apt-get clean && rm -rf /var/lib/apt/lists/* +RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /run/php && chown -R nonroot:nonroot /var/www/html /run/php + ADD nginx-site.conf /etc/nginx/sites-available/default WORKDIR /var/www/html/ -RUN mkdir -p /run/php - COPY . /var/www/html EXPOSE 80 -CMD ["/bin/bash", "-c", "service php8.2-fpm start && nginx -g 'daemon off;'"] +USER nonroot + +CMD ["/bin/bash", "-c", "php-fpm8.3 --daemonize && nginx -g 'daemon off;'"] diff --git a/sample-docker-templates/php/php7.4/nginx-site.conf b/sample-docker-templates/php/php7.4/nginx-site.conf index 6b0e2929cb..dfd383d0fa 100644 --- a/sample-docker-templates/php/php7.4/nginx-site.conf +++ b/sample-docker-templates/php/php7.4/nginx-site.conf @@ -1,6 +1,6 @@ server { - listen 80; ## listen for ipv4; this line is default and implied - listen [::]:80 default ipv6only=on; ## listen for ipv6 + listen 8080; # listen for ipv4 as non-root + listen [::]:8080 default ipv6only=on; # listen for ipv6 as non-root root /var/www/html; index index.php index.html index.htm; @@ -40,7 +40,7 @@ server { location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/run/php/php7.4-fpm.sock; + fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_index index.php; From 0b25a54928533855d677099d9d9054912658f937 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Tue, 3 Jun 2025 16:28:17 +0530 Subject: [PATCH 14/15] resolved all review points --- sample-docker-templates/django/Dockerfile | 8 ++-- sample-docker-templates/flask/Dockerfile | 10 ++--- sample-docker-templates/go/Dockerfile | 3 +- .../java/Gradle_Dockerfile | 5 ++- sample-docker-templates/java/Maven_Dockerfile | 3 +- sample-docker-templates/kotlin/Dockerfile | 18 +++++--- sample-docker-templates/node/Dockerfile | 14 ++++--- sample-docker-templates/php/Apache_Dockerfile | 3 +- sample-docker-templates/php/Nginx_Dockerfile | 9 ++-- sample-docker-templates/php/php7.4/Dockerfile | 9 ++-- sample-docker-templates/react/Dockerfile | 41 +++++++++++-------- sample-docker-templates/rust/Dockerfile | 3 +- 12 files changed, 77 insertions(+), 49 deletions(-) diff --git a/sample-docker-templates/django/Dockerfile b/sample-docker-templates/django/Dockerfile index 7232599ce6..246691e5ba 100644 --- a/sample-docker-templates/django/Dockerfile +++ b/sample-docker-templates/django/Dockerfile @@ -24,12 +24,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends nginx vim && \ # Copy app code, nginx.conf, and start script COPY app/ ./ COPY nginx.conf /etc/nginx/nginx.conf -COPY start-server.sh ./ RUN chmod +x start-server.sh # Create non-root user and set permissions -RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ - mkdir -p /tmp/nginx-logs && chown -R nonroot:nonroot /app /tmp/nginx-logs +RUN groupadd -g 2002 nonroot && \ + useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /tmp/nginx-logs && \ + chown -R nonroot:nonroot /app /tmp/nginx-logs # Expose port 8080 EXPOSE 8080 @@ -38,6 +39,7 @@ EXPOSE 8080 USER nonroot # Stop signal for graceful shutdown +# https://docs.docker.com/reference/dockerfile/#stopsignal STOPSIGNAL SIGTERM # Start server (migrations, superuser, gunicorn, nginx) diff --git a/sample-docker-templates/flask/Dockerfile b/sample-docker-templates/flask/Dockerfile index 7d1dcfdba0..8261490866 100644 --- a/sample-docker-templates/flask/Dockerfile +++ b/sample-docker-templates/flask/Dockerfile @@ -17,15 +17,15 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* # Copy app code, configs, and start script -COPY app.py ./ -COPY uwsgi.ini ./ COPY nginx.conf /etc/nginx/nginx.conf -COPY start.sh ./ +COPY app.py uwsgi.ini start.sh ./ RUN chmod +x start.sh # Create non-root user and set permissions -RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ - mkdir -p /tmp/nginx-logs && chown -R nonroot:nonroot /app /tmp/nginx-logs +RUN groupadd -g 2002 nonroot && \ + useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /tmp/nginx-logs && \ + chown -R nonroot:nonroot /app /tmp/nginx-logs # Expose port 8080 EXPOSE 8080 diff --git a/sample-docker-templates/go/Dockerfile b/sample-docker-templates/go/Dockerfile index 77fd0836ad..5a65993ddd 100644 --- a/sample-docker-templates/go/Dockerfile +++ b/sample-docker-templates/go/Dockerfile @@ -25,7 +25,8 @@ FROM alpine:3.20 RUN apk --no-cache add ca-certificates # Create a non-root user with UID/GID 2002 -RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot +RUN addgroup -g 2002 nonroot && \ + adduser -u 2002 -G nonroot -S nonroot # Switch to the non-root user USER nonroot diff --git a/sample-docker-templates/java/Gradle_Dockerfile b/sample-docker-templates/java/Gradle_Dockerfile index 060dcc79fd..f3f5029071 100644 --- a/sample-docker-templates/java/Gradle_Dockerfile +++ b/sample-docker-templates/java/Gradle_Dockerfile @@ -5,6 +5,7 @@ FROM gradle:8.13.0-jdk21-alpine AS build # Set working directory and ensure proper permissions COPY --chown=gradle:gradle . /home/gradle/src + WORKDIR /home/gradle/src # Build the application without using the Gradle daemon @@ -16,8 +17,8 @@ RUN gradle build --no-daemon FROM eclipse-temurin:21-jdk-jammy # Create a non-root user to run the app securely -RUN addgroup --gid 2002 nonroot && adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" - +RUN addgroup --gid 2002 nonroot && \ + adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" # Set the working directory WORKDIR /app diff --git a/sample-docker-templates/java/Maven_Dockerfile b/sample-docker-templates/java/Maven_Dockerfile index bdd1db76f9..e64d1f9b3d 100644 --- a/sample-docker-templates/java/Maven_Dockerfile +++ b/sample-docker-templates/java/Maven_Dockerfile @@ -24,7 +24,8 @@ RUN mvn clean package FROM eclipse-temurin:21-jdk-jammy # Create a non-root user 'nonroot' for security best practices -RUN addgroup --gid 2002 nonroot && adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" +RUN addgroup --gid 2002 nonroot && \ + adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" # Set working directory WORKDIR /app diff --git a/sample-docker-templates/kotlin/Dockerfile b/sample-docker-templates/kotlin/Dockerfile index 863e3d1fd9..a14b68b76b 100644 --- a/sample-docker-templates/kotlin/Dockerfile +++ b/sample-docker-templates/kotlin/Dockerfile @@ -1,31 +1,37 @@ # --- Build stage --- FROM gradle:8.13.0-jdk21-alpine AS builder +# Set working directory WORKDIR /src -# Copy Gradle build files -COPY build.gradle.kts . -COPY settings.gradle.kts . +# Copy Gradle build files first (leverages Docker caching) +COPY build.gradle.kts settings.gradle.kts ./ -# Create directory structure and copy source code +# Pre-create expected source directory to avoid COPY issues RUN mkdir -p src/main/kotlin + +# Copy Kotlin source files COPY app.kt src/main/kotlin/App.kt -# Build the Kotlin JAR +# Build the application distribution (binary JAR + startup scripts) RUN gradle installDist --no-daemon --parallel # --- Final stage --- FROM eclipse-temurin:21-jre-jammy # Add a non-root user for security -RUN addgroup --gid 2002 nonroot && adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" +RUN addgroup --gid 2002 nonroot && \ + adduser --gid 2002 --uid 2002 nonroot --disabled-password --gecos "" WORKDIR /home/nonroot # Copy the built distribution from the builder stage COPY --from=builder /src/build/install/app ./ +# Switch to non-root user USER nonroot + +# Expose the application port EXPOSE 8080 # Run the application diff --git a/sample-docker-templates/node/Dockerfile b/sample-docker-templates/node/Dockerfile index 746403165d..bcb34f5679 100644 --- a/sample-docker-templates/node/Dockerfile +++ b/sample-docker-templates/node/Dockerfile @@ -10,7 +10,15 @@ RUN apk update && apk add --no-cache nginx # Set working directory WORKDIR /app -# Copy application code +# Copy only package files first to install dependencies +COPY package*.json ./ + + +# Install production dependencies +RUN npm install --prefer-offline --no-audit && \ + npm i -g pm2 + +# Now copy the rest of the source COPY . . # Main global config @@ -19,10 +27,6 @@ COPY nginx.conf /etc/nginx/nginx.conf # Default server/site config COPY nginx-default.conf /etc/nginx/http.d/default.conf -# Install production dependencies -RUN npm install --production --prefer-offline --no-audit && \ - npm i -g pm2 - # Create non-root user and set permissions RUN addgroup -g 2002 nonroot && \ adduser -u 2002 -G nonroot -S nonroot && \ diff --git a/sample-docker-templates/php/Apache_Dockerfile b/sample-docker-templates/php/Apache_Dockerfile index 5965c42912..1947445fd2 100644 --- a/sample-docker-templates/php/Apache_Dockerfile +++ b/sample-docker-templates/php/Apache_Dockerfile @@ -5,7 +5,8 @@ FROM php:8.3-apache RUN a2enmod rewrite # Create non-root user with UID/GID 2002 and set ownership -RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -m nonroot && \ +RUN groupadd -g 2002 nonroot && \ + useradd -u 2002 -g nonroot -m nonroot && \ chown -R nonroot:www-data /var/www/html # Copy application source code diff --git a/sample-docker-templates/php/Nginx_Dockerfile b/sample-docker-templates/php/Nginx_Dockerfile index 22357f96d6..b693b5f08f 100644 --- a/sample-docker-templates/php/Nginx_Dockerfile +++ b/sample-docker-templates/php/Nginx_Dockerfile @@ -4,13 +4,14 @@ FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get upgrade -y && \ - apt-get install -y --no-install-recommends \ - php8.3 php8.3-cli php8.3-fpm nginx && \ + apt-get install -y --no-install-recommends php8.3 php8.3-cli php8.3-fpm nginx && \ apt-get clean && rm -rf /var/lib/apt/lists/* # Create non-root user and set permissions -RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ - mkdir -p /run/php && chown -R nonroot:nonroot /var/www/html /run/php +RUN groupadd -g 2002 nonroot && \ + useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /run/php && \ + chown -R nonroot:nonroot /var/www/html /run/php COPY nginx-site.conf /etc/nginx/sites-available/default diff --git a/sample-docker-templates/php/php7.4/Dockerfile b/sample-docker-templates/php/php7.4/Dockerfile index 1955b99d3e..cff82f55d8 100644 --- a/sample-docker-templates/php/php7.4/Dockerfile +++ b/sample-docker-templates/php/php7.4/Dockerfile @@ -7,10 +7,13 @@ RUN apt-get update && \ php8.3-cli \ php8.3-fpm \ nginx && \ - apt-get clean && rm -rf /var/lib/apt/lists/* + apt-get clean && \ + rm -rf /var/lib/apt/lists/* -RUN groupadd -g 2002 nonroot && useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ - mkdir -p /run/php && chown -R nonroot:nonroot /var/www/html /run/php +RUN groupadd -g 2002 nonroot && \ + useradd -u 2002 -g nonroot -s /bin/bash -m nonroot && \ + mkdir -p /run/php && \ + chown -R nonroot:nonroot /var/www/html /run/php ADD nginx-site.conf /etc/nginx/sites-available/default diff --git a/sample-docker-templates/react/Dockerfile b/sample-docker-templates/react/Dockerfile index 51811c54b4..42c13bec10 100644 --- a/sample-docker-templates/react/Dockerfile +++ b/sample-docker-templates/react/Dockerfile @@ -1,48 +1,55 @@ ###### BUILD ENVIRONMENT ###### -# Use official Node.js LTS base image for building React app -FROM node:22.14.0 as build +# Use official Node.js LTS base image for building the React app +FROM node:22.14.0 AS build + +# Set NODE_ENV for the build stage +ENV NODE_ENV=production # Set working directory WORKDIR /app -# Copy all source files to container -COPY . /app/ +# Copy only package files first to leverage Docker layer caching +COPY package*.json ./ + # Install dependencies RUN npm install -# Create production build of React app +# Copy the rest of the application source +COPY . . + +# Create production build RUN npm run build ###### PRODUCTION ENVIRONMENT ###### -# Use official stable nginx Alpine image (small and secure) +# Use stable NGINX Alpine image for serving static files FROM nginx:stable-alpine -# Create non-root user and group -RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot +# Create a non-root user +RUN addgroup -g 2002 nonroot && \ + adduser -u 2002 -G nonroot -S nonroot -# Copy React build files from build stage to nginx html folder +# Copy the React build output from the build stage COPY --from=build /app/build /usr/share/nginx/html -# Give permissions to nonroot user for required nginx folders -RUN chown -R nonroot:nonroot /usr/share/nginx/html /var/cache/nginx /var/log/nginx/ +# Set permissions for non-root user +RUN chown -R nonroot:nonroot /usr/share/nginx/html /var/cache/nginx /var/log/nginx -# Copy custom NGINX config file +# Copy custom NGINX config COPY nginx.conf /etc/nginx/nginx.conf -# Link logs to stdout/stderr +# Redirect logs to Docker's logging system RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ ln -sf /dev/stderr /var/log/nginx/error.log - -# Switch to non-root user +# Run as non-root user USER nonroot -# Expose port 8080 (non-root) +# Expose port (non-privileged) EXPOSE 8080 -# Run nginx in foreground +# Start NGINX in foreground CMD ["nginx", "-g", "daemon off;"] diff --git a/sample-docker-templates/rust/Dockerfile b/sample-docker-templates/rust/Dockerfile index 34d251889b..8a2726543a 100644 --- a/sample-docker-templates/rust/Dockerfile +++ b/sample-docker-templates/rust/Dockerfile @@ -13,7 +13,8 @@ RUN rustc main.rs -o app FROM alpine:3.21 # Create a non-root user for security -RUN addgroup -g 2002 nonroot && adduser -u 2002 -G nonroot -S nonroot +RUN addgroup -g 2002 nonroot && \ + adduser -u 2002 -G nonroot -S nonroot WORKDIR /app From 34695a558ee736cfccb812bf9ae174018f63a3e9 Mon Sep 17 00:00:00 2001 From: Badal Kumar Prusty Date: Wed, 4 Jun 2025 18:39:02 +0530 Subject: [PATCH 15/15] wip --- sample-docker-templates/django/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sample-docker-templates/django/Dockerfile b/sample-docker-templates/django/Dockerfile index 246691e5ba..cfd5124629 100644 --- a/sample-docker-templates/django/Dockerfile +++ b/sample-docker-templates/django/Dockerfile @@ -17,7 +17,8 @@ WORKDIR /app # Install system dependencies and nginx, then install Python deps COPY requirements.txt . -RUN apt-get update && apt-get install -y --no-install-recommends nginx vim && \ +RUN apt-get update && \ + apt-get install -y --no-install-recommends nginx vim && \ pip install --no-cache-dir -r requirements.txt && \ rm -rf /var/lib/apt/lists/*