ejemplos-practicos-dockerfile

Practical Dockerfile Examples

  • 5 min

Docker is a very useful tool, but facing a blank file for the first time can be intimidating. Fortunately, one of its advantages is that you don’t have to reinvent the wheel every time you start a project.

In this article, I have compiled 10 practical Dockerfile examples covering everything from basic system configurations to advanced Multi-stage architectures for compiled languages.

Use them as base templates, copy them and adapt them to the needs of your own projects 👇.

Utilities and Basic Configuration

Ideal for creating isolated command-line tools or understanding how environment variables work.

Base Image (Ubuntu + Curl)

This example illustrates how to start from a blank operating system and install basic Linux packages.

FROM ubuntu:22.04

# Update repositories and install curl
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Default command
CMD ["curl", "--version"]
Copied!

Using Environment Variables (httpie)

Learn to use the ENV instruction to make your container dynamic and accept parameters at startup (e.g., docker run -e URL=[https://google.com](https://google.com) my-image).

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y httpie && rm -rf /var/lib/apt/lists/*

# Define a variable with default value
ENV URL=https://example.com

# Use the variable in execution
CMD ["sh", "-c", "http -h $URL"]
Copied!

Interpreted Languages

Classic web applications usually require copying dependencies, installing them, and then copying the source code.

Node.js (Express / Frontend)

The industry standard for JavaScript applications. We copy the package.json before the code to leverage Docker’s cache.

FROM node:18-alpine
WORKDIR /app

# Install dependencies first
COPY package*.json ./
RUN npm install

# Copy the rest of the code
COPY . .

EXPOSE 3000
CMD ["npm", "start"]
Copied!

Python (Django / Flask)

Prepared to install dependencies from a requirements.txt file without caching garbage that would bloat the image.

FROM python:3.9-slim
WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000
CMD ["python", "app.py"]
Copied!

PHP with Apache

A very quick setup for serving legacy projects or classic PHP architectures.

FROM php:8.1-apache

# Enable mod_rewrite for friendly URLs
RUN a2enmod rewrite

# Copy code directly to Apache's public folder
COPY src/ /var/www/html/

# Adjust permissions
RUN chown -R www-data:www-data /var/www/html

EXPOSE 80
# CMD is already configured in the Apache base image
Copied!

Ruby on Rails

A more complex environment that requires precompiling assets and managing system tools before startup.

FROM ruby:3.2-slim
WORKDIR /app

# Install system dependencies required for Rails
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

COPY Gemfile Gemfile.lock ./
RUN bundle install

COPY . .

# Precompile Rails assets
RUN bundle exec rake assets:precompile

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Copied!

Compiled Languages

In languages like Java, Go, or .NET, we use a heavy image to compile the code, and then copy only the final executable to an empty, ultra-light image for production.

.NET (C# / ASP.NET)

Microsoft’s recommended way to package enterprise applications.

# STAGE 1: Build and Publish
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /source
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

# STAGE 2: Production (Runtime only)
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .

EXPOSE 80
ENTRYPOINT ["dotnet", "your-application.dll"]
Copied!

Java (Spring Boot with Maven)

We compile the .jar file using Maven in the first stage and run it using a lightweight Java environment (JRE) in the second stage.

# STAGE 1: Compilation
FROM maven:3.8-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# STAGE 2: Production
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
Copied!

Go (Golang)

We go from a compilation image of several hundred megabytes to a final production image that takes up just a few MB.

# STAGE 1: Compilation
FROM golang:1.20-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main_app

# STAGE 2: Production
FROM alpine:latest
WORKDIR /app
# Copy only the compiled binary
COPY --from=build /app/main_app .

EXPOSE 8080
CMD ["./main_app"]
Copied!

Rust

Useful for high-performance microservices where the final image must be minimal and secure (it’s safe!! 🦀).

# STAGE 1: Compilation
FROM rust:1.70 AS build
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
# Trick to cache dependencies by compiling an empty project
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release
RUN rm -rf src
# Compile the real code
COPY src ./src
RUN cargo build --release

# STAGE 2: Production
FROM debian:bullseye-slim
WORKDIR /app
COPY --from=build /app/target/release/mi_app /usr/local/bin/

EXPOSE 8000
CMD ["mi_app"]
Copied!