Containerized PHP Development with Apache and Oracle on Mac Silicon Using Docker

Developing a modern PHP application with Apache and Oracle on a Mac with Apple Silicon (M1/M2/M3) can present some challenges—especially when deploying to Intel-based environments. This guide walks you through setting up a containerized development environment using Docker Desktop, the CodeIgniter PHP framework, and Oracle's Instant Client. By explicitly targeting the linux/amd64 platform, you'll ensure compatibility with Intel-based Linux and Windows systems, simplifying deployment and collaboration.

Why Use Docker on Mac Silicon?

Developing on Apple Silicon means working with an ARM-based architecture, whereas most production and enterprise environments still use Intel (x86_64). This architecture mismatch can cause compatibility issues when installing dependencies—especially when dealing with low-level libraries like the Oracle Instant Client.

Docker bridges this gap by allowing you to run containers that emulate the target architecture (linux/amd64). This means your CodeIgniter + Apache + Oracle setup will work the same whether you're on Mac, Linux, or Windows. Additionally, Docker keeps your dependencies isolated, avoids system-level conflicts, and allows for reproducible environments with ease.


Step 1: Install Docker Desktop for Mac Silicon

Follow the official Docker installation guide for Mac with Apple Silicon: 👉 https://docs.docker.com/desktop/setup/install/mac-install


Step 2: Set Up Your CodeIgniter Project

Create your project directory and install the CodeIgniter 4 framework using Composer:

composer create-project codeigniter4/appstarter project-root

This will create a project folder named project-root and build all the necessary directories within project-root for CodeIgniter. Name this directory to whatever the name of your project is going to be.

Step 3: Create the Dockerfile

FROM php:8.2-apache

# Install required dependencies
RUN apt-get update && apt-get install -y \
    unzip \
    libaio1 \
    libicu-dev \
    && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install intl

# Set working directory for Oracle client install
WORKDIR /opt/oracle

# Copy the Oracle Instant Client ZIP files into the image
COPY instantclient-basic-linux.x64-23.8.0.25.04.zip /tmp
COPY instantclient-sdk-linux.x64-23.8.0.25.04.zip /tmp

# Unzip and configure Oracle Instant Client
RUN mkdir -p /opt/oracle \
    && unzip -o /tmp/instantclient-basic-linux.x64-23.8.0.25.04.zip -d /opt/oracle \
    && unzip -o /tmp/instantclient-sdk-linux.x64-23.8.0.25.04.zip -d /opt/oracle \
    && ln -s /opt/oracle/instantclient_23_8 /opt/oracle/instantclient \
    && echo /opt/oracle/instantclient > /etc/ld.so.conf.d/oracle-instantclient.conf \
    && ldconfig

# Set environment variables
ENV LD_LIBRARY_PATH=/opt/oracle/instantclient
ENV ORACLE_HOME=/opt/oracle/instantclient

# Install oci8 extension
RUN docker-php-ext-configure oci8 --with-oci8=instantclient,/opt/oracle/instantclient \
    && docker-php-ext-install oci8

# Enable Apache rewrite module
RUN a2enmod rewrite

# Switch to web root for app
WORKDIR /var/www/html/public

# Optional: copy entrypoint and Apache site config
COPY startup.sh /var/www/html/public/startup.sh
COPY apache-site.conf /etc/apache2/sites-available/000-default.conf
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf

# Expose HTTP port
EXPOSE 80

This Dockerfile builds a containerized web environment designed for PHP development using the Apache web server and Oracle 23c database connectivity. It also supports the CodeIgniter 4 framework and is tailored for cross-platform compatibility (especially for deployment from Apple Silicon to Intel-based systems).

Key Points:

FROM: This line defines the base image for your container: PHP 8.2 with Apache pre-installed. It gives you a solid foundation for running PHP applications on an Apache HTTP server, commonly used in traditional LAMP stacks.

The RUN apt-get command installs these packages in the Linux container::

  • unzip: Extracting the Oracle Instant Client ZIP files.

  • libaio1: Required by Oracle’s libraries for async I/O.

  • libicu-dev: Needed for the PHP intl extension, useful for internationalization (e.g., date, time, locale formatting).

The rm -rf /var/lib/apt/lists/* command cleans up after package installation, reducing the image size.

The RUN docker-php-ext-install command Installs the intl extension, commonly needed by modern PHP frameworks like CodeIgniter or Laravel for handling localization and formatting.

The Oracle instant client is installed. It copies the instant client files int the working directory /tmp. Then unzips the Instant Client ZIP files into the /opt/oracle/instantclient.<version> directory. A symbolic link is made to the /opt/oracle/instantclient directory. This allows for the software to be changed but the PHP environment will use the instantclient symbolic link.

The environment variables are set in preparation of building the PHP software

RUN docker-php-ext-configure is building the OCI8 library necessary for PHP to connect to an Oracle database.

The Copy commands copy the files from the host laptop to the directory inside the container

The Run command sets the ServerName in the Apache configuration file and then port 80 is set to be open for the container.

Step 4: Create the docker-compose.yml File

services:
  web:
    platform: linux/amd64  # Target Intel architecture
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8088:80"
    container_name: certapp
    volumes:
      - ./sslCertCheckApp:/var/www/html
    working_dir: /var/www/html/public
    # entrypoint: ["/var/www/html/public/startup.sh"]

Key Points:

  • platform: linux/amd64: Ensures the container is built for Intel-based architecture—even when running on Apple Silicon. This improves compatibility with most production environments.

  • build.context and dockerfile: Tells Docker to build the image from the current directory using the specified Dockerfile.

  • ports: Maps port 8088 on the host machine to port 80 in the container, making the web app accessible at http://localhost:8088.

  • container_name: Names the running container certapp, making it easier to reference with Docker CLI commands.

  • volumes: Mounts your local ./sslCertCheckApp directory into the container at /var/www/html, allowing live code changes during development.

Step 5: CodeIgniter Configuration

Update your CodeIgniter .env file:

CI_ENVIRONMENT = development

database.default.hostname = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.250)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=freepdb1)))
database.default.database = freepdb1
database.default.username = YOUR_USERNAME
database.default.password = YOUR_PASSWORD
database.default.DBDriver = OCI8
database.default.DBPrefix =
database.default.port = 1521
database.default.charset = AL32UTF8
database.default.DBDebug = true

Update the base URL in app/Config/App.php:

public string $baseURL = 'http://localhost:80/';

Next Steps

When complete the directory structure should look like this:

project-root/
├── docker-compose.yml
├── Dockerfile
├── apache-site.conf
├── startup.sh
├── instantclient-basic-linux.x64-23.8.0.25.04.zip
├── instantclient-sdk-linux.x64-23.8.0.25.04.zip
├── sslCertCheckApp/
│   ├── app/
│   ├── public/
│   ├── tests/
│   ├── vendor/
│   ├── writable/
│   ├── builds
│   ├── composer.json
│   ├── composer.lock
│   ├── env
│   ├── LICENSE
│   ├── phpunit.xml.dist
│   ├── preload.php
│   ├── README.md
│   ├── spark

Run the container

docker-compose up --build

The application should be able to be access at http://localhost:8088.

Final Thoughts

Using Docker to containerize your PHP and Oracle environment on a Mac with Apple Silicon provides a robust, platform-independent development setup. Whether you’re deploying to cloud, Linux, or Windows systems, your containerized stack ensures consistency, reduces bugs, and accelerates your workflow. Docker also simplifies working with complex libraries like the Oracle Instant Client—without needing to pollute your local system.

0
Subscribe to my newsletter

Read articles from Christopher Youll directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Christopher Youll
Christopher Youll