Next.js Discord

Discord Forum

Development dockerfile and docker-compose

Answered
Dwarf Crocodile posted this in #help-forum
Open in Discord
Dwarf CrocodileOP
Hello,
Does anyone have a working dockerfile and docker-compose for working with NextJS with hotreloading?
Answered by Knopper gall
services:
  frontend:
    image: node:lts
    volumes:
      - type: bind
        source: ./static
        target: /opt/app/static
volumes:
  myapp:
View full answer

52 Replies

Knopper gall
... you just make a container with the entry point "npm run dev"...
Dwarf CrocodileOP
Yes but will that update whenever I change a file? I have a production dockerfile but that doesn’t hotreload my website when I update a file. It only has a COPY . . to transfer files
@Dwarf Crocodile Yes but will that update whenever I change a file? I have a production dockerfile but that doesn’t hotreload my website when I update a file. It only has a COPY . . to transfer files
Knopper gall
if you're running it in dev mode, inside the container, then it will hot reload, I'm confused as to your issue?
Knopper gall
Production isn't going to hotreload if that's what you're after
Norwegian Forest Cat
I few years ago I ran into an issue on Windows where the ports used for hotreloading were not working from inside a Docker container, ended up having to switch NextJS to polling mode instead
" I have a production dockerfile but that doesn’t hotreload my website"
@Knopper gall Production isn't going to hotreload if that's what you're after
Norwegian Forest Cat
You're right. I wouldn't expect a production website to be hotreloading as the assets are pre-built in a production build
Dwarf CrocodileOP
Sorry i have a working production dockerfile and when i replace pnpm start with pnpm dev it still doesnt hotreload
here is my current dev dockerfile

FROM node:iron
RUN npm install -g pnpm
COPY ./ui /usr/src/ui
COPY ./web /usr/src/app
WORKDIR /usr/src/ui
RUN pnpm install
WORKDIR /usr/src/app
RUN ls
SHELL ["/bin/bash", "--login", "-c"]
ENV SHELL bash
RUN chmod 777 /usr/src/app -R
RUN chmod 744 ./prisma/schema.prisma
RUN pnpm install
RUN pnpm dlx prisma generate
CMD ["pnpm", "dev"]
@Dwarf Crocodile Sorry i have a working production dockerfile and when i replace `pnpm start` with `pnpm dev` it still doesnt hotreload
Norwegian Forest Cat
That'll be down to the port bindings as I described. Things may have changed. Look into exposing the ports
Dwarf CrocodileOP
No but it isnt even the hotreloading but the files updating as changing a line in vscode doesnt update the files in the container.
Norwegian Forest Cat
That's because you're using the COPY directive
You need to mount your app as a volume
Dwarf CrocodileOP
If i mount the volumes like this
    volumes:
      - ./ui:/usr/src/ui
      - ./web:/usr/src/app

the files dont appear in my container. do i have to specify some flags on top of this?
Knopper gall
I think there's some misunderstanding of how docker works.

Your dockerfile is the instructions to build an image of a container, think about it of instructions how to make a coffee (dockerfile), putting it into an envelope (build) and making the coffee from the instructions in the envelope (running the container)

Now if you copy some files in the dockerfile, you're telling docker that it should copy during build (before we seal the envelope)

The thing is, once that envelope is sealed (dockerfile built), only the container can read it, it can't be edited. You need to re-build if you change the instructions.

Because you're using "COPY" you're telling the build compiler to copy the files at compile-time (not runtime)

By mounting as a volume, you're mounting your host filesystem into the container filesystem, allowing you to dynamically modify (and persist) files.

I hope this makes sense
@Dwarf Crocodile Yes i've changed to mounting but now no files appear in `/usr/src/ui` and `/usr/src/app`. Do i have to add flags to my volumes in my docker-compose for mounting to work as expected?
Knopper gall
services:
  frontend:
    image: node:lts
    volumes:
      - type: bind
        source: ./static
        target: /opt/app/static
volumes:
  myapp:
Answer
Knopper gall
Dwarf CrocodileOP
Ok this is my docker-compose now but it still doesnt bind to my container
  dev:
    build:
      context: ../
      dockerfile: ./web/Dockerfile.dev
    ports:
      - '3000:3000'
    volumes:
      - type: bind
        source: ./ui
        target: /usr/src/ui
      - type: bind
        source: ./web
        target: /usr/src/app
    env_file:
      - path: ./.env
        required: true
volumes:
  mysql: ~
  dev: 


i just get

2024-04-14 16:08:08  ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND  No package.json (or package.yaml, or package.json5) was found in "/usr/src/app".


do i need to edit some permissions to allow docker to bind volumes?
Knopper gall
I think you might have your source and target back to front
source: host machine
target: in container
or is that correct?
Dwarf CrocodileOP
No i dont think so
Error response from daemon: invalid mount config for type "bind": invalid mount path: 'ui' mount path must be absolute
Knopper gall
Can you show me the contents of the directory which contains your "docker-compose.yml"?
Dwarf CrocodileOP
❯ ls -la
total 304
drwxr-xr-x 12 willem willem   4096 Apr 14 14:00 .
drwxr-xr-x  4 willem willem   4096 Apr 13 19:38 ..
drwxr-xr-x  6 willem willem   4096 Apr 13 19:37 app
-rw-r--r--  1 willem willem    738 Apr 14 16:14 docker-compose.yml
-rw-r--r--  1 willem willem    385 Apr 13 19:37 Dockerfile
-rw-r--r--  1 willem willem    370 Apr 14 16:07 Dockerfile.dev
-rw-r--r--  1 willem willem     72 Apr 13 19:48 .dockerignore
-rw-r--r--  1 willem willem    268 Apr 13 19:42 .env
-rw-r--r--  1 willem willem    241 Apr 13 19:37 .env.example
-rw-r--r--  1 willem willem  24573 Apr 14 14:10 .eslintjscache
-rw-r--r--  1 willem willem    823 Apr 14 12:34 .eslintrc.js
drwxr-xr-x  8 willem willem   4096 Apr 14 14:11 .git
-rw-r--r--  1 willem willem    435 Apr 14 14:10 .gitignore
-rw-r--r--  1 willem willem   1171 Apr 14 12:29 .gitlab-ci.yml
drwxr-xr-x  2 willem willem   4096 Apr 13 19:37 lib
drwxr-xr-x  6 willem willem   4096 Apr 14 15:47 .next
-rw-r--r--  1 willem willem    208 Apr 14 12:34 next.config.js
-rw-r--r--  1 willem willem    201 Apr 13 19:39 next-env.d.ts
drwxr-xr-x 17 willem willem   4096 Apr 14 12:33 node_modules
-rw-r--r--  1 willem willem   1908 Apr 14 12:33 package.json
-rw-r--r--  1 willem willem 151126 Apr 14 12:33 pnpm-lock.yaml
-rw-r--r--  1 willem willem     60 Apr 14 12:34 postcss.config.js
-rw-r--r--  1 willem willem  10105 Apr 14 14:10 .prettiercache
-rw-r--r--  1 willem willem    585 Apr 14 12:33 .prettierignore
-rw-r--r--  1 willem willem    212 Apr 14 12:34 .prettierrc
drwxr-xr-x  2 willem willem   4096 Apr 13 19:37 prisma
drwxr-xr-x  2 willem willem   4096 Apr 13 19:37 public
-rw-r--r--  1 willem willem   1383 Apr 13 19:37 README.md
drwxr-xr-x  5 willem willem   4096 Apr 13 19:37 server
-rw-r--r--  1 willem willem     49 Apr 14 12:34 tailwind.config.ts
-rw-r--r--  1 willem willem    791 Apr 13 19:37 tsconfig.json
Knopper gall
ok, and what is your pwd before you run docker build?
Dwarf CrocodileOP
/home/willem/Coding/Web/t/web

just the folder
The context of the container is however in the /t/ directory
Knopper gall
well there's your issue
you're trying to mount ./app from the web directory
so you're mounting web/app not app
Dwarf CrocodileOP
No i'm trying to mount the /web directory from /t/ to the /usr/src/app directory in my container and /t/ contains those two folders
❯ ls -l
total 8
drwxr-xr-x  5 willem willem 4096 Apr 13 19:38 ui
drwxr-xr-x 10 willem willem 4096 Apr 14 16:15 web
Knopper gall
oh right sorry I misunderstood
so does web contain package.json?
Dwarf CrocodileOP
Yes the /web directory is the one listed above
I'm wondering if its a secuity problem for docker. Basically that you cant mount folders that are in parent directories of your docker-compose
Knopper gall
that makes no sense
@Dwarf Crocodile ❯ ls -la total 304 drwxr-xr-x 12 willem willem 4096 Apr 14 14:00 . drwxr-xr-x 4 willem willem 4096 Apr 13 19:38 .. drwxr-xr-x 6 willem willem 4096 Apr 13 19:37 app -rw-r--r-- 1 willem willem 738 Apr 14 16:14 docker-compose.yml -rw-r--r-- 1 willem willem 385 Apr 13 19:37 Dockerfile -rw-r--r-- 1 willem willem 370 Apr 14 16:07 Dockerfile.dev -rw-r--r-- 1 willem willem 72 Apr 13 19:48 .dockerignore -rw-r--r-- 1 willem willem 268 Apr 13 19:42 .env -rw-r--r-- 1 willem willem 241 Apr 13 19:37 .env.example -rw-r--r-- 1 willem willem 24573 Apr 14 14:10 .eslintjscache -rw-r--r-- 1 willem willem 823 Apr 14 12:34 .eslintrc.js drwxr-xr-x 8 willem willem 4096 Apr 14 14:11 .git -rw-r--r-- 1 willem willem 435 Apr 14 14:10 .gitignore -rw-r--r-- 1 willem willem 1171 Apr 14 12:29 .gitlab-ci.yml drwxr-xr-x 2 willem willem 4096 Apr 13 19:37 lib drwxr-xr-x 6 willem willem 4096 Apr 14 15:47 .next -rw-r--r-- 1 willem willem 208 Apr 14 12:34 next.config.js -rw-r--r-- 1 willem willem 201 Apr 13 19:39 next-env.d.ts drwxr-xr-x 17 willem willem 4096 Apr 14 12:33 node_modules -rw-r--r-- 1 willem willem 1908 Apr 14 12:33 package.json -rw-r--r-- 1 willem willem 151126 Apr 14 12:33 pnpm-lock.yaml -rw-r--r-- 1 willem willem 60 Apr 14 12:34 postcss.config.js -rw-r--r-- 1 willem willem 10105 Apr 14 14:10 .prettiercache -rw-r--r-- 1 willem willem 585 Apr 14 12:33 .prettierignore -rw-r--r-- 1 willem willem 212 Apr 14 12:34 .prettierrc drwxr-xr-x 2 willem willem 4096 Apr 13 19:37 prisma drwxr-xr-x 2 willem willem 4096 Apr 13 19:37 public -rw-r--r-- 1 willem willem 1383 Apr 13 19:37 README.md drwxr-xr-x 5 willem willem 4096 Apr 13 19:37 server -rw-r--r-- 1 willem willem 49 Apr 14 12:34 tailwind.config.ts -rw-r--r-- 1 willem willem 791 Apr 13 19:37 tsconfig.json
Knopper gall
read this
this isn't your web directory
Dwarf CrocodileOP
It is
Knopper gall
so your web directory contains ui and web?
so you have web/web
and web/ui?
Dwarf CrocodileOP
Oh no sorry disregard the last two folders they are empty
its from testing
my mistake
Knopper gall
change your entrypoint to /bin/sh, docker run -it your container please
then ls the filesystem in the container
(or docker exec)
Dwarf CrocodileOP
Ok apparently the volumes did work but didnt update for some reason so i deleted all volumes and images and now it works, how i love tech sometimes. Now i've got some weird local dependency resolution that works with next build but not next dev but i'll keep that to another thread.