diff --git a/config/docker/Dockerfile.danbooru b/config/docker/Dockerfile.danbooru index b4506bdc8..ecb71bfeb 100644 --- a/config/docker/Dockerfile.danbooru +++ b/config/docker/Dockerfile.danbooru @@ -1,62 +1,70 @@ -FROM ubuntu:20.10 AS build +ARG RUBY_VERSION=2.7.1 +ARG NODE_VERSION=14.15.5 +ARG VIPS_VERSION=8.10.6 +ARG FFMPEG_VERSION=4.3.2 + + + +FROM ubuntu:20.10 AS base + +WORKDIR /danbooru +ENV PATH="/root/.asdf/bin:/root/.asdf/shims:$PATH" + +COPY config/docker/build-base-image.sh . + +RUN \ + ./build-base-image.sh && \ + chmod go+rx /root && \ + useradd --home-dir /root --user-group danbooru && \ + rm build-base-image.sh + + + +FROM base AS development +ARG NODE_VERSION RUN \ apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ - build-essential \ - ruby \ - ruby-dev \ - ruby-bundler \ - git \ - nodejs \ - yarnpkg \ - webpack \ - libvips-dev \ - libxml2-dev \ - libxslt-dev \ - zlib1g-dev \ - postgresql-server-dev-all && \ - # webpacker expects the binary to be called `yarn`, but debian/ubuntu installs it as `yarnpkg`. - ln -sf /usr/bin/yarnpkg /usr/bin/yarn + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential libpq-dev libvips-dev libxml2-dev libxslt-dev zlib1g-dev \ + curl ca-certificates dirmngr git gpg && \ + rm -rf /var/lib/apt/lists/* -WORKDIR /build - -COPY .bundle .bundle -COPY Gemfile Gemfile.lock ./ RUN \ - bundle config set deployment true --local && \ - bundle config set path vendor/bundle && \ - bundle install --jobs 4 + asdf plugin add nodejs && \ + asdf install nodejs "$NODE_VERSION" && \ + asdf global nodejs "$NODE_VERSION" && \ + npm install --unsafe-perm=true -g yarn -COPY package.json yarn.lock ./ +COPY .bundle Gemfile Gemfile.lock ./ +RUN \ + bundle install --jobs "$(nproc)" && \ + rm -rf "$(gem environment gemdir)/cache" && \ + find "$(gem environment gemdir)" -name "*.o" -delete + +COPY .yarn package.json yarn.lock ./ RUN yarn install COPY . . -RUN bundle config set path vendor/bundle --local -ARG RAILS_ENV=production -RUN bin/rails assets:precompile && ln -sf packs public/packs-test -RUN rm -rf node_modules log tmp .yarn/cache && mkdir log tmp -FROM ubuntu:20.10 + +FROM development AS assets RUN \ - useradd --create-home --user-group danbooru && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ - ruby \ - ffmpeg \ - mkvtoolnix \ - libvips \ - libxml2 \ - libxslt1.1 \ - zlib1g \ - postgresql-client + bin/rails assets:precompile && \ + rm -rf \ + node_modules .yarn/cache tmp /usr/local/share/.cache/yarn \ + /root/.yarn/berry/cache /root/.bundle/cache /root/.npm && \ + asdf uninstall nodejs && \ + ln -s /tmp tmp + + + +FROM base as production + +COPY --from=development /root /root +COPY --from=assets /danbooru /danbooru USER danbooru -WORKDIR /home/danbooru/app -COPY --from=build --chown=danbooru /build . - -VOLUME ["/home/danbooru/app/public/data"] -ENTRYPOINT ["./bin/rails"] -CMD ["server"] +CMD ["bin/rails", "server"] diff --git a/config/docker/build-base-image.sh b/config/docker/build-base-image.sh new file mode 100755 index 000000000..c5a063009 --- /dev/null +++ b/config/docker/build-base-image.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +set -xeuo pipefail + +RUBY_VERSION="${RUBY_VERSION:-2.7.1}" +VIPS_VERSION="${VIPS_VERSION:-8.10.6}" +FFMPEG_VERSION="${FFMPEG_VERSION:-4.3.2}" + +COMMON_BUILD_DEPS=" + curl ca-certificates build-essential pkg-config git +" +RUBY_BUILD_DEPS="libssl-dev zlib1g-dev" +FFMPEG_BUILD_DEPS="libvpx-dev nasm" +VIPS_BUILD_DEPS=" + libfftw3-dev libwebp-dev liborc-dev liblcms2-dev libpng-dev + libjpeg-turbo8-dev libexpat1-dev libglib2.0-dev libgif-dev libexif-dev +" +DANBOORU_RUNTIME_DEPS=" + mkvtoolnix postgresql-client-12 libpq5 libxml2 libxslt1.1 zlib1g + libfftw3-3 libwebp6 libwebpmux3 libwebpdemux2 liborc-0.4.0 liblcms2-2 + libpng16-16 libjpeg-turbo8 libexpat1 libglib2.0 libgif7 libexif12 + libvpx6 +" + +apt_install() { + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@" +} + +install_asdf() { + git clone https://github.com/asdf-vm/asdf.git ~/.asdf +} + +install_vips() { + apt_install $VIPS_BUILD_DEPS + + VIPS_URL="https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.gz" + curl -L "$VIPS_URL" | tar -C /usr/local/src -xzvf - + cd /usr/local/src/vips-${VIPS_VERSION} + + ./configure --disable-static + CFLAGS="-O2" make -j "$(nproc)" + make install + ldconfig + + vips --version +} + +install_ffmpeg() { + apt_install $FFMPEG_BUILD_DEPS + + FFMPEG_URL="https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n${FFMPEG_VERSION}.tar.gz" + curl -L "$FFMPEG_URL" | tar -C /usr/local/src -xzvf - + cd /usr/local/src/FFmpeg-n${FFMPEG_VERSION} + + ./configure --disable-ffplay --disable-network --disable-doc --enable-libvpx + make -j "$(nproc)" + cp ffmpeg ffprobe /usr/local/bin + + ffmpeg -version + ffprobe -version +} + +install_ruby() { + apt_install $RUBY_BUILD_DEPS + + asdf plugin add ruby + RUBY_BUILD_OPTS="--verbose" RUBY_CONFIGURE_OPTS="--disable-install-doc" asdf install ruby "$RUBY_VERSION" + asdf global ruby "$RUBY_VERSION" + + ruby --version +} + +cleanup() { + apt-get purge -y $COMMON_BUILD_DEPS $RUBY_BUILD_DEPS $VIPS_BUILD_DEPS $FFMPEG_BUILD_DEPS + apt-get purge -y --allow-remove-essential \ + e2fsprogs git libglib2.0-bin libglib2.0-doc mount perl-modules-5.30 procps \ + python3 readline-common shared-mime-info tzdata + apt-get autoremove -y + + rm -rf \ + /var/lib/apt/lists/* \ + /var/log/* \ + /usr/local/share/gtk-doc \ + /usr/local/src \ + /usr/share/doc/* \ + /usr/share/info/* \ + /usr/share/gtk-doc + + cd / +} + +apt-get update +apt_install $COMMON_BUILD_DEPS $DANBOORU_RUNTIME_DEPS +install_asdf +install_ffmpeg +install_vips +install_ruby +cleanup diff --git a/config/docker/docker-compose.simple.yaml b/config/docker/docker-compose.simple.yaml index 495526bca..44ff2170d 100644 --- a/config/docker/docker-compose.simple.yaml +++ b/config/docker/docker-compose.simple.yaml @@ -16,14 +16,15 @@ services: ports: - "80:3000" environment: - - RAILS_ENV=development + - RAILS_ENV=production + - RAILS_SERVE_STATIC_FILES=true - DATABASE_URL=postgresql://danbooru@postgres/danbooru - DANBOORU_CANONICAL_URL=http://localhost volumes: - - "danbooru-images:/home/danbooru/app/public/data" + - "danbooru-images:/danbooru/public/data" depends_on: - postgres - entrypoint: ["bash", "-c", "bin/rails db:setup 2> /dev/null; bin/rails server -b 0.0.0.0"] + command: ["bash", "-c", "bin/rails db:setup; bin/rails server -b 0.0.0.0"] user: root postgres: