nuxt / nuxt

The Intuitive Vue Framework.

Home Page:https://nuxt.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usefetch does not return data on full reload of page in docker, but returns data when pages are navigated

justinkekeocha opened this issue Β· comments

Environment

  • Operating System: Linux
  • Node Version: v20.13.1
  • Nuxt Version: 3.11.2
  • CLI Version: 3.11.1
  • Nitro Version: 2.9.6
  • Package Manager: npm@10.5.2
  • Builder: -
  • User Config: devtools, typescript, devServer, runtimeConfig, modules, shadcn, build, alias, imports, piniaPersistedstate, radash, hooks, routeRules
  • Runtime Modules: @nuxtjs/tailwindcss@6.12.0, shadcn-nuxt@0.10.2, nuxt-icon@0.6.10, @pinia/nuxt@0.5.1, @pinia-plugin-persistedstate/nuxt@1.2.0, nuxt-radash@1.0.0
  • Build Modules: -

Reproduction

version: '3.8'

services:
node:
build:
context: ./docker/node
#Needed for bash scripts to access environment variables
env_file:
- .env
volumes:
- ./:/var/www/html
networks:
- frontend

nginx:
    image: 'nginx:1.25-alpine'
    ports:
        - '${APP_PORT}:80'
    volumes:
        - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
        - ./docker/nginx/conf.d/:/etc/nginx/conf.d/
    networks:
        - frontend
    depends_on:
        - node

networks:
frontend:
driver: bridge

./docker/node/dockerfile

FROM node:20-bullseye-slim

Install dumb-init to handle process management

RUN apt-get update && apt-get install -y dumb-init && rm -rf /var/lib/apt/lists/*

Set the working directory

WORKDIR /var/www/html

Copy application directory contents and permissions

COPY --chown=node:node . .

ENV HOST='0.0.0.0'
#This port can be changed to something like 5000
ENV PORT='3000'
#node-server is the default preset for nuxt, but it is still nice to set it here.
#This set up will still work without setting it since the default is node-server.
#https://nuxt.com/docs/getting-started/deployment#presets
ENV NITRO_PRESET=node-server

COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

Change to non-root user

USER node

ENTRYPOINT ["entrypoint.sh"]

EXPOSE $PORT


./docker/node/entrypoint.sh

#!/bin/bash

#Specifying env_file in docker-compose is important for [$NODE_ENV] this to work

Run the command to start the server using "dumb-init"

if [ "$NODE_ENV" = "production" ]; then
echo "Starting in production mode"
npm run build
exec dumb-init npm run start
else
echo "Starting in development mode"
#adding -- --host below or specifying HOST=0.0.0.0 in env is needed for this to expose the port to the host
#vitejs/vite#3396 (reply in thread)
exec dumb-init npm run dev --public
fi
#for debugging purposes
#exit 1


./docker/nginx/nginx.conf

#https://github.com/laradock/laradock/blob/master/nginx/nginx.conf

worker_processes auto;
pid /run/nginx.pid;

events {
worker_connections 2048;
multi_accept on;
use epoll;
}

http {
disable_symlinks off;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;
types_hash_max_size 2048;
client_max_body_size 120M;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr;
gzip on;
gzip_disable "msie6";
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;

gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

include /etc/nginx/conf.d/*.conf;
open_file_cache off; # Disabled for issue 619
charset UTF-8;
}


./docker/nginx/conf.d/default.conf

#https://v5-docs.adonisjs.com/guides/deployment#nginx-reverse-proxy
server {

listen 80;
listen [::]:80;

location / {
proxy_pass http://node:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
}


Describe the bug

For context, useFetch works well when used with the regular npm run dev, but when i put the same codebase in a docker container, usefetch returns no data.

I also tested the application without the NGINX reverse proxy and it still didn't work.

Additional context

No response

Logs

No response

Would you be able to provide a reproduction? πŸ™

More info

Why do I need to provide a reproduction?

Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.

What will happen?

If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritize it based on its severity and how many people we think it might affect.

If needs reproduction labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.

How can I create a reproduction?

We have a couple of templates for starting with a minimal reproduction:

πŸ‘‰ https://stackblitz.com/github/nuxt/starter/tree/v3-stackblitz
πŸ‘‰ https://codesandbox.io/s/github/nuxt/starter/v3-codesandbox

A public GitHub repository is also perfect. πŸ‘Œ

Please ensure that the reproduction is as minimal as possible. See more details in our guide.

You might also find these other articles interesting and/or helpful:

Please provide a minimal reproduction, e.g. without additional backend services and the smallest amount of setup code/Dockerfile (if this is the issue) possible.

To me, this sounds more like a network issue at the moment.

Network issue? The codebase works well with npm run dev.

Also can I be able to run docker in those sandboxes? I tried with https://codesandbox.io/s/github/nuxt/starter/v3-codesandbox and it isn't possible

Also can I be able to run docker in those sandboxes?

No you can't. Feel free to provide a GitHub repo instead (and please keep it minimal to reproduce the error so it is not related to any api service / backend / ... πŸ‘πŸ») πŸ˜‹

I don't see how this won't be related to any api or backend, since this has to do with useFetch. This issue only happens with 127.0.0.1 host but will work well with any production host and when you run the project without docker and with only npm run dev.

I have created a minimal reproduction here. You should start a localhost api and replace it with the one in the index.vue page
https://github.com/justinkekeocha/nuxt-issue/tree/main/27177.

In the /tasks page, I have added this URL: https://jsonplaceholder.typicode.com/posts

You can replace the localhost link in index.vue with https://jsonplaceholder.typicode.com/posts and see that everything works very well with links in production.

I am willing to provide any other help as needed.

Cheers.

@justinkekeocha Thanks for the reproduction! If it works with a different API, then it is not a Nuxt issue ☺️

Did you enable CORS for your "local" API (on 8000)? If not, getting no data on the client side would be expected while SSR works fine.

Yes I did, if it is a CORS issue, the error would be there in console.

How is it not a nuxt issue when it works with npm run dev on CLI, but not when in a docker container?

How is it not a nuxt issue when it works with npm run dev on CLI, but not when in a docker container?

The networking inside the container is different to your dev node process.

await useFetch('http://127.0.0.1:8000/api/test'): running this in docker will not resolve to a process running on your local machine, instead it refers to port 8000 on the local network interface of the docker container running nuxt.

Thanks for this, but I am struggling to understand you here. 127.0.0.1:8000 is a Laravel application that runs on docker, mapped to 8000 port on my local machine, not the local docker network interface, for clarity I can go to my browser and see what's on 127.0.0.1:8000.

Maybe I am getting you all wrong, but I will appreciate a way for me to fix this issue.

You can see it in your browser because your browser uses your PC's network interface. The docker app running nuxt doesn't have access the to same network interface as it's it's own VM. 127.0.0.1:8000 inside the docker container and 127.0.0.1:8000 on your PC are entirely seperated things.
You can configure cross container networking either through: https://docs.docker.com/network/network-tutorial-standalone/ or through docker compose.

@warflash how come the docker app running nuxt does not have access to 127.0.0.1:8000 when a hard reload is done, but somehow has access to it when you navigate between pages and return data from 127.0.0.1:8000?

Data loaded by navigation between pages in the client side is done, well, on the client aka your browser. Your browser has access to that port as both run on the same host

i have the same issue im using nuxt with SSR mode and nginx for hosting
any solution ?

@ChamkhiAnas Would you mind opening a new issue alongside a reproduction? What's described in this issue here was not related to anything nuxt, but rather docker internal routing misunderstandings

@ChamkhiAnas Would you mind opening a new issue alongside a reproduction? What's described in this issue here was not related to anything nuxt, but rather docker internal routing misunderstandings

@warflash

im facing same problem i'm using useFetch it was working well in the dev server , i've deployed it to prod server with nginx and pm2 , now when im trying to acces from direct url or to refresh the page useFetch doesnt work , but when im navigate trough internal navigations inside app everything works fine , why ?

@ChamkhiAnas If you are truly facing the same issue then I recommend reading through my past comments regarding docker networking I gave above. If that doesn't resolve it then we'd need to see a reproduction of your issue in order to give hints.

For those who will encounter this problem in the future, I think it is worthy to share my findings.

This issue is experienced (on Windows), because docker create a virtual host, to be able to run docker on the OS.

This issue can be solved by adding:

        ` extra_hosts:
        - "host.docker.internal:host-gateway"`

to docker-compose on the service, that serves the application, whether NGINX or just node server. Then change 127.0.0.1:8000 (Or whatever port your backend is on) to host.docker.internal:8000 on the URL you use to call the backend.

I also found that adding the extra hosts is redundant and just trying to access host.docker.internal:8000 on my windows machine resolves perfectly.

I went to experience cookies and CORS errors subsequently, which I know clearly why I am experiencing that, but I don't have enough motive to resolve that now.

I will just use npm run dev locally and then use docker in production, since most servers are Linux machines and won't be creating a virtual host.