Search code examples
reactjsdockervite

Vite React app: esbuild error in Docker container


I'm trying to get to grips with both vite and docker so I apologise if I've made stupid mistakes.

I'm running into an issue with esbuild inside docker. I'm trying to get a dev setup going, so I want to mount my code in my containers so that changes should be reflected in real time.

Previously I used Dockerfiles which copied /frontend and /backend into their respective containers and that worked, I had my web and api containers running and happily talking to each other. However, it meant it didn't pick up any code changes so it wasn't suitable for development.

So I've switched to volume mounts in the hope that I can get my dockerized apps to hot reload, but hit this error instead.

Here's my docker-compose.yml

version: "3.8"
services:
  api:
    image: node:16-slim
    volumes:
      - ./backend:/app
      - ./shared:/shared
    working_dir: /app
    command: yarn start:dev
    ports:
      - "3001:3001"
  web:
    image: node:16-slim
    volumes:
      - ./frontend:/app
      - ./shared:/shared
    working_dir: /app
    command: yarn dev
    ports:
      - "3000:3000"

here's my vite.config.js

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    host: "0.0.0.0",
    port: 3000,
    fs: {
      strict: false,
    },
  },
  plugins: [react()],
});

docker-compose up -d --build

So this is the error that I'm trying to fix:

web_1  | yarn run v1.22.15
web_1  | $ vite
web_1  | failed to load config from /app/vite.config.js
web_1  | error when starting dev server:
web_1  | Error: The package "esbuild-linux-64" could not be found, and is needed by esbuild.
web_1  |
web_1  | If you are installing esbuild with npm, make sure that you don't specify the
web_1  | "--no-optional" flag. The "optionalDependencies" package.json feature is used
web_1  | by esbuild to install the correct binary executable for your current platform.
web_1  |     at generateBinPath (/app/node_modules/esbuild/lib/main.js:1643:15)
web_1  |     at esbuildCommandAndArgs (/app/node_modules/esbuild/lib/main.js:1699:11)
web_1  |     at ensureServiceIsRunning (/app/node_modules/esbuild/lib/main.js:1856:25)
web_1  |     at Object.build (/app/node_modules/esbuild/lib/main.js:1749:26)
web_1  |     at bundleConfigFile (/app/node_modules/vite/dist/node/chunks/dep-713b45e1.js:68592:34)
web_1  |     at loadConfigFromFile (/app/node_modules/vite/dist/node/chunks/dep-713b45e1.js:68569:35)
web_1  |     at resolveConfig (/app/node_modules/vite/dist/node/chunks/dep-713b45e1.js:68119:34)
web_1  |     at createServer (/app/node_modules/vite/dist/node/chunks/dep-713b45e1.js:66633:26)
web_1  |     at CAC.<anonymous> (/app/node_modules/vite/dist/node/cli.js:687:30)
web_1  | error Command failed with exit code 1.
web_1  | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
homepage_web_1 exited with code 1

I've spent most of the day reading various similar SO questions and github threads but nothing I found specifically addresses this, at least in a way I understand. I'd be really grateful if anyone could either point out where I've gone wrong, or point me at an example of a dockerized vite/react app with good dev and prod setups. Thanks!


Solution

  • Finally managed to get this working having read and better understood this discussion; https://github.com/vitejs/vite/issues/2671#issuecomment-829535806.

    I'm on MacOS but the container is running Linux and the architecture is mismatched when it attempts to use the version of esbuild from my mounted volume. So, I need to rebuild esbuild inside the container. I tried to use the entrypoint script as that thread suggests but that didn't work for me.

    What did work was to change the command in my docker-compose.yml to command: sh -c "npm rebuild esbuild && yarn dev".

    It's now hot reloading like a dream.