From 46d17d9a1b1ceeddc1c7b9c57fbabb2c17d2d358 Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Tue, 19 May 2026 20:34:04 +0900 Subject: [PATCH] Align dev container Instant Client TZ data with Oracle server Apply the workaround from #292 to the dev container. CI fixed `ORA-01805: possible error in date/time operation` by copying the running Oracle server's `timezlrg_*.dat` into the Instant Client's `oracore/zoneinfo/` and pointing `ORA_TZFILE` at it. The dev container combines `gvenzl/oracle-free:latest` with the Instant Client installed via the app `Dockerfile`, so it is exposed to the same drift and benefits from the same fix. PR #301 ported the workaround by adding the `docker-outside-of-docker` feature and copying the file from inside the dev container via `docker exec` / `docker cp`. That approach fails on Dev Containers 0.459.0 with the `mcr.microsoft.com/devcontainers/base:trixie` base image because Debian trixie removed `moby-cli`: (!) The 'moby' option is not supported on Debian 'trixie' because 'moby-cli' and related system packages have been removed from that distribution. ERROR: Feature "Docker (docker-outside-of-docker)" failed to install! Move the copy to the host, where Docker is already available. Mirrors rsim/oracle-enhanced#2799. - `.devcontainer/initializeCommand.sh` (new) -- pull `gvenzl/oracle-free:latest`, then extract `$ORACLE_HOME/oracore/zoneinfo/timezlrg_*.dat` from an ephemeral container into `.devcontainer/tzdata/` on the host. No DB start, no readiness wait -- the file ships in the image. - `.devcontainer/devcontainer.json` -- `initializeCommand` now runs the new script (it previously did the inline `docker pull`). The `docker-outside-of-docker` feature, added in #301 and never merged to master, stays absent. - `.devcontainer/docker-compose.yml` -- bind-mount `.devcontainer/tzdata` read-only at `/opt/tzdata` inside the `app` service. - `.devcontainer/postCreateCommand.sh` -- set `ORA_TZFILE` from `/opt/tzdata/timezlrg_*.dat` and persist it via `/etc/profile.d/ora-tzfile.sh` so interactive shells and `bundle exec` runs pick it up. - `.gitignore` -- ignore `.devcontainer/tzdata/`. No `docker-outside-of-docker` feature, no `/var/run/docker.sock` bind, and no network access during the dev container build. Co-Authored-By: Claude Opus 4.7 (1M context) --- .devcontainer/devcontainer.json | 2 +- .devcontainer/docker-compose.yml | 1 + .devcontainer/initializeCommand.sh | 19 +++++++++++++++++++ .devcontainer/postCreateCommand.sh | 12 ++++++++++++ .gitignore | 1 + 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100755 .devcontainer/initializeCommand.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b845dee..5cf3826 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,7 +15,7 @@ ] } }, - "initializeCommand": "docker pull gvenzl/oracle-free:latest", + "initializeCommand": "bash .devcontainer/initializeCommand.sh", "postCreateCommand": "bash .devcontainer/postCreateCommand.sh", "remoteEnv": { "DATABASE_NAME": "FREEPDB1", diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index ae47d9a..4e2c380 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -5,6 +5,7 @@ services: dockerfile: Dockerfile volumes: - ../..:/workspaces:cached + - ./tzdata:/opt/tzdata:ro command: sleep infinity network_mode: service:oracle diff --git a/.devcontainer/initializeCommand.sh b/.devcontainer/initializeCommand.sh new file mode 100755 index 0000000..6159e08 --- /dev/null +++ b/.devcontainer/initializeCommand.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -euo pipefail + +IMAGE=gvenzl/oracle-free:latest +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +OUT_DIR="$SCRIPT_DIR/tzdata" + +docker pull "$IMAGE" + +mkdir -p "$OUT_DIR" +rm -f "$OUT_DIR"/timezlrg_*.dat "$OUT_DIR"/timezdif_*.dat + +docker run --rm --entrypoint sh \ + -v "$OUT_DIR:/out" \ + "$IMAGE" \ + -c 'cp "$ORACLE_HOME"/oracore/zoneinfo/timezlrg_*.dat /out/ && chmod a+r /out/*.dat' + +ls -1 "$OUT_DIR" diff --git a/.devcontainer/postCreateCommand.sh b/.devcontainer/postCreateCommand.sh index 22c8c4b..35e6581 100755 --- a/.devcontainer/postCreateCommand.sh +++ b/.devcontainer/postCreateCommand.sh @@ -5,6 +5,18 @@ set -e gem update --system bundle install +# Match Instant Client TZ data to the Oracle server's to avoid ORA-01805. +# The file is extracted from the gvenzl image into .devcontainer/tzdata/ by +# initializeCommand.sh and bind-mounted read-only at /opt/tzdata. +TZ_FILE=$(ls /opt/tzdata/timezlrg_*.dat 2>/dev/null | head -1) +if [ -n "$TZ_FILE" ]; then + echo "Using $TZ_FILE for Instant Client TZ data." + export ORA_TZFILE="$TZ_FILE" + echo "export ORA_TZFILE=$TZ_FILE" | sudo tee /etc/profile.d/ora-tzfile.sh > /dev/null +else + echo "Warning: no timezlrg_*.dat found under /opt/tzdata; skipping ORA_TZFILE setup." >&2 +fi + echo "Waiting for Oracle to be ready..." oracle_ready=false for i in $(seq 1 30); do diff --git a/.gitignore b/.gitignore index 8aeed57..e5808ef 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ Gemfile.lock *.zip .idea spec/support/custom_config.rb +.devcontainer/tzdata/