This Dockerfile sets up a PHP environment with Apache, installs necessary system dependencies and PHP extensions, configures PHP for Google Cloud Run, and includes Composer for dependency management. Additionally, it customizes the Apache configuration to use the environment variable for the port. Basically this setup is intended for laravel but learn from this to apply to other frameworks as well

Dockerfile

# Use the official PHP image.
# https://hub.docker.com/_/php
FROM php:8.3-apache

# Install system dependencies and PHP extensions
RUN apt-get update && apt-get install -y \
  libfreetype6-dev \
  libjpeg62-turbo-dev \
  libpng-dev \
  libzip-dev \
  libpq-dev \
  libsqlite3-dev \
  zip \
  unzip \
  postgresql-client \
  && docker-php-ext-install -j "$(nproc)" opcache gd zip pdo_pgsql \
  && docker-php-ext-configure gd --with-freetype --with-jpeg

# Configure PHP for Cloud Run.
RUN set -ex; \
  { \
  echo "; Cloud Run enforces memory & timeouts"; \
  echo "memory_limit = -1"; \
  echo "max_execution_time = 0"; \
  echo "; File upload at Cloud Run network limit"; \
  echo "upload_max_filesize = 1G"; \
  echo "post_max_size = 1G"; \
  echo "; Configure Opcache for Containers"; \
  echo "opcache.enable = On"; \
  echo "opcache.validate_timestamps = Off"; \
  echo "; Configure Opcache Memory (Application-specific)"; \
  echo "opcache.memory_consumption = 32"; \
  } > "$PHP_INI_DIR/conf.d/cloud-run.ini"

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

# Copy in custom code from the host machine.
WORKDIR /var/www/html

COPY . ./

COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

RUN chmod 777 -R /var/www
RUN chown -R www-data:www-data /var/www

# Ensure the storage and cache directories exist
RUN mkdir -p /var/www/html/storage/logs /var/www/html/bootstrap/cache

# Set the correct permissions for Laravel
RUN chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache

# RUN composer install --no-scripts --no-interaction --prefer-dist

# Use the PORT environment variable in Apache configuration files.
# https://cloud.google.com/run/docs/reference/container-contract#port
ENV PORT=8080

RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf

# Configure PHP for development.
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

# Enable Apache modules
RUN a2enmod rewrite

# Expose the port
EXPOSE 8080

COPY entrypoint.sh ./
RUN chmod +x entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]

Here’s an explanation of each line in the provided Dockerfile:

1. Base Image and Metadata

# Use the official PHP image.
# https://hub.docker.com/_/php
FROM php:8.3-apache
  • FROM php:8.3-apache: This line specifies the base image for the Docker container. It uses the official PHP image with version 8.3, bundled with the Apache HTTP server.

2. Install Dependencies

# Install system dependencies and PHP extensions
RUN apt-get update && apt-get install -y \
  libfreetype6-dev \
  libjpeg62-turbo-dev \
  libpng-dev \
  libzip-dev \
  libpq-dev \
  libsqlite3-dev \
  zip \
  unzip \
  postgresql-client \
  && docker-php-ext-install -j "$(nproc)" opcache gd zip pdo_pgsql \
  && docker-php-ext-configure gd --with-freetype --with-jpeg
  • RUN apt-get update && apt-get install -y: Updates the package lists for APT and installs the specified packages.
    • libfreetype6-dev, libjpeg62-turbo-dev, libpng-dev: Libraries for image processing.
    • libzip-dev, libpq-dev, libsqlite3-dev: Libraries for ZIP files, PostgreSQL, and SQLite.
    • zip, unzip: Utilities for handling ZIP files.
    • postgresql-client: Client tools for PostgreSQL.
  • docker-php-ext-install: Installs PHP extensions.
    • opcache: A caching mechanism to improve PHP performance.
    • gd: A library for image processing.
    • zip: Supports ZIP archive creation.
    • pdo_pgsql: PHP Data Objects (PDO) extension for PostgreSQL.
  • docker-php-ext-configure gd –with-freetype –with-jpeg: Configures the GD extension with FreeType and JPEG support.

3. Configure PHP for Cloud Run

# Configure PHP for Cloud Run.
RUN set -ex; \
  { \
  echo "; Cloud Run enforces memory & timeouts"; \
  echo "memory_limit = -1"; \
  echo "max_execution_time = 0"; \
  echo "; File upload at Cloud Run network limit"; \
  echo "upload_max_filesize = 1G"; \
  echo "post_max_size = 1G"; \
  echo "; Configure Opcache for Containers"; \
  echo "opcache.enable = On"; \
  echo "opcache.validate_timestamps = Off"; \
  echo "; Configure Opcache Memory (Application-specific)"; \
  echo "opcache.memory_consumption = 32"; \
  } > "$PHP_INI_DIR/conf.d/cloud-run.ini"
  • RUN set -ex; \ { \ … } > “$PHP_INI_DIR/conf.d/cloud-run.ini”: Adds custom PHP configurations specific to Cloud Run:
    • memory_limit = -1: No memory limit.
    • max_execution_time = 0: No execution time limit.
    • upload_max_filesize = 1G, post_max_size = 1G: Allows large file uploads up to 1GB.
    • opcache.enable = On: Enables opcode caching.
    • opcache.validate_timestamps = Off: Disables automatic cache invalidation.
    • opcache.memory_consumption = 32: Sets the memory allocated for opcode caching to 32MB.

4. Install Composer

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
  • COPY –from=composer:latest /usr/bin/composer /usr/bin/composer: Copies the Composer binary from the latest Composer Docker image to the current image.

5. Setup Working Directory and Copy Application Code

# Copy in custom code from the host machine.
WORKDIR /var/www/html

COPY . ./
  • WORKDIR /var/www/html: Sets the working directory to /var/www/html.
  • COPY . ./: Copies the entire contents of the current directory on the host machine to the working directory in the container.

6. Apache Configuration

COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

RUN chmod 777 -R /var/www
RUN chown -R www-data:www-data /var/www
  • COPY 000-default.conf /etc/apache2/sites-available/000-default.conf: Copies the Apache configuration file to the container.
  • RUN chmod 777 -R /var/www: Grants full permissions to all users for the /var/www directory.
  • RUN chown -R www-data:www-data /var/www: Changes the ownership of the /var/www directory to the www-data user and group.
<VirtualHost *:80>
	ServerName localhost
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/public
	<Directory /var/www/html/public/>
		Options Indexes FollowSymLinks
		AllowOverride All
		Require all granted
	</Directory>
</VirtualHost>

7. Create and Set Permissions for Storage and Cache Directories

# Ensure the storage and cache directories exist
RUN mkdir -p /var/www/html/storage/logs /var/www/html/bootstrap/cache

# Set the correct permissions for Laravel
RUN chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache
  • RUN mkdir -p /var/www/html/storage/logs /var/www/html/bootstrap/cache: Ensures the necessary directories exist for Laravel’s storage and cache.
  • RUN chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache: Sets full permissions for the storage and cache directories.

8. Uncomment Composer Install (Optional)

# RUN composer install --no-scripts --no-interaction --prefer-dist
  • RUN composer install –no-scripts –no-interaction –prefer-dist: (Commented out) Installs PHP dependencies using Composer. Uncomment if needed.

9. Configure Apache to Use PORT Environment Variable

# Use the PORT environment variable in Apache configuration files.
# https://cloud.google.com/run/docs/reference/container-contract#port
ENV PORT=8080

RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
  • ENV PORT=8080: Sets the environment variable PORT to 8080.
  • RUN sed -i ’s/80/${PORT}/g’ /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf: Replaces occurrences of port 80 with the value of the PORT environment variable in Apache configuration files.

10. Configure PHP for Development

# Configure PHP for development.
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
  • RUN mv “$PHP_INI_DIR/php.ini-development” “$PHP_INI_DIR/php.ini”: Replaces the default PHP configuration with the development configuration.

11. Enable Apache Modules

# Enable Apache modules
RUN a2enmod rewrite
  • RUN a2enmod rewrite: Enables the mod_rewrite module in Apache, which is required for URL rewriting.

12. Expose the Port

# Expose the port
EXPOSE 8080
  • EXPOSE 8080: Informs Docker that the container listens on port 8080.

13. Set Entry Point

COPY entrypoint.sh ./
RUN chmod +x entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]
  • COPY entrypoint.sh ./: Copies the entrypoint.sh script to the container.
  • RUN chmod +x entrypoint.sh: Makes the entrypoint.sh script executable.
  • ENTRYPOINT ["./entrypoint.sh"]: Sets the entrypoint.sh script as the entry point for the container. This script will be executed when the container starts.

These explanations provide a detailed understanding of each line in the Dockerfile, ensuring that the purpose and function of each instruction are clear.