I am developing with Next.js on my Mac OS host using Docker running Ubuntu 18 and bind mounting my development directory to the container. I want to know if there is any way when using SWC Minify in Next.js 12+ to not have to copy over the whole host build context to Docker and then use a yarn install
build step and a persistent volume to run a development environment in Docker because of the missing @next/swc-linux-x64-gnu
binary.
Relevant part of docker-compose.yaml
# Next.js Client and Server
my-nextjs:
container_name: my-nextjs
build:
context: ./www
dockerfile: Dockerfile
volumes:
# bind mounting my development directory to /app in Docker
- ./www:/app/
ports:
- "3911:3000"
I know that because it will be running on Linux and not Mac, Next.js SWC Minify will need a different binary so I explicitly add that to my dependencies on my Host machine with Yarn 3 (set to nodeLinker: node-modules
in .yarnrc)
But that does not install the package to my host node_modules
folder even though it is zipped in the .yarn/cache
folder and appears in my package.json dependencies. I'm not sure why, and I think it's the reason for this problem.
Dockerfile:
FROM ubuntu:18.04
# Install Node.js
RUN apt-get update
RUN apt-get -y install curl
RUN apt-get -y install sudo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -
RUN apt-get install -y nodejs
RUN apt-get install -y build-essential
# Install Yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
RUN sudo apt-get update
RUN sudo apt-get install yarn
WORKDIR /app
EXPOSE 3000
ENV PORT 3000
ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "dev"]
When I try run this container I get:
❯ docker compose up my-nextjs
[+] Running 1/1
⠿ Container my-nextjs Recreated 0.1s
Attaching to my-nextjs
my-nextjs | ready - started server on 0.0.0.0:3000, url: http://localhost:3000
my-nextjs | info - Loaded env from /app/.env
my-nextjs | warn - SWC minify release candidate enabled. https://nextjs.org/docs/messages/swc-minify-enabled
my-nextjs | info - Attempted to load @next/swc-linux-x64-gnu, but it was not installed
my-nextjs | info - Attempted to load @next/swc-linux-x64-gnux32, but it was not installed
my-nextjs | info - Attempted to load @next/swc-linux-x64-musl, but it was not installed
my-nextjs | error - Failed to load SWC binary for linux/x64, see more info here: https://nextjs.org/docs/messages/failed-loading-swc
my-nextjs exited with code 1
I have figured out a workaround for this... adding - /app/node_modules
to the docker-compose volumes to allow the container to persist that folder and in the Dockerfile:
COPY . /app/
RUN yarn install
Which gets the correct binary and persists it in its own node_modules
over the bind mounted node_modules
folder. But I'm just trying to see if there's a way to do it without copying over the whole thing from the build context. I'm sure that if Yarn 3 would actually install @next/swc-linux-x64-gnu
to node_modules
on my host then this could be possible.
Any thoughts?
In
<repoDir>/.yarnrc
, add:(Valid for yarn 1. You might want to double-check for later versions.)
Then run:
This will install the Linux version of SWC in your
node_modules
, regardless of the platform, and you'll be able to use that in docker containers.Trade-offs: