diff --git a/.github/workflows/cloudrun.yml b/.github/workflows/cloudrun.yml index 04befa8..cd0f544 100644 --- a/.github/workflows/cloudrun.yml +++ b/.github/workflows/cloudrun.yml @@ -28,6 +28,6 @@ jobs: - name: Deploy to Cloud Run run: | gcloud run deploy bastienlaw-website \ - --region useast1 \ - --source .\app\ \ + --region us-east1 \ + --source ./app/ \ --allow-unauthenticated diff --git a/app/Dockerfile b/app/Dockerfile index 4edc94b..2b0239c 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -1,10 +1,16 @@ -ARG NODE_VERSION=18 -ARG PNPM_VERSION=9.0.5 +# syntax=docker/dockerfile:1 + +# ENV COREPACK_ENABLE_STRICT=0 + +ARG NODE_VERSION=20.11.0 +ARG PNPM_VERSION=9.7.0 ################################################################################ -# Base stage for shared node/pnpm setup +# Use node image for base image for all stages. FROM node:${NODE_VERSION}-alpine AS base +ENV DOCKER_BUILDKIT=1 + # Associate with GitHub repository LABEL org.opencontainers.image.source=https://github.com/noclocks/bastienlaw-remix @@ -16,67 +22,61 @@ RUN --mount=type=cache,target=/root/.npm \ npm install -g pnpm@${PNPM_VERSION} ################################################################################ -# Dependencies stage - install all dependencies +# Create a stage for installing production dependecies. FROM base AS deps -# Copy package files -COPY package.json pnpm-lock.yaml ./ - -# Install dependencies with a more flexible approach -RUN --mount=type=cache,target=/root/.local/share/pnpm/store \ - pnpm install --prod +# Download dependencies AS a separate step to take advantage of Docker's caching. +# Leverage a cache mount to /root/.local/share/pnpm/store to speed up subsequent builds. +# Leverage bind mounts to package.json and pnpm-lock.yaml to avoid having to copy them +# into this layer. +RUN --mount=type=bind,source=package.json,target=package.json \ + --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ + --mount=type=cache,target=/root/.local/share/pnpm/store \ + pnpm install ################################################################################ -# Builder stage - build the application -FROM base AS builder - -# Copy package files -COPY package.json pnpm-lock.yaml ./ +# Create a stage for building the application. +FROM deps AS build -# Install all dependencies (including dev deps) -RUN --mount=type=cache,target=/root/.local/share/pnpm/store \ - pnpm install +# Download additional development dependencies before building, AS some projects require +# "devDependencies" to be installed to build. If you don't need this, remove this step. +RUN --mount=type=bind,source=package.json,target=package.json \ + --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ + --mount=type=cache,target=/root/.local/share/pnpm/store \ + pnpm install --frozen-lockfile -# Copy source code +# Copy the rest of the source files into the image. COPY . . - -# Build the application +# Run the build script. RUN pnpm run build -# List build output for debugging -RUN echo "Build directory structure:" && \ - find build -type f - ################################################################################ -# Runner stage - final production image -FROM node:${NODE_VERSION}-alpine AS runner +# Create a new stage to run the application with minimal runtime dependencies +# where the necessary files are copied from the build stage. +FROM base AS final -# Use production node environment +# Use production node environment by default. ENV NODE_ENV=production -ENV HOST=0.0.0.0 -ENV PORT=3000 - -WORKDIR /usr/src/app +# ENV NODE_ENV=development -# Install only the packages needed to run the server -COPY package.json pnpm-lock.yaml ./ -RUN npm install --global pnpm@${PNPM_VERSION} && \ - pnpm install --prod +# # Run the application AS a non-root user. +USER node -# Copy server.js and the build directory -COPY server.js ./ -COPY --from=builder /usr/src/app/build ./build -COPY --from=builder /usr/src/app/public ./public +# Copy package.json so that package manager commands can be used. +COPY package.json . -# List directories for debugging -RUN echo "Final build structure:" && \ - find . -type f +# Copy the production dependencies from the deps stage and also +# the built application from the build stage into the image. +COPY --from=deps /usr/src/app/node_modules ./node_modules +COPY --from=build /usr/src/app/build ./build -# Run the application as a non-root user. -USER node +ENV HOST='0.0.0.0' +# ENV PORT=8080 +# ARG PORT=8080 +# ENV PORT=${PORT} # Expose the port that the application listens on. -EXPOSE 3000 +EXPOSE 8080 -# Run the application using the express server -CMD ["node", "server.js"] +# Run the application. +CMD ["pnpm", "run", "serve"] diff --git a/app/app/components/HelpForm.tsx b/app/app/components/HelpForm.tsx index b30a63f..ffca57f 100644 --- a/app/app/components/HelpForm.tsx +++ b/app/app/components/HelpForm.tsx @@ -15,7 +15,9 @@ import 'react-toastify/dist/ReactToastify.min.css'; // return json(data); // }; -const notify = ({type = 'success' || 'error'}) => +const notify = ({type}: { + type: 'success' | 'error'; +}) => toast( type === 'success' ? 'Thank you for contacting us!' diff --git a/app/app/root.tsx b/app/app/root.tsx index a27bf0f..b98cbfb 100644 --- a/app/app/root.tsx +++ b/app/app/root.tsx @@ -63,6 +63,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=