Skip to content

Commit

Permalink
feat: custom cache handler
Browse files Browse the repository at this point in the history
  • Loading branch information
riipandi committed Sep 27, 2024
1 parent 01eb522 commit 8c87b1c
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 71 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
APP_BASE_URL=http://localhost:3000
ALLOW_SEARCH_ENGINE_INDEXING=false
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ COPY --chown=node:node . .

RUN apt update && apt -yqq install tini jq
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install \
--ignore-scripts && pnpm add sharp && pnpm build
--ignore-scripts && pnpm add sharp && pnpm build --verbose

# -----------------------------------------------------------------------------
# Compile the application and install production only dependencies.
Expand All @@ -38,12 +38,10 @@ FROM base AS pruner
# Required generated files
COPY --from=builder /srv/.next/standalone /srv/.next/standalone
COPY --from=builder /srv/.next/static /srv/.next/standalone/.next/static
COPY --from=builder /srv/public /srv/.next/standalone/public

# Required metadata files
COPY --from=builder /srv/package.json /srv/package.json
COPY --from=builder /srv/pnpm-lock.yaml /srv/pnpm-lock.yaml
COPY --from=builder /srv/next.config.mjs /srv/next.config.mjs
COPY --from=builder /srv/.npmrc /srv/.npmrc

# Install production dependencies and cleanup node_modules.
Expand All @@ -68,8 +66,10 @@ ENV APP_BASE_URL=$APP_BASE_URL
# Copy the build output files from the pruner stage.
# Automatically leverage output traces to reduce image size
# @ref: https://nextjs.org/docs/app/api-reference/next-config-js/output
COPY --from=pruner --chown=nonroot:nonroot /srv/.next/standalone /srv
COPY --from=pruner --chown=nonroot:nonroot /srv/next.config.mjs /srv/next.config.mjs
COPY --from=pruner /srv/.next/standalone /srv
COPY --from=builder /srv/public /srv/public
COPY --from=builder /srv/next.config.mjs /srv/next.config.mjs
COPY --from=builder /srv/scripts/cache-handler.mjs /srv/scripts/cache-handler.mjs

# Copy some utilities from builder image.
COPY --from=builder /usr/bin/tini /usr/bin/tini
Expand Down
32 changes: 24 additions & 8 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import NextBundleAnalyzer from '@next/bundle-analyzer'
import { fileURLToPath } from 'node:url'
import { dirname, resolve } from 'node:path'

// Avoid build and lint error in Docker or Vercel deployment
const isProduction =
process.env.NODE_ENV === 'production' ||
process.env.IS_VERCEL_ENV === 'true' ||
process.env.FLY_MACHINE_ID
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const isFly = process.env.FLY_MACHINE_ID
const isVercel = process.env.IS_VERCEL_ENV === 'true'
const isProduction = process.env.NODE_ENV === 'production' || isVercel || isFly

const withBundleAnalyzer = NextBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
Expand All @@ -14,16 +17,29 @@ const withBundleAnalyzer = NextBundleAnalyzer({
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
cleanDistDir: true,
reactStrictMode: true,
poweredByHeader: false,
cleanDistDir: true,
productionBrowserSourceMaps: false,
images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] },

// @ref: https://nextjs.org/blog/next-14-1#improved-self-hosting
// cacheHandler: require.resolve('./cache-handler.js'),
// cacheMaxMemorySize: 0, // disable default in-memory caching
cacheMaxMemorySize: 0, // disable default in-memory caching
cacheHandler:
process.env.NODE_ENV === 'production' && !isVercel
? resolve(__dirname, 'scripts/cache-handler.mjs')
: undefined,

eslint: { ignoreDuringBuilds: isProduction },
typescript: { ignoreBuildErrors: isProduction },
logging: { fetches: { fullUrl: true } },

experimental: {
// This is required for the experimental feature of
// pre-populating the cache with the initial data.
instrumentationHook: true,
},

rewrites() {
return [{ source: '/healthz', destination: '/api/healthz' }]
},
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-start",
"version": "14.0.0",
"version": "14.1.0",
"license": "MIT",
"private": true,
"scripts": {
Expand All @@ -24,6 +24,7 @@
"pre-dev": "docker compose up -d --remove-orphans"
},
"dependencies": {
"@neshca/cache-handler": "^1.7.3",
"@next/bundle-analyzer": "^14.2.13",
"@t3-oss/env-core": "^0.11.1",
"lucide-react": "^0.446.0",
Expand Down
100 changes: 100 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 0 additions & 51 deletions public/site.webmanifest

This file was deleted.

13 changes: 13 additions & 0 deletions scripts/cache-handler.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { CacheHandler } from '@neshca/cache-handler'
import createLocalHandler from '@neshca/cache-handler/local-lru'

CacheHandler.onCreation(async () => {
const localHandler = createLocalHandler({
maxItemsNumber: 10000,
maxItemSizeBytes: 1024 * 1024 * 500,
})

return { handlers: [localHandler] }
})

export default CacheHandler
8 changes: 5 additions & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ export const metadata: Metadata = {
applicationName: 'Next Start',
description: 'A starter project for Next.js with Tailwind CSS and Typescript.',
keywords: ['nextjs', 'react', 'starter', 'boilerplate'],
robots: { index: true, follow: true },
manifest: '/site.webmanifest',
robots: {
index: ENV.ALLOW_SEARCH_ENGINE_INDEXING,
follow: ENV.ALLOW_SEARCH_ENGINE_INDEXING,
},
manifest: '/manifest.webmanifest',
icons: [
{ rel: 'icon', type: 'image/x-icon', url: '/favicon.ico' },
{ rel: 'icon', type: 'image/svg+xml', url: '/favicon.svg' },
{ rel: 'icon', type: 'image/png', url: '/favicon.png' },
{ rel: 'apple-touch-icon', url: '/favicon.png' },
],
metadataBase: new URL(ENV.APP_BASE_URL),
Expand Down
Loading

0 comments on commit 8c87b1c

Please sign in to comment.