-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDockerfile.server-oracle
More file actions
193 lines (162 loc) · 7.73 KB
/
Dockerfile.server-oracle
File metadata and controls
193 lines (162 loc) · 7.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Multi-stage Oracle Linux TMI application build with Oracle ADB support
# Uses Oracle Linux 9 (base for Autonomous Linux) with Oracle Instant Client
#
# This Dockerfile builds TMI with CGO enabled for Oracle database connectivity.
# The resulting image can connect to Oracle Autonomous Database (ADB) using wallets.
#
# Build arguments:
# BUILD_DATE - ISO8601 build timestamp
# GIT_COMMIT - Short git commit hash
# VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH - Version components
#
# Runtime environment variables required:
# TMI_DB_USER - Database username
# TMI_DB_PASSWORD - Database password
# TMI_ORACLE_CONNECT_STRING - TNS alias or Easy Connect string
# TMI_ORACLE_WALLET_LOCATION - Path to wallet directory (mounted volume)
# Stage 1: Build environment using Oracle Linux 9
FROM container-registry.oracle.com/os/oraclelinux:9 AS builder
# Metadata for tracking
LABEL security.scan-date="AUTO_GENERATED"
LABEL security.patch-level="high-critical"
LABEL maintainer="TMI Security Team"
LABEL stage="builder"
# Build arguments
ARG BUILD_DATE
ARG GIT_COMMIT
ARG VERSION_MAJOR=1
ARG VERSION_MINOR=0
ARG VERSION_PATCH=0
ARG VERSION_PRERELEASE=""
# Install security patches and required packages
# This updates all packages to latest patched versions
RUN dnf -y update && \
dnf -y install \
# Development tools for CGO
gcc \
gcc-c++ \
make \
# Required for Go download verification
tar \
gzip \
# Git for version embedding
git \
# CA certificates for HTTPS
ca-certificates && \
dnf clean all && \
rm -rf /var/cache/dnf
# Install Oracle Instant Client from Oracle Linux repos
# The oracle-instantclient-release package configures the Instant Client repo
RUN dnf -y install oracle-instantclient-release-23ai-el9 && \
dnf -y install \
oracle-instantclient-basic \
oracle-instantclient-devel \
oracle-instantclient-sqlplus && \
dnf clean all && \
rm -rf /var/cache/dnf
# Set Oracle Instant Client environment variables
ENV LD_LIBRARY_PATH=/usr/lib/oracle/23/client64/lib
ENV PATH=$PATH:/usr/lib/oracle/23/client64/bin
ENV PKG_CONFIG_PATH=/usr/lib/oracle/23/client64/lib/pkgconfig
# Install Go 1.26.1 (matches go.mod requirement)
# Use TARGETARCH to download the correct architecture binary
ARG GO_VERSION=1.26.1
ARG TARGETARCH
RUN GOARCH=$(echo ${TARGETARCH} | sed 's/amd64/amd64/;s/arm64/arm64/') && \
curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GOARCH}.tar.gz" -o /tmp/go.tar.gz && \
tar -C /usr/local -xzf /tmp/go.tar.gz && \
rm /tmp/go.tar.gz
# Set Go environment
ENV PATH=$PATH:/usr/local/go/bin
ENV GOPATH=/go
ENV GOCACHE=/go/cache
# Set working directory
WORKDIR /app
# Copy go mod files first for better layer caching
COPY go.mod go.sum ./
# Download dependencies with security verification
RUN go mod download && \
go mod verify
# Copy source code
COPY . .
# Build the application with Oracle support enabled (CGO required)
# TARGETARCH is automatically set by Docker buildx
ARG TARGETARCH
RUN CGO_ENABLED=1 GOOS=linux GOARCH=${TARGETARCH} go build \
-tags oracle \
-ldflags "-s -w \
-X github.com/ericfitz/tmi/api.VersionMajor=${VERSION_MAJOR} \
-X github.com/ericfitz/tmi/api.VersionMinor=${VERSION_MINOR} \
-X github.com/ericfitz/tmi/api.VersionPatch=${VERSION_PATCH} \
-X github.com/ericfitz/tmi/api.VersionPreRelease=${VERSION_PRERELEASE} \
-X github.com/ericfitz/tmi/api.GitCommit=${GIT_COMMIT:-development} \
-X github.com/ericfitz/tmi/api.BuildDate=${BUILD_DATE:-unknown}" \
-trimpath \
-o tmiserver \
./cmd/server
# Stage 2: Runtime image using Oracle Linux 9 (minimal)
FROM container-registry.oracle.com/os/oraclelinux:9-slim
# Metadata for tracking security patches
LABEL security.oracle-linux="9-slim"
LABEL security.scan-date="AUTO_GENERATED"
LABEL security.patch-level="runtime-minimal"
LABEL maintainer="TMI Security Team"
LABEL org.opencontainers.image.title="TMI Server (Oracle ADB)"
LABEL org.opencontainers.image.description="TMI Server with Oracle Autonomous Database support"
LABEL org.opencontainers.image.name="tmi/tmi-server-oracle"
# Build arguments for labels
ARG BUILD_DATE
ARG GIT_COMMIT
LABEL org.opencontainers.image.created="${BUILD_DATE}"
LABEL org.opencontainers.image.revision="${GIT_COMMIT}"
# Install security patches and runtime dependencies only
RUN microdnf -y update && \
microdnf -y install \
# Required for Oracle Instant Client
libaio \
# CA certificates for TLS connections
ca-certificates \
# Required for wallet extraction
unzip \
# Required for entrypoint script
bash && \
microdnf clean all && \
rm -rf /var/cache/yum
# Install Oracle Instant Client runtime (basic only, no devel)
RUN microdnf -y install oracle-instantclient-release-23ai-el9 && \
microdnf -y install oracle-instantclient-basic && \
microdnf clean all && \
rm -rf /var/cache/yum
# Set Oracle Instant Client environment variables
ENV LD_LIBRARY_PATH=/usr/lib/oracle/23/client64/lib
ENV PATH=$PATH:/usr/lib/oracle/23/client64/bin
# Create non-root user for security
RUN groupadd -r tmi && useradd -r -g tmi -s /sbin/nologin tmi
# Create directory for Oracle wallet mount
RUN mkdir -p /wallet && chown tmi:tmi /wallet
# Copy binary from builder
COPY --from=builder /app/tmiserver /tmiserver
RUN chmod +x /tmiserver && chown tmi:tmi /tmiserver
# Create entrypoint script that extracts wallet if needed
# Extract to /tmp/wallet since the mounted /wallet is read-only
# Uses 'env' with exec to ensure environment variables are passed to the process
RUN printf '#!/bin/bash\necho "=== TMI Container Entrypoint ==="\necho "Date: $(date)"\necho "User: $(whoami)"\nWALLET_DIR="/tmp/wallet"\necho ""\necho "=== Checking /wallet mount ==="\nif [ -d "/wallet" ]; then\n ls -la /wallet/ 2>&1\nelse\n echo "ERROR: /wallet directory does not exist!"\nfi\necho ""\nif [ -f "/wallet/wallet.zip" ]; then\n echo "=== Extracting wallet to $WALLET_DIR ==="\n mkdir -p "$WALLET_DIR"\n if unzip -o /wallet/wallet.zip -d "$WALLET_DIR" 2>&1; then\n echo "Wallet extracted successfully"\n # Fix sqlnet.ora to use correct wallet path\n if [ -f "$WALLET_DIR/sqlnet.ora" ]; then\n echo "=== Fixing sqlnet.ora wallet path ==="\n echo "Before:"\n cat "$WALLET_DIR/sqlnet.ora"\n # Update DIRECTORY path in sqlnet.ora to point to extracted wallet\n # Original: DIRECTORY="?/network/admin" -> New: DIRECTORY="/tmp/wallet"\n sed -i "s|DIRECTORY=\\\"[^\\\"]*\\\"|DIRECTORY=\\\"$WALLET_DIR\\\"|g" "$WALLET_DIR/sqlnet.ora"\n echo "After:"\n cat "$WALLET_DIR/sqlnet.ora"\n fi\n echo "=== Wallet contents ==="\n ls -la "$WALLET_DIR"\n else\n echo "ERROR: Failed to extract wallet!"\n fi\nelse\n echo "WARNING: /wallet/wallet.zip not found"\nfi\necho ""\necho "=== Starting TMI Server ==="\nif [ -d "$WALLET_DIR" ] && [ "$(ls -A $WALLET_DIR 2>/dev/null)" ]; then\n echo "Using wallet at $WALLET_DIR"\n exec env TNS_ADMIN="$WALLET_DIR" TMI_ORACLE_WALLET_LOCATION="$WALLET_DIR" /tmiserver "$@"\nelse\n echo "Starting without wallet"\n exec /tmiserver "$@"\nfi\n' > /entrypoint.sh && \
chmod +x /entrypoint.sh && chown tmi:tmi /entrypoint.sh
# Set working directory
WORKDIR /
# Expose port 8080
EXPOSE 8080
# Set secure environment variables
ENV ENV=production
ENV LOG_LEVEL=info
ENV SERVER_PORT=8080
ENV SERVER_INTERFACE=0.0.0.0
ENV GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
# Oracle wallet location (mount point)
ENV TNS_ADMIN=/wallet
# Note: Health check is configured in OCI Container Instances, not in Dockerfile
# This avoids conflict between Docker HEALTHCHECK and OCI health check
# Run as non-root user
USER tmi:tmi
# Run the application with wallet extraction
ENTRYPOINT ["/entrypoint.sh"]