chore: add dockerfile.test + compose for running the spec suite in docker

Existing Dockerfile builds the production image with
BUNDLE_WITHOUT=development:test, so it can't run RSpec. This adds a
test-only image that ships every native lib the app loads at boot
(libvips, libpdfium, onnxruntime, chromium for cuprite) plus the full
dev/test gem bundle.

Usage:
  docker compose -f docker-compose.test.yml up --build
  # or run a subset:
  SPEC_FILES="spec/requests/well_known_spec.rb" \
    docker compose -f docker-compose.test.yml up --build --exit-code-from test

The bundle gems live in a named volume so `docker compose up` re-runs
are fast after the first build. Postgres uses tmpfs — no state
persists between runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pull/633/head
Ortes 2 weeks ago
parent 21d0b6bf3e
commit 6c51ee9929

@ -0,0 +1,70 @@
# syntax=docker/dockerfile:1.7
# Test-only image: runs the full Rails/RSpec suite with every native lib the
# app loads at boot (libvips, libpdfium, onnxruntime, chromium for cuprite).
# Source code is mounted at runtime via docker-compose.test.yml — only the
# Gemfile is baked in so `bundle install` caches between runs.
FROM ruby:4.0.1-alpine AS pdfium
WORKDIR /download
RUN apk --no-cache add wget && \
wget -O pdfium-linux.tgz "https://github.com/bblanchon/pdfium-binaries/releases/latest/download/pdfium-linux-musl-$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/').tgz" && \
mkdir -p /pdfium-linux && \
tar -xzf pdfium-linux.tgz -C /pdfium-linux
FROM ruby:4.0.1-alpine
ENV RAILS_ENV=test \
BUNDLE_WITHOUT="" \
LANG=C.UTF-8 \
TZ=UTC
WORKDIR /app
# System deps:
# - libpq / libpq-dev → pg gem
# - vips + vips-heif → image processing (ruby-vips FFI)
# - onnxruntime → field detection at boot
# - chromium + chromium-chromedriver → capybara/cuprite system specs
# - fontconfig + ttf-* → PDF rendering
# - build-base/git/yaml-dev → native gem compilation
RUN apk add --no-cache \
build-base \
git \
bash \
curl \
yaml-dev \
libpq \
libpq-dev \
vips \
vips-dev \
vips-heif \
redis \
fontconfig \
ttf-dejavu \
onnxruntime \
nodejs \
yarn \
chromium \
chromium-chromedriver \
tzdata
# libpdfium is not in Alpine packages — copy the prebuilt binary.
COPY --from=pdfium /pdfium-linux/lib/libpdfium.so /usr/lib/libpdfium.so
# Bundle deps. Copy only Gemfile/Gemfile.lock so this layer is cached while
# source code changes beneath it.
COPY Gemfile Gemfile.lock ./
RUN bundle config set --local without "" && \
bundle install --jobs 4 --retry 3
# Link onnxruntime.so into the onnxruntime gem's vendor dir (mirrors the
# production Dockerfile) so the gem finds it at runtime.
RUN ln -sf /usr/lib/libonnxruntime.so.1 \
"$(ruby -e "print Dir[Gem::Specification.find_by_name('onnxruntime').gem_dir + '/vendor/*.so'].first")"
# Cuprite launches Chromium directly — point it at the Alpine binary.
ENV CUPRITE_CHROME_PATH=/usr/bin/chromium-browser
CMD ["bundle", "exec", "rspec"]

@ -0,0 +1,38 @@
services:
test:
build:
context: .
dockerfile: Dockerfile.test
depends_on:
postgres:
condition: service_healthy
environment:
RAILS_ENV: test
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/docuseal_test
# Silence bootsnap cache warnings when mounting source read-write.
BOOTSNAP_CACHE_DIR: /tmp/bootsnap
volumes:
- .:/app
- bundle:/usr/local/bundle
command: >
bash -c "
bin/rails db:prepare &&
bundle exec rspec ${SPEC_FILES:-spec}
"
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: docuseal_test
tmpfs:
- /var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 2s
timeout: 3s
retries: 10
volumes:
bundle:
Loading…
Cancel
Save