Skip to content

Commit 0bce23f

Browse files
palashcPalash Chauhan
andauthored
PHOENIX-7868 : Docker setup for phoenix-adapters (#6)
Co-authored-by: Palash Chauhan <p.chauhan@pchauha-ltmgv47.internal.salesforce.com>
1 parent 9a7b377 commit 0bce23f

12 files changed

Lines changed: 1304 additions & 0 deletions

.dockerignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
**/target/
2+
**/logs/
3+
**/*.log
4+
**/*.log.*
5+
**/dynamodb-local-metadata.json
6+
**/heap-dumps/
7+
8+
**/*.tar.gz
9+
**/*.tar.bz2
10+
**/*.zip
11+
12+
.idea/
13+
.vscode/
14+
.cursor/
15+
.DS_Store
16+
17+
.git/
18+
.gitignore
19+
20+
docker/README.md

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,41 @@ The Phoenix DynamoDB REST service is fully compatible with AWS SDKs. You can con
6767
port 8842 with zk-quorum localhost:2181.
6868
Alternative to `-z <zk-quorum>` is env variable `ZOO_KEEPER_QUORUM`.
6969

70+
#### One-shot Docker setup (recommended for first-time users)
71+
72+
Skip steps 1-2 above with the bundled Docker cluster. From a fresh clone:
73+
74+
**Prerequisites:** Docker Desktop running; `jq` and `curl` on `PATH`
75+
(`brew install jq` on macOS).
76+
77+
```bash
78+
# 1. Bring up the full stack at the versions pinned in pom.xml and BLOCK
79+
# until every container reports healthy (REST is ~30-60s on cold start).
80+
# First time: ~8-12 min total -- most of that is Maven downloading
81+
# ~1.5 GB of dependencies into the BuildKit cache mount. Subsequent
82+
# runs reuse the cache and rebuild in seconds.
83+
docker compose -f docker/docker-compose.yml up -d --build --wait
84+
85+
# 2. Validate it works end-to-end (CRUD + UpdateItem + BatchWriteItem + streams).
86+
bash docker/scripts/smoke.sh
87+
# -> "Result: 21 checks PASSED across 18 API calls"
88+
89+
# 3. Use it. The DynamoDB-compatible endpoint is at http://localhost:8842 .
90+
# Point any AWS SDK at it (Java/Python/Node.js snippets in
91+
# phoenix-ddb-rest/README.md), or hit it with curl:
92+
curl -s -X POST http://localhost:8842/ \
93+
-H 'Content-Type: application/x-amz-json-1.0' \
94+
-H 'X-Amz-Target: DynamoDB_20120810.ListTables' -d '{}'
95+
96+
# 4. Tear down when you're done.
97+
docker compose -f docker/docker-compose.yml down -v
98+
```
99+
100+
See [`docker/README.md`](docker/README.md) for the full reference: port
101+
mappings, the developer inner loop for code changes, the smoke-test
102+
breakdown, troubleshooting, and how to run the REST server outside
103+
Docker against the dockerized cluster.
104+
70105
### Building Distribution Tarball
71106

72107
To build a distribution tarball that includes all components:

docker/Dockerfile.hbase-phoenix

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# syntax=docker/dockerfile:1
2+
FROM eclipse-temurin:8-jdk-jammy
3+
4+
ARG HBASE_VERSION=2.5.14
5+
ARG HBASE_FLAVOR=hadoop3
6+
ARG PHOENIX_HBASE_LINE=2.5
7+
ARG PHOENIX_VERSION=5.3.1
8+
9+
ENV HBASE_VERSION=${HBASE_VERSION} \
10+
HBASE_FLAVOR=${HBASE_FLAVOR} \
11+
PHOENIX_HBASE_LINE=${PHOENIX_HBASE_LINE} \
12+
PHOENIX_VERSION=${PHOENIX_VERSION} \
13+
JAVA_HOME=/opt/java/openjdk \
14+
HBASE_HOME=/opt/hbase \
15+
HBASE_CONF_DIR=/opt/hbase/conf \
16+
PHOENIX_HOME=/opt/phoenix \
17+
HBASE_MANAGES_ZK=false \
18+
PATH=/opt/hbase/bin:/opt/phoenix/bin:/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
19+
20+
RUN set -eux; \
21+
apt-get update; \
22+
apt-get install -y --no-install-recommends \
23+
bash curl ca-certificates netcat-openbsd procps tini less; \
24+
rm -rf /var/lib/apt/lists/*
25+
26+
RUN set -eux; \
27+
mkdir -p "${HBASE_HOME}"; \
28+
curl -fSL --retry 5 --retry-delay 5 \
29+
"https://archive.apache.org/dist/hbase/${HBASE_VERSION}/hbase-${HBASE_VERSION}-${HBASE_FLAVOR}-bin.tar.gz" \
30+
-o /tmp/hbase.tar.gz; \
31+
tar -xzf /tmp/hbase.tar.gz -C "${HBASE_HOME}" --strip-components=1; \
32+
rm /tmp/hbase.tar.gz; \
33+
mkdir -p /var/log/hbase /var/run/hbase
34+
35+
# phoenix-server JAR is copied into HBase's lib so the coprocessors and
36+
# the IndexedWALEditCodec are visible to both the master and every RS.
37+
RUN set -eux; \
38+
mkdir -p "${PHOENIX_HOME}"; \
39+
curl -fSL --retry 5 --retry-delay 5 \
40+
"https://archive.apache.org/dist/phoenix/phoenix-${PHOENIX_VERSION}/phoenix-hbase-${PHOENIX_HBASE_LINE}-${PHOENIX_VERSION}-bin.tar.gz" \
41+
-o /tmp/phoenix.tar.gz; \
42+
tar -xzf /tmp/phoenix.tar.gz -C "${PHOENIX_HOME}" --strip-components=1; \
43+
rm /tmp/phoenix.tar.gz; \
44+
cp "${PHOENIX_HOME}/phoenix-server-hbase-${PHOENIX_HBASE_LINE}-${PHOENIX_VERSION}.jar" "${HBASE_HOME}/lib/"
45+
46+
# Kept below the tarball downloads to preserve their (multi-hundred-MB) cache.
47+
# python3 is required by /opt/phoenix/bin/sqlline.py.
48+
RUN set -eux; \
49+
apt-get update; \
50+
apt-get install -y --no-install-recommends python3; \
51+
rm -rf /var/lib/apt/lists/*; \
52+
ln -sf /usr/bin/python3 /usr/local/bin/python
53+
54+
COPY conf/hbase/hbase-site.xml ${HBASE_HOME}/conf/hbase-site.xml
55+
COPY conf/hbase/hbase-env.sh ${HBASE_HOME}/conf/hbase-env.sh
56+
57+
COPY scripts/hbase-entrypoint.sh /usr/local/bin/entrypoint.sh
58+
RUN chmod +x /usr/local/bin/entrypoint.sh
59+
60+
WORKDIR /opt
61+
62+
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"]
63+
CMD ["help"]

docker/Dockerfile.phoenix-adapters

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# syntax=docker/dockerfile:1
2+
#
3+
# Build context: project root (the Maven reactor needs every module).
4+
#
5+
FROM maven:3.9-eclipse-temurin-8 AS builder
6+
7+
WORKDIR /workspace
8+
9+
# Copy poms first to maximise dep-layer cache hits on rebuild.
10+
COPY pom.xml ./
11+
COPY phoenix-ddb-utils/pom.xml phoenix-ddb-utils/pom.xml
12+
COPY phoenix-ddb-rest/pom.xml phoenix-ddb-rest/pom.xml
13+
COPY phoenix-ddb-assembly/pom.xml phoenix-ddb-assembly/pom.xml
14+
COPY coverage-report/pom.xml coverage-report/pom.xml
15+
16+
# `|| true` because the cross-module reactor can't resolve siblings yet;
17+
# this step is only here to warm ~/.m2.
18+
RUN --mount=type=cache,target=/root/.m2 \
19+
mvn -B -q -DskipTests \
20+
-pl phoenix-ddb-utils,phoenix-ddb-rest,phoenix-ddb-assembly -am \
21+
dependency:go-offline || true
22+
23+
COPY phoenix-ddb-utils phoenix-ddb-utils
24+
COPY phoenix-ddb-rest phoenix-ddb-rest
25+
COPY phoenix-ddb-assembly phoenix-ddb-assembly
26+
COPY coverage-report coverage-report
27+
COPY bin bin
28+
COPY conf conf
29+
COPY README.md DDB_API_REFERENCE.md ./
30+
31+
RUN --mount=type=cache,target=/root/.m2 \
32+
mvn -B -DskipTests \
33+
-pl phoenix-ddb-assembly -am \
34+
clean package
35+
36+
RUN set -eux; \
37+
# If the assembly module ever ships an additional *-bin.tar.gz (e.g.
38+
# with a classifier), fail loudly rather than silently picking one.
39+
count=$(find phoenix-ddb-assembly/target -maxdepth 1 -type f -name 'phoenix-adapters-*-bin.tar.gz' | wc -l); \
40+
if [ "$count" -ne 1 ]; then \
41+
echo "Expected exactly one phoenix-adapters-*-bin.tar.gz, found $count:" >&2; \
42+
find phoenix-ddb-assembly/target -maxdepth 1 -type f -name 'phoenix-adapters-*-bin.tar.gz' >&2; \
43+
exit 1; \
44+
fi; \
45+
tarball=$(find phoenix-ddb-assembly/target -maxdepth 1 -type f -name 'phoenix-adapters-*-bin.tar.gz'); \
46+
cp "$tarball" /tmp/phoenix-adapters-bin.tar.gz
47+
48+
FROM eclipse-temurin:8-jdk-jammy
49+
50+
ENV JAVA_HOME=/opt/java/openjdk \
51+
PHOENIX_ADAPTERS_HOME=/opt/phoenix-adapters \
52+
PHOENIX_ADAPTERS_CONF_DIR=/opt/phoenix-adapters/conf \
53+
PHOENIX_ADAPTERS_LOG_DIR=/var/log/phoenix-adapters \
54+
PHOENIX_ADAPTERS_PID_DIR=/var/run/phoenix-adapters \
55+
PHOENIX_REST_PORT=8842 \
56+
ZOO_KEEPER_QUORUM=zookeeper:2181 \
57+
HBASE_MASTER_HOST=hbase-master \
58+
HBASE_MASTER_PORT=16000
59+
60+
RUN set -eux; \
61+
apt-get update; \
62+
apt-get install -y --no-install-recommends \
63+
bash curl ca-certificates netcat-openbsd tini procps; \
64+
rm -rf /var/lib/apt/lists/*; \
65+
mkdir -p "${PHOENIX_ADAPTERS_LOG_DIR}" "${PHOENIX_ADAPTERS_PID_DIR}"
66+
67+
COPY --from=builder /tmp/phoenix-adapters-bin.tar.gz /tmp/phoenix-adapters-bin.tar.gz
68+
69+
RUN set -eux; \
70+
mkdir -p "${PHOENIX_ADAPTERS_HOME}"; \
71+
tar -xzf /tmp/phoenix-adapters-bin.tar.gz -C "${PHOENIX_ADAPTERS_HOME}" --strip-components=1; \
72+
rm /tmp/phoenix-adapters-bin.tar.gz; \
73+
chmod -R +x "${PHOENIX_ADAPTERS_HOME}/bin"; \
74+
# The assembly ships a mix of hadoop-common 3.3.6 (declared in pom.xml)
75+
# and hadoop-hdfs/yarn/mapreduce 3.4.x (transitive from phoenix-core-client
76+
# via hbase-server:2.5.14-hadoop3). The 3.4.x jars register FileSystem
77+
# impls that reference `WithErasureCoding`, a class only present in
78+
# hadoop-common 3.4.x. When HBase returns a remote exception during
79+
# bootstrap, the client's classloader tries to enumerate FileSystem
80+
# impls, hits NoClassDefFoundError, and poisons the JVM. The REST
81+
# server only talks to HBase via RPC and never opens HDFS directly,
82+
# so we strip the 3.4.x hadoop client jars to break the cycle.
83+
rm -f "${PHOENIX_ADAPTERS_HOME}/lib/hadoop-hdfs-"*.jar \
84+
"${PHOENIX_ADAPTERS_HOME}/lib/hadoop-hdfs-client-"*.jar \
85+
"${PHOENIX_ADAPTERS_HOME}/lib/hadoop-yarn-"*.jar \
86+
"${PHOENIX_ADAPTERS_HOME}/lib/hadoop-mapreduce-client-"*.jar \
87+
"${PHOENIX_ADAPTERS_HOME}/lib/hadoop-distcp-"*.jar
88+
89+
# Client-side WAL codec / RPC controller must match the server cluster.
90+
COPY docker/conf/phoenix-adapters/hbase-site.xml ${PHOENIX_ADAPTERS_CONF_DIR}/hbase-site.xml
91+
92+
COPY docker/scripts/phoenix-adapters-entrypoint.sh /usr/local/bin/entrypoint.sh
93+
RUN chmod +x /usr/local/bin/entrypoint.sh
94+
95+
EXPOSE 8842
96+
97+
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"]

0 commit comments

Comments
 (0)