# syntax = docker/dockerfile:1 FROM node:slim as build RUN apt-get update && \ apt-get install -y gnupg2 curl procps xz-utils git && \ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y &&\ export PATH=/root/.cargo/bin:$PATH &&\ gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB &&\ curl -sSL https://get.rvm.io | bash -s stable && \ bash -c 'source /etc/profile.d/rvm.sh && rvm install 3.2.0' ENV PATH=/usr/local/rvm/wrappers/default:$PATH RUN gem install rails RUN rails new demo --skip-active-record --javascript esbuild WORKDIR demo RUN yarn add react react-dom FROM node:slim WORKDIR demo COPY --from=build /demo /demo COPY --from=build /usr/local/rvm /usr/local/rvm COPY --from=build /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu ENV PATH=/usr/local/rvm/wrappers/default:$PATH RUN bin/rails generate controller Time index RUN cat <<-"EOF" >> app/javascript/application.js import "./components/counter" EOF RUN mkdir app/javascript/components COPY <<-"EOF" app/javascript/components/counter.jsx import React, { useState, useEffect, useRef } from 'react'; import { createRoot } from 'react-dom/client'; const Counter = ({ arg }) => { const [count, setCount] = useState(0); const countRef = useRef(count); countRef.current = count; useEffect(() => { const interval = setInterval(() => { setCount(countRef.current + 1); }, 1000); return () => clearInterval(interval); }, []); return
{`${arg} - counter = ${count}!`}
; }; document.addEventListener("DOMContentLoaded", () => { const container = document.getElementById("root"); const root = createRoot(container); root.render(); }); EOF COPY <<-"EOF" app/views/time/index.html.erb
React Logo
ruby=<%= RUBY_VERSION %> rails=<%= Rails::VERSION::STRING %>>
EOF COPY <<-"EOF" config/routes.rb Rails.application.routes.draw { root "time#index" } EOF ENV RAILS_ENV=production RUN bin/rails assets:precompile EXPOSE 3000 CMD bin/rails server