167 lines
8.4 KiB
Docker
167 lines
8.4 KiB
Docker
# Explore container for flaredown — rubyforgood chronic-illness symptom tracker.
|
|
# github.com/rubyforgood/Flaredown (GPL-3), pinned upstream at 5f859e8d. Polyglot, multi-service:
|
|
# - backend/ Rails 7.1 API, Ruby 3.2.3. Mongoid 8.1 on MongoDB (primary store) + Postgres
|
|
# (small relational slice) + Redis + Sidekiq.
|
|
# - frontend/ Ember.js client, Node 14.21.3 (npm 7).
|
|
# Adapted for live-mount: the source repo is bind-mounted at /workspace/repo; deps + DB set up
|
|
# by post-create.sh, and the three datastores are started by post-start.sh.
|
|
#
|
|
# Deliberate version choice: docker-compose pins MongoDB 4.4.9, which is EOL and ships no
|
|
# arm64 / Debian-bookworm packages. Mongoid 8.1.3 + the mongo ruby driver 2.20.1 support
|
|
# servers up to 7.0, so we run MongoDB 7.0 (native amd64 + aarch64, no emulation) instead of
|
|
# fighting a dead 4.4 build. Same wire protocol; the app is version-agnostic here.
|
|
FROM ruby:3.2.3
|
|
|
|
# System deps: Postgres + libpq (the pg gem), Redis (Sidekiq), plus build tooling. python3
|
|
# (bookworm ships 3.11 ≥ 3.10, which the reduced-toolset str_replace_editor needs). xz/curl/
|
|
# gnupg for the Node + Mongo downloads. libyaml for psych.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
postgresql postgresql-client libpq-dev \
|
|
redis-server \
|
|
build-essential pkg-config libyaml-dev \
|
|
python3 \
|
|
git sudo curl ca-certificates gnupg xz-utils procps \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# MongoDB 7.0 server binary (mongod) from the official tarball, arch-aware. The ubuntu2204
|
|
# build (glibc 2.35) runs fine on bookworm (glibc 2.36). Only mongod is needed — Mongoid
|
|
# connects over the wire; no mongosh required (post-start probes the port directly).
|
|
RUN set -eux; \
|
|
arch="$(dpkg --print-architecture)"; \
|
|
case "$arch" in \
|
|
amd64) marm=x86_64;; \
|
|
arm64) marm=aarch64;; \
|
|
*) echo "unsupported arch: $arch" >&2; exit 1;; \
|
|
esac; \
|
|
ver=7.0.14; \
|
|
curl -fsSL "https://fastdl.mongodb.org/linux/mongodb-linux-${marm}-ubuntu2204-${ver}.tgz" -o /tmp/mongo.tgz; \
|
|
tar -xzf /tmp/mongo.tgz -C /tmp; \
|
|
cp /tmp/mongodb-linux-${marm}-ubuntu2204-${ver}/bin/mongod /usr/local/bin/; \
|
|
rm -rf /tmp/mongo.tgz /tmp/mongodb-linux-*; \
|
|
mongod --version | head -1
|
|
|
|
# Node via nvm: 18 (default — toolkit tooling: create-snapshot hooks, `node -e` reads of
|
|
# toolkit.json) + 14 (the Ember app; frontend/.nvmrc = v14.21.3). Symlink v18 to /usr/local/bin
|
|
# so the toolkit's own node always resolves; run-app switches PATH to v14 for the client.
|
|
# The frontend's .npmrc sets engine-strict=true and its package.json requires npm 6.x, so pin
|
|
# npm 6 in the v14 line (nvm's 14.21.3 otherwise bundles npm 7, which fails engine-strict). The
|
|
# v18.* glob (not `nvm version`) avoids sourcing nvm.sh under Docker's /bin/sh (dash), bash-only.
|
|
ENV NVM_DIR=/usr/local/nvm
|
|
RUN mkdir -p "$NVM_DIR" \
|
|
&& curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \
|
|
&& bash -c '. "$NVM_DIR/nvm.sh" \
|
|
&& nvm install 18 \
|
|
&& nvm install 14.21.3 && nvm use 14.21.3 && npm install -g npm@6.14.18 \
|
|
&& nvm alias default 18' \
|
|
&& for b in node npm npx; do ln -sf "$NVM_DIR"/versions/node/v18.*/bin/"$b" /usr/local/bin/"$b"; done \
|
|
&& node --version
|
|
|
|
# phantomjs stub. The Ember client depends on phantomjs-prebuilt@2.1.16, which has NO arm64
|
|
# binary and is EOL everywhere — its install script aborts `npm install` on Apple-Silicon
|
|
# hosts. A stub on PATH that reports the expected version makes the install script treat
|
|
# PhantomJS as "already installed" and skip the (impossible) download, so `npm install`
|
|
# completes and `ember build`/`ember serve` (what run-app uses) work. `ember test` runs on
|
|
# headless Chrome at this pin, wired up after the Playwright block below.
|
|
RUN printf '#!/bin/bash\n[ "$1" = "--version" ] && { echo "2.1.1"; exit 0; }\nexit 0\n' > /usr/local/bin/phantomjs \
|
|
&& chmod +x /usr/local/bin/phantomjs
|
|
|
|
# Match backend/Gemfile.lock "BUNDLED WITH 2.5.6".
|
|
RUN gem install bundler -v 2.5.6
|
|
|
|
# Postgres trust auth: backend/config/database.yml connects as PG_DATABASE_USERNAME (default
|
|
# postgres). OVERWRITE pg_hba.conf (Debian's default `local all all peer` is first-match, so
|
|
# an appended trust rule never applies).
|
|
RUN PG_VERSION=$(ls /etc/postgresql) \
|
|
&& printf 'local all all trust\nhost all all 127.0.0.1/32 trust\nhost all all ::1/128 trust\nhost all all 0.0.0.0/0 trust\n' > "/etc/postgresql/${PG_VERSION}/main/pg_hba.conf" \
|
|
&& echo "listen_addresses='*'" >> "/etc/postgresql/${PG_VERSION}/main/postgresql.conf"
|
|
|
|
USER root
|
|
|
|
# --- Playwright + Chromium, for driving the app in a real browser -------------
|
|
# Self-contained under /opt — the member's own runtime is untouched.
|
|
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright
|
|
RUN apt-get update -qq \
|
|
&& apt-get install -y -qq --no-install-recommends \
|
|
xz-utils \
|
|
libxcomposite1 \
|
|
libxdamage1 \
|
|
libxfixes3 \
|
|
libxrandr2 \
|
|
libasound2 \
|
|
libatk1.0-0 \
|
|
libatk-bridge2.0-0 \
|
|
libatspi2.0-0 \
|
|
libcups2 \
|
|
libdbus-1-3 \
|
|
libgbm1 \
|
|
libnspr4 \
|
|
libnss3 \
|
|
libxkbcommon0 \
|
|
libpango-1.0-0 \
|
|
libcairo2 \
|
|
libxshmfence1 \
|
|
libx11-xcb1 \
|
|
libxcb-dri3-0 \
|
|
libdrm2 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
RUN set -eux; \
|
|
arch="$(dpkg --print-architecture)"; \
|
|
case "$arch" in amd64) nodearch=x64;; arm64) nodearch=arm64;; *) echo "unsupported arch: $arch" >&2; exit 1;; esac; \
|
|
curl -fsSL "https://nodejs.org/dist/v20.19.5/node-v20.19.5-linux-${nodearch}.tar.xz" -o /tmp/pw-node.tar.xz; \
|
|
mkdir -p /opt/pw-node; \
|
|
tar -xJf /tmp/pw-node.tar.xz -C /opt/pw-node --strip-components=1; \
|
|
rm /tmp/pw-node.tar.xz; \
|
|
export npm_config_prefix=/opt/pw-node PATH="/opt/pw-node/bin:$PATH"; \
|
|
/opt/pw-node/bin/npm install -g playwright@1.56.0; \
|
|
test -d /opt/pw-node/lib/node_modules/playwright; \
|
|
/opt/pw-node/bin/node /opt/pw-node/lib/node_modules/playwright/cli.js install chromium
|
|
|
|
# `pw <script.js>` runs Node with `require("playwright")` resolvable (CommonJS).
|
|
RUN printf '#!/bin/sh\nNODE_PATH=/opt/pw-node/lib/node_modules exec /opt/pw-node/bin/node "$@"\n' > /usr/local/bin/pw \
|
|
&& chmod +x /usr/local/bin/pw
|
|
|
|
# Fail the build if Chromium cannot start.
|
|
RUN printf 'const{chromium}=require("playwright");(async()=>{const b=await chromium.launch();const p=await b.newPage();await p.setContent("<h1 id=t>ok</h1>");if(await p.textContent("#t")!=="ok")throw new Error("bad render");await b.close();console.log("chromium OK");})()\n' > /tmp/pw-check.js \
|
|
&& pw /tmp/pw-check.js \
|
|
&& rm -f /tmp/pw-check.js
|
|
# `ember test` resolves its browser via CHROME_BIN, falling back to `google-chrome` on PATH
|
|
# (frontend/testem.js). Point both at the Chromium Playwright just installed. The glob is
|
|
# resolved at build time so a Playwright bump can't strand a hardcoded chromium-<build> path.
|
|
RUN set -eux; \
|
|
chrome="$(echo /opt/ms-playwright/chromium-*/chrome-linux/chrome)"; \
|
|
test -x "$chrome"; \
|
|
printf '#!/bin/bash\nexec %s --no-sandbox --disable-dev-shm-usage "$@"\n' "$chrome" \
|
|
> /usr/local/bin/google-chrome; \
|
|
chmod +x /usr/local/bin/google-chrome; \
|
|
google-chrome --version
|
|
ENV CHROME_BIN=/usr/local/bin/google-chrome
|
|
|
|
ENV IS_SANDBOX=1
|
|
RUN mkdir -p /root/.claude && \
|
|
echo '{"permissions":{"deny":["WebFetch","WebSearch"]}}' > /root/.claude/settings.json
|
|
|
|
# Startup for a direct `docker run` (the devcontainer path uses post-start.sh instead, which
|
|
# starts the same services). Bring up Postgres + Redis + MongoDB, then hand off.
|
|
RUN cat > /usr/local/bin/start-services.sh <<'EOF'
|
|
#!/bin/bash
|
|
set -e
|
|
service postgresql start || true
|
|
service redis-server start >/dev/null 2>&1 || redis-server --daemonize yes >/dev/null 2>&1 || true
|
|
mkdir -p /data/db
|
|
mongod --dbpath /data/db --bind_ip 127.0.0.1 --fork --logpath /tmp/mongod.log >/dev/null 2>&1 || true
|
|
until pg_isready -h localhost -p 5432 -U postgres >/dev/null 2>&1; do sleep 0.5; done
|
|
exec "$@"
|
|
EOF
|
|
RUN chmod +x /usr/local/bin/start-services.sh
|
|
|
|
WORKDIR /workspace/repo
|
|
# Resolver for the DNS jail (.devcontainer/dns-jail-container.sh, applied by
|
|
# post-start.sh); if this does not land, Explore just runs unjailed.
|
|
RUN (command -v apk >/dev/null 2>&1 && apk add --no-cache dnsmasq bind-tools) \
|
|
|| (apt-get update && apt-get install -y --no-install-recommends dnsmasq-base dnsutils \
|
|
&& rm -rf /var/lib/apt/lists/*) \
|
|
|| true
|
|
|
|
ENTRYPOINT ["/usr/local/bin/start-services.sh"]
|
|
CMD ["sleep", "infinity"]
|