Moving a Linux server PHP application with PHP 8.2 + OCI8 to a Docker-Based PHP 8.3 Setup

We needed to upgrade an Apache 2.4, PHP 8.2 with the OCI8 extension on a Linux Redhat 8 server connected to an Oracle backend. The existing setup was RPM-based on RHEL, and getting OCI8 working had previously required manual handling of the Oracle Instant Client libraries.

When are thinking the move to application to PHP 8.3, and later to PHP 8.5 to follow the strict requirements from our IT security department. Which is a good thing.

The Problem

The current setup required:

  • Manual removal and re-installation of oracle-instantclient
  • Matching the correct libclntsh.so version
  • Updating php82-php-oci8
  • Making sure system libraries aligned with the OS version

That is fine to do, but it require a lot of dnf/yum stuff either on the current production server, which is a NO-NO, or setting up a new Linux server, which again require help from the Linux Server group, so with Docker we thought this could be a better way…

The Idea

Instead of upgrading the OS stack and PHP modules directly, we decided to DOCKER containerize the setup:

  • php:8.3-apache as base image
  • Install Oracle Instant Client inside the container
  • Compile and enable OCI8 in the image
  • Expose Apache on port 8083 on the Docker-Host

Make the environment portable, reproducible, and independent of the host OS. That is the key feature of moving to a Docker setup, instead of a full Linux Redhat server.

What We Did

  1. Built a custom Docker image with PHP 8.3 + OCI8.
  2. Installed Oracle Instant Client during the image build.
  3. Exposed the container on port 8083.
  4. Mounted the application files using a bind mount instead of copying them into the container.

Some of the files had some secrets in them, so instead of adding them to the git repo, we decided to copy them to the volume mount after the Docker container was build and created. This makes it is to change content to the PHP files directly, without worrying about any of the content being exposed in the Git repo.
To be blank: it is actually similar to just copy a bunch of files from one Linux server to another. The security is not less, it is the same. In the Docker setup we will make the volume mount read-only, so it will increase the security not make it worse. The next later will to be locate the secrets, and protect them.


The Result

The container is now:

  • Running PHP 8.3 with OCI8
  • Fully isolated from host OS library conflicts
  • Easy to rebuild
  • Easy to roll back
  • Cleaner from an operational perspective

Most importantly: upgrading PHP in the future will now mean changing a base image tag and rebuilding — not re-engineering system libraries.

This small migration significantly reduced long-term operational risk.

So here is our Dockerfile for the moment. We chose the php-apache image, but of course one can use Alpine or another docker image. This is the one that currently seem to be working.

FROM php:8.3-apache

# Install required system dependencies
RUN apt-get update && apt-get install -y \
    libaio1t64 \
    libaio-dev \
    unzip \
    build-essential \
    && rm -rf /var/lib/apt/lists/* \
    && ln -s /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/x86_64-linux-gnu/libaio.so.1

# Copy Oracle Instant Client packages (download manually first)
COPY instantclient-basic-linux.x64-23.26.1.0.0.zip /tmp/
COPY instantclient-sdk-linux.x64-23.26.1.0.0.zip /tmp/

# Extract Oracle Instant Client Basic
RUN mkdir -p /opt/oracle && \
    unzip -q /tmp/instantclient-basic-linux.x64-23.26.1.0.0.zip -d /opt/oracle

# Extract Oracle Instant Client SDK (force overwrite with -o)
RUN unzip -qo /tmp/instantclient-sdk-linux.x64-23.26.1.0.0.zip -d /opt/oracle

# Create symlink and cleanup
RUN ln -s /opt/oracle/instantclient_23_26 /opt/oracle/instantclient && \
    rm /tmp/*.zip

# Configure library path
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 \
    && docker-php-ext-enable oci8

# Enable Apache modules if needed
RUN a2enmod rewrite

RUN chown -R www-data:www-data /var/www/html

# Expose port
EXPOSE 80

Leave a Reply

Your email address will not be published. Required fields are marked *