Home > Net >  Deploying Next.js in Docker container with custom dependencies
Deploying Next.js in Docker container with custom dependencies

Time:10-30

I am new to Next.js and Docker. What I am trying to achieve is to essentially deploy a Next.js project with Docker. I am in the process of creating the Dockerfile and docker-compose.yml files. However, the project has some custom packages that it uses outside of the source folder (on the root level). My build step is failing because it cannot resolve these packages.

ModuleNotFoundError: Module not found: Error: Can't resolve '@custompackage/themes/src/Simply/containers' in '/opt/app/src/pages'

This is what the imports look like

import Theme, { theme } from '@custompackage/themes/src/Simply';
import {
  Navbar,
  Copyright,
  Welcome,
  Services,
  About,
  Pricing,
  Clients,
  Contact,
} from '@custompackage/themes/src/Simply/containers';

import preview from '@custompackage/themes/src/Simply/assets/preview.jpg';

This is my Dockerfile

# Install dependencies only when needed
FROM node:16-alpine AS deps

WORKDIR /opt/app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Rebuild the source code only when needed
# This is where because may be the case that you would try
# to build the app based on some `X_TAG` in my case (Git commit hash)
# but the code hasn't changed.
FROM node:16-alpine AS builder

ENV NODE_ENV=production
WORKDIR /opt/app
COPY . .
COPY --from=deps /opt/app/node_modules ./node_modules
RUN yarn build

# Production image, copy all the files and run next
FROM node:16-alpine AS runner

ARG X_TAG
WORKDIR /opt/app
ENV NODE_ENV=production
COPY --from=builder /opt/app/next.config.js ./
COPY --from=builder /opt/app/public ./public
COPY --from=builder /opt/app/.next ./.next
COPY --from=builder /opt/app/node_modules ./node_modules
CMD ["node_modules/.bin/next", "start"]

Folder structure

enter image description here

I have tried to use the COPY command in the Dockerfile before build step to copy the packages content into the /opt/app folder so that they can be resolved. However, I wasn't exactly sure if I was doing it right and kept getting nowhere.

CodePudding user response:

You could sure find a way to make your app work without changing the directory structure, but I don't think you should.

Module imported import keyword should fall into one of this two category:

  • Application code, located in your source folder
  • Dependencies in usually in a node_modules folder

I you want to have multiple packages into one repository, you should look at the monorepo pattern.

Since you are using yarn, you can take a look at Yarn Workspace which is the solution provided by Yarn to build a monorepo.

You might want to slightly change you directory structure to something like that:

├── app
│   ├── src
│   └── package.json       (next.js)
├── packages
│   ├── custom-package-1
│   │   ├── src
│   │   └── package.json
│   └── custom-package-2
│       ├── src
│       └── package.json
└── package.json            (main)

In the package.json you will add custom-package-1 to your dependencies and your monorepo tool will do some magic to include custom-package-1 in your dependencies (mainly by creating some symlinks).

  • Related