Skip to content

Commit

Permalink
Install DB and apply patches in a single layer
Browse files Browse the repository at this point in the history
The oracle-docker-images repository allows patches to be applied, but the resulting image size is doubled (see oracle#1990). Instead, we would like to apply the patches in the same layer where the database binaries are installed.

I have applied this only to the 19c and 21c Dockerfiles since the other versions are either at or rapidly approaching end of life.

Changes:
- Set SLIMMING to false to ensure that all files required for patching are present.
- Copied patchDBBinaries.sh, runDatapatch.sh and savePatchSummary.sh from the extensions/patch directory.
- Modified patchDBBinaries.sh to delete temporary files to reduce image size.
- Added steps to builder stage in Dockerfile to copy the patches to the container and run the patchDBBinaries.sh script.
- Added steps to Dockerfile to copy datapatch and lspatches scripts under $ORACLE_BASE.
  • Loading branch information
thelateperseus committed Mar 21, 2023
1 parent 0596473 commit b868b60
Show file tree
Hide file tree
Showing 12 changed files with 360 additions and 2 deletions.
28 changes: 27 additions & 1 deletion OracleDatabase/SingleInstance/dockerfiles/19.3.0/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ LABEL "provider"="Oracle" \
"port.oemexpress"="5500"

# Argument to control removal of components not needed after db software installation
ARG SLIMMING=true
ARG SLIMMING=false
ARG INSTALL_FILE_1="LINUX.X64_193000_db_home.zip"

# Environment variables required for this build (do NOT change)
Expand Down Expand Up @@ -79,6 +79,11 @@ ENV PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch/:/usr/sbin:$PATH \
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib \
CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

# Environment variables for patching
ENV HOST_PATCH_DIR="patches" \
PATCH_DIR=/opt/install/patches \
PATCH_DB_BINARIES_FILE="patchDBBinaries.sh"

# Copy files needed during both installation and runtime
# -------------
COPY $SETUP_LINUX_FILE $CHECK_SPACE_FILE $INSTALL_DIR/
Expand Down Expand Up @@ -111,6 +116,14 @@ RUN chmod ug+x $INSTALL_DIR/*.sh && \
sync && \
$INSTALL_DIR/$INSTALL_DB_BINARIES_FILE $DB_EDITION

# Copy DB patches
COPY --chown=oracle:dba $HOST_PATCH_DIR $PATCH_DB_BINARIES_FILE $PATCH_DIR/

# Apply DB Patches
RUN chmod ug+x $PATCH_DIR/*.sh && \
sync && \
$PATCH_DIR/$PATCH_DB_BINARIES_FILE



#############################################
Expand All @@ -134,6 +147,19 @@ WORKDIR /home/oracle
# Add a bashrc file to capitalize ORACLE_SID in the environment
RUN echo 'ORACLE_SID=${ORACLE_SID:-ORCLCDB}; export ORACLE_SID=${ORACLE_SID^^}' > .bashrc

# Environment variables for patching
ENV DATAPATCH_FILE="runDatapatch.sh" \
LSPATCHES_FILE="savePatchSummary.sh" \
SKIP_DATAPATCH=false

# Copy script to run datapatch
COPY --chown=oracle:dba $DATAPATCH_FILE $ORACLE_BASE/scripts/extensions/startup/
RUN chmod ug+x $ORACLE_BASE/scripts/extensions/startup/*.sh && sync

# Copy script to run lspatches
COPY --chown=oracle:dba $LSPATCHES_FILE $ORACLE_BASE/scripts/extensions/setup/
RUN chmod ug+x $ORACLE_BASE/scripts/extensions/setup/*.sh && sync

HEALTHCHECK --interval=1m --start-period=5m --timeout=30s \
CMD "$ORACLE_BASE/$CHECK_DB_FILE" >/dev/null || exit 1

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash
# LICENSE UPL 1.0
#
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
#
# Since: March, 2020
# Author: [email protected]
# Description: Applies the patches provided by the user on the oracle home.
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#

RU_DIR="${PATCH_DIR}/release_update"
ONE_OFFS_DIR="${PATCH_DIR}/one_offs"

ru_count=$(ls $RU_DIR/*.zip 2> /dev/null | wc -l)
if [ $ru_count -ge 2 ]; then
echo "Error: Only 1 Release Update can be applied."
exit 1;
elif [ $ru_count == 1 ]; then
ru_patch="$(ls $RU_DIR/*.zip)"
echo "Unzipping $ru_patch";
unzip -qo $ru_patch -d $PATCH_DIR;
ru_patch=$(echo ${ru_patch##*/} | cut -d_ -f1 | cut -dp -f2)
else
echo "No Release Update to be installed."
fi

ONE_OFFS_LIST=()

if ls $ONE_OFFS_DIR/*.zip 2> /dev/null; then
for patch_zip in $ONE_OFFS_DIR/*.zip; do
patch_no=$(echo ${patch_zip##*/} | cut -d_ -f1 | cut -dp -f2)
if [ $patch_no == "6880880" ]; then
echo "Removing directory ${ORACLE_HOME}/OPatch";
rm -rf ${ORACLE_HOME}/OPatch;
echo "Unzipping OPatch archive $patch_zip to ${ORACLE_HOME}";
unzip -qo $patch_zip -d $ORACLE_HOME;
else
ONE_OFFS_LIST+=($patch_no);
echo "Unzipping $patch_zip";
unzip -qo $patch_zip -d $PATCH_DIR;
fi
done
else
echo "No one-offs to be installed."
fi

export PATH=${ORACLE_HOME}/perl/bin:$PATH;

if [ ! -z $ru_patch ]; then
echo "Applying Release Update: $ru_patch";
cmd="${ORACLE_HOME}/OPatch/opatchauto apply -binary -oh $ORACLE_HOME ${PATCH_DIR}/${ru_patch} -target_type rac_database";
echo "Running: $cmd";
$cmd || {
echo "RU application failed for patchset: ${ru_patch}";
exit 1;
}
fi

for patch in ${ONE_OFFS_LIST[@]}; do
echo "Applying patch: $patch";
cmd="${ORACLE_HOME}/OPatch/opatchauto apply -binary -oh $ORACLE_HOME ${PATCH_DIR}/${patch} -target_type rac_database";
echo "Running: $cmd";
$cmd || {
echo "Patch application failed for ${patch}";
exit 1;
}
done

# Remove not needed components
# APEX
rm -rf "$ORACLE_HOME"/apex && \
# ORDS
rm -rf "$ORACLE_HOME"/ords && \
# SQL Developer
rm -rf "$ORACLE_HOME"/sqldeveloper && \
# UCP connection pool
rm -rf "$ORACLE_HOME"/ucp && \
# All installer files
rm -rf "$ORACLE_HOME"/lib/*.zip && \
# OUI backup
rm -rf "$ORACLE_HOME"/inventory/backup/* && \
# Network tools help
rm -rf "$ORACLE_HOME"/network/tools/help && \
# Database upgrade assistant
rm -rf "$ORACLE_HOME"/assistants/dbua && \
# Database migration assistant
rm -rf "$ORACLE_HOME"/dmu && \
# Remove pilot workflow installer
rm -rf "$ORACLE_HOME"/install/pilot && \
# Support tools
rm -rf "$ORACLE_HOME"/suptools && \
# Temp location
rm -rf /tmp/* && \
# Database files directory
rm -rf "$INSTALL_DIR"/database
# Database patch directories
rm -rf $PATCH_DIR/* $ORACLE_HOME/.patch_storage
Empty file.
Empty file.
38 changes: 38 additions & 0 deletions OracleDatabase/SingleInstance/dockerfiles/19.3.0/runDatapatch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
# LICENSE UPL 1.0
#
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
#
# Since: March, 2020
# Author: [email protected]
# Description: Runs datapatch in a container while using existing datafiles if container is at different RU level
# than the container which created the datafiles
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#

if [ "${SKIP_DATAPATCH}" = "true" ]; then
echo "Skipping Datapatch"
exit 0;
fi

# LSPATCHES_FILE will have the patch summary of the datafiles.
DBCONFIG_DIR="${ORACLE_BASE}/oradata/dbconfig/${ORACLE_SID}"
LSPATCHES_FILE="${DBCONFIG_DIR}/${ORACLE_SID}.lspatches"

# tmp.lspatches will have the patch summary of the oracle home.
temp_lspatches_file="/tmp/tmp.lspatches"
$ORACLE_HOME/OPatch/opatch lspatches > ${temp_lspatches_file};

if diff ${LSPATCHES_FILE} ${temp_lspatches_file} 2> /dev/null; then
echo "Datafiles are already patched. Skipping datapatch run."
else
echo "Running datapatch...";
if ! $ORACLE_HOME/OPatch/datapatch -skip_upgrade_check; then
echo "Datapatch execution has failed.";
exit 1;
else
echo "DONE: Datapatch execution."
cp ${temp_lspatches_file} ${LSPATCHES_FILE};
fi
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
# LICENSE UPL 1.0
#
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
#
# Since: March, 2020
# Author: [email protected]
# Description: Runs lspatches to save summary of installed patches just after new db is created.
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#

LSPATCHES_FILE="${ORACLE_SID}.lspatches"
LSPATCHES_FILE_PATH="${ORACLE_BASE}/oradata/dbconfig/${ORACLE_SID}/${LSPATCHES_FILE}"

$ORACLE_HOME/OPatch/opatch lspatches > ${LSPATCHES_FILE_PATH};
28 changes: 27 additions & 1 deletion OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ LABEL "provider"="Oracle" \
"port.oemexpress"="5500"

# Argument to control removal of components not needed after db software installation
ARG SLIMMING=true
ARG SLIMMING=false
ARG INSTALL_FILE_1="LINUX.X64_213000_db_home.zip"

# Environment variables required for this build (do NOT change)
Expand Down Expand Up @@ -80,6 +80,11 @@ ENV PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch/:/usr/sbin:$PATH \
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib \
CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

# Environment variables for patching
ENV HOST_PATCH_DIR="patches" \
PATCH_DIR=/opt/install/patches \
PATCH_DB_BINARIES_FILE="patchDBBinaries.sh"

# Copy files needed during both installation and runtime
# -------------
COPY $SETUP_LINUX_FILE $CHECK_SPACE_FILE $INSTALL_DIR/
Expand Down Expand Up @@ -112,6 +117,14 @@ RUN chmod ug+x $INSTALL_DIR/*.sh && \
sync && \
$INSTALL_DIR/$INSTALL_DB_BINARIES_FILE $DB_EDITION

# Copy DB patches
COPY --chown=oracle:dba $HOST_PATCH_DIR $PATCH_DB_BINARIES_FILE $PATCH_DIR/

# Apply DB Patches
RUN chmod ug+x $PATCH_DIR/*.sh && \
sync && \
$PATCH_DIR/$PATCH_DB_BINARIES_FILE



#############################################
Expand All @@ -135,6 +148,19 @@ WORKDIR /home/oracle
# Add a bashrc file to capitalize ORACLE_SID in the environment
RUN echo 'ORACLE_SID=${ORACLE_SID:-ORCLCDB}; export ORACLE_SID=${ORACLE_SID^^}' > .bashrc

# Environment variables for patching
ENV DATAPATCH_FILE="runDatapatch.sh" \
LSPATCHES_FILE="savePatchSummary.sh" \
SKIP_DATAPATCH=false

# Copy script to run datapatch
COPY --chown=oracle:dba $DATAPATCH_FILE $ORACLE_BASE/scripts/extensions/startup/
RUN chmod ug+x $ORACLE_BASE/scripts/extensions/startup/*.sh && sync

# Copy script to run lspatches
COPY --chown=oracle:dba $LSPATCHES_FILE $ORACLE_BASE/scripts/extensions/setup/
RUN chmod ug+x $ORACLE_BASE/scripts/extensions/setup/*.sh && sync

HEALTHCHECK --interval=1m --start-period=5m --timeout=30s \
CMD "$ORACLE_BASE/$CHECK_DB_FILE" >/dev/null || exit 1

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash
# LICENSE UPL 1.0
#
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
#
# Since: March, 2020
# Author: [email protected]
# Description: Applies the patches provided by the user on the oracle home.
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#

RU_DIR="${PATCH_DIR}/release_update"
ONE_OFFS_DIR="${PATCH_DIR}/one_offs"

ru_count=$(ls $RU_DIR/*.zip 2> /dev/null | wc -l)
if [ $ru_count -ge 2 ]; then
echo "Error: Only 1 Release Update can be applied."
exit 1;
elif [ $ru_count == 1 ]; then
ru_patch="$(ls $RU_DIR/*.zip)"
echo "Unzipping $ru_patch";
unzip -qo $ru_patch -d $PATCH_DIR;
ru_patch=$(echo ${ru_patch##*/} | cut -d_ -f1 | cut -dp -f2)
else
echo "No Release Update to be installed."
fi

ONE_OFFS_LIST=()

if ls $ONE_OFFS_DIR/*.zip 2> /dev/null; then
for patch_zip in $ONE_OFFS_DIR/*.zip; do
patch_no=$(echo ${patch_zip##*/} | cut -d_ -f1 | cut -dp -f2)
if [ $patch_no == "6880880" ]; then
echo "Removing directory ${ORACLE_HOME}/OPatch";
rm -rf ${ORACLE_HOME}/OPatch;
echo "Unzipping OPatch archive $patch_zip to ${ORACLE_HOME}";
unzip -qo $patch_zip -d $ORACLE_HOME;
else
ONE_OFFS_LIST+=($patch_no);
echo "Unzipping $patch_zip";
unzip -qo $patch_zip -d $PATCH_DIR;
fi
done
else
echo "No one-offs to be installed."
fi

export PATH=${ORACLE_HOME}/perl/bin:$PATH;

if [ ! -z $ru_patch ]; then
echo "Applying Release Update: $ru_patch";
cmd="${ORACLE_HOME}/OPatch/opatchauto apply -binary -oh $ORACLE_HOME ${PATCH_DIR}/${ru_patch} -target_type rac_database";
echo "Running: $cmd";
$cmd || {
echo "RU application failed for patchset: ${ru_patch}";
exit 1;
}
fi

for patch in ${ONE_OFFS_LIST[@]}; do
echo "Applying patch: $patch";
cmd="${ORACLE_HOME}/OPatch/opatchauto apply -binary -oh $ORACLE_HOME ${PATCH_DIR}/${patch} -target_type rac_database";
echo "Running: $cmd";
$cmd || {
echo "Patch application failed for ${patch}";
exit 1;
}
done

# Remove not needed components
# APEX
rm -rf "$ORACLE_HOME"/apex && \
# ORDS
rm -rf "$ORACLE_HOME"/ords && \
# SQL Developer
rm -rf "$ORACLE_HOME"/sqldeveloper && \
# UCP connection pool
rm -rf "$ORACLE_HOME"/ucp && \
# All installer files
rm -rf "$ORACLE_HOME"/lib/*.zip && \
# OUI backup
rm -rf "$ORACLE_HOME"/inventory/backup/* && \
# Network tools help
rm -rf "$ORACLE_HOME"/network/tools/help && \
# Database upgrade assistant
rm -rf "$ORACLE_HOME"/assistants/dbua && \
# Database migration assistant
rm -rf "$ORACLE_HOME"/dmu && \
# Remove pilot workflow installer
rm -rf "$ORACLE_HOME"/install/pilot && \
# Support tools
rm -rf "$ORACLE_HOME"/suptools && \
# Temp location
rm -rf /tmp/* && \
# Database files directory
rm -rf "$INSTALL_DIR"/database
# Database patch directories
rm -rf $PATCH_DIR/* $ORACLE_HOME/.patch_storage
Empty file.
Empty file.
Loading

0 comments on commit b868b60

Please sign in to comment.