Loading Now

Apache Web Server Dockerfile Example

Apache Web Server Dockerfile Example
server” decoding=”async” fetchpriority=”high” />

When establishing web services in containers, the Apache HTTP server is a highly trusted and popular choice for hosting everything from basic static pages to intricate web applications. To create an optimal Dockerfile for Apache, one must grasp the container ecosystem, various Apache configurations, and Docker best practices to ensure the resulting images are secure, efficient, and easy to maintain. This guide explains how to construct Apache Dockerfiles suitable for production, addresses common configuration scenarios, shares troubleshooting strategies, and evaluates various approaches for deploying resilient web services in containers.

Understanding Apache Docker Containers

Within a Docker container, Apache operates as the primary process, generally listening on ports 80 (HTTP) and 443 (HTTPS). The container encompasses the Apache binary, configuration scripts, modules, and your website content. Upon container startup, Apache runs as the principal process (PID 1), making correct signal handling and graceful shutdowns vital for production scenarios.

The essential components found in an Apache Docker configuration include:

  • Base operating system (commonly Ubuntu, Debian, or Alpine)
  • Apache HTTP server package and necessary modules
  • Configuration files (httpd.conf, sites-enabled, etc.)
  • SSL certificates and security settings
  • Your web application files and assets
  • Log management and volume mount strategies

Implementing a Basic Apache Dockerfile

Below is a simple Dockerfile that establishes Apache with standard configurations:

FROM ubuntu:22.04

# Prevent interactive prompts during package setup
ENV DEBIAN_FRONTEND=ninteractive

# Install Apache and necessary utilities
RUN apt-get update && \
    apt-get install -y \
        apache2 \
        apache2-utils \
        curl \
        vim \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Activate Apache modules
RUN a2enmod rewrite ssl headers deflate

# Create directory for SSL certificates
RUN mkdir -p /etc/apache2/ssl

# Copy custom configurations
COPY apache2.conf /etc/apache2/apache2.conf
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

# Copy web content
COPY ./html/ /var/www/html/

# Assign appropriate permissions
RUN chown -R www-data:www-data /var/www/html \
    && chmod -R 755 /var/www/html

# Expose relevant ports
EXPOSE 80 443

# Run Apache in the foreground
CMD ["apache2ctl", "-D", "FOREGROUND"]

This Dockerfile serves as a strong starting point, but you’ll require supporting configuration files. Below is an example of an apache2.conf with enhanced security:

# /etc/apache2/apache2.conf
DefaultRuntimeDir ${APACHE_RUN_DIR}
PidFile ${APACHE_PID_FILE}
Timeout 60
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

HostnameLookups Off

LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# Security headers
Header always set X-Content-Type-Options sniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

# Conceal Apache version
ServerTokens Prod
ServerSignature Off

# Include module settings
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf

Advanced Example of Multi-Stage Builds

In production scenarios, optimising image size and security can be achieved through multi-stage builds. This method delineates the build environment from the runtime environment:

# Build stage
FROM de:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY src/ ./src/
RUN npm run build

# Production stage
FROM httpd:2.4-alpine

# Install additional dependencies
RUN apk add ---cache \
    openssl \
    curl \
    bash

# Transfer built application
COPY --from=builder /app/dist/ /usr/local/apache2/htdocs/

# Add Apache configuration
COPY httpd.conf /usr/local/apache2/conf/httpd.conf
COPY ssl.conf /usr/local/apache2/conf/extra/httpd-ssl.conf

# Create SSL directory and generate self-signed certificate for developmental use
RUN mkdir -p /usr/local/apache2/conf/ssl && \
    openssl req -x509 -des -days 365 -newkey rsa:2048 \
    -keyout /usr/local/apache2/conf/ssl/apache.key \
    -out /usr/local/apache2/conf/ssl/apache.crt \
    -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

# Set appropriate permissions
RUN chown -R daemon:daemon /usr/local/apache2/htdocs/

EXPOSE 80 443

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost/ || exit 1

CMD ["httpd-foreground"]

Examples and Use Cases in the Real World

Apache for PHP Applications

Numerous developers require Apache alongside PHP. Here’s a Dockerfile for a PHP application:

FROM php:8.2-apache

# Install PHP extensions and system dependencies
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libzip-dev \
    unzip \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql zip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Activate Apache modules
RUN a2enmod rewrite ssl headers

# Copy application files
COPY ./src/ /var/www/html/

# Include custom Apache configurations
COPY apache-php.conf /etc/apache2/sites-available/000-default.conf

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Install PHP dependencies
WORKDIR /var/www/html
RUN composer install ---dev --optimize-autoloader

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

EXPOSE 80 443

Configuration for Reverse Proxy

Apache can function as a reverse proxy for backend services. Below is an example configuration:

# reverse-proxy.conf

    ServerName api.example.com
    
    ProxyPreserveHost On
    ProxyRequests Off
    
    # Load balancing between backend Servers
    ProxyPass /api/ balancer://backend-cluster/
    ProxyPassReverse /api/ balancer://backend-cluster/
    
    
        BalancerMember http://backend1:3000
        BalancerMember http://backend2:3000
        ProxySet hcmethod GET
        ProxySet hcuri /health
    
    
    # Static files served directly
    ProxyPass /static/ !
    Alias /static/ /var/www/static/
    
    LogLevel info
    ErrorLog ${APACHE_LOG_DIR}/proxy_error.log
    CustomLog ${APACHE_LOG_DIR}/proxy_access.log combined

Best Practices for Performance Optimization

Enhancing Apache’s performance in containers necessitates specific tuning techniques. Below is a performance-optimized configuration:

# performance-tuned.conf
# MPM Configuration for containers

    StartServers 2
    MinSpareServers 2
    MaxSpareServers 5
    MaxRequestWorkers 150
    MaxConnectionsPerChild 1000


# Enable compression

    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
    DeflateCompressionLevel 6


# Cache static files

    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"


# Set limits for request size and timeouts in container settings
LimitRequestBody 10485760
Timeout 30
KeepAliveTimeout 2

Comparative Analysis with Other Approaches

Strategy Image Size Security Level Performance Rating Maintenance Needs Optimal Use Case
Official Apache (httpd:2.4) ~200MB High Exceptional Low Static websites, reverse proxies
PHP-Apache (php:8.2-apache) ~500MB Medium Good Medium PHP-based applications
Custom Alpine-based ~50MB High Very Good High Production microservices
Custom Ubuntu-based ~300MB Medium Good Medium Development, complex applications

Typical Challenges and Resolutions

Below are common issues you might face, along with their solutions:

Challenges with Permissions

A frequent issue is related to file permissions. Apache typically runs as the www-data user, yet files are often copied as root:

# Solution in Dockerfile
RUN chown -R www-data:www-data /var/www/html && \
    find /var/www/html -type d -exec chmod 755 {} \; && \
    find /var/www/html -type f -exec chmod 644 {} \;

# Alternative using COPY with ownership
COPY --chown=www-data:www-data ./html/ /var/www/html/

Apache Fails to Start in Container

Apache must run in the foreground in containers. Check the following common issues:

# Incorrect - Apache will start and then exit immediately
CMD ["service", "apache2", "start"]

# Correct - Apache runs in the foreground
CMD ["apache2ctl", "-D", "FOREGROUND"]

# Alternative correct method
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]

Problems with Module Loading

You should explicitly enable necessary modules within your Dockerfile:

# Check modules available
RUN apache2ctl -M

# Enable specific modules
RUN a2enmod rewrite ssl headers deflate proxy proxy_http proxy_balancer lbmethod_byrequests

# Verify configuration correctness
RUN apache2ctl configtest

Log Management Practices

Logs within containers should direct to stdout/stderr for efficient Docker log handling:

# Link Apache logs to stdout/stderr
RUN ln -sf /dev/stdout /var/log/apache2/access.log && \
    ln -sf /dev/stderr /var/log/apache2/error.log

# Or configure in apache2.conf
ErrorLog /proc/self/fd/2
CustomLog /proc/self/fd/1 combined

Integrating Docker Compose

Here’s a comprehensive docker-compose.yml example showcasing Apache integration with additional services:

version: '3.8'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile.apache
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/var/www/html:ro
      - ./ssl:/etc/apache2/ssl:ro
      - apache-logs:/var/log/apache2
    environment:
      - APACHE_LOG_LEVEL=warn
    depends_on:
      - db
    networks:
      - webnet
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: webapp
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - webnet

volumes:
  apache-logs:
  mysql-data:

networks:
  webnet:
    driver: bridge

Security Measures to Consider

Securing Apache within containers involves both container-level and Apache-specific configurations:

# Enhancements to Dockerfile security
FROM httpd:2.4-alpine

# Operate as a non-root user
RUN addgroup -g 1001 appgroup && \
    adduser -D -s /bin/sh -u 1001 -G appgroup appuser

# Eliminate extraneous packages and files
RUN apk del --purge wget curl && \
    rm -rf /var/cache/apk/* && \
    rm -rf /usr/local/apache2/htdocs/index.html

# Include security-hardened configuration
COPY --chown=appuser:appgroup security.conf /usr/local/apache2/conf/extra/

# Set secure file permissions
RUN chmod -R o-rwx /usr/local/apache2/conf/ && \
    chown -R appuser:appgroup /usr/local/apache2/

USER appuser

EXPOSE 8080

For detailed Apache documentation and advanced configuration options, refer to the official Apache HTTP server documentation. The Docker development best practices guide offers further insights for optimising container workflows.

Utilising Apache within Docker containers provides exceptional adaptability for both development and live environments. The paramount success factor lies in comprehending the relationship between Apache’s process model and Docker’s container lifecycle, implementing adequate security protocols, and fine-tuning for your particular requirements. Whether you’re serving static resources, executing PHP applications, or establishing reverse proxies, these configurations and patterns establish a reliable base for effective Apache deployments.



This article draws on information and materials from various online sources. We recognise and appreciate the contributions of all original authors, publishers, and websites. While efforts have been made to correctly attribute source materials, any inadvertent oversights or omissions do not constitute copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article serves informational and educational purposes only and does not infringe copyright holders’ rights. Should any copyrighted material be used without appropriate credit or in violation of copyright laws, it is unintentional, and we will correct it promptly upon notification. Please note that republishing, redistributing, or reproducing any part of the content in any form is prohibited without explicit written permission from the author and website owner. For permissions or further inquiries, please contact us.