Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
justinkekeocha opened this issue May 12, 2024 · 18 comments

Comments

@justinkekeocha
Copy link
Contributor

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

Copy link
Contributor

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:

@manniL
Copy link
Member

manniL commented May 12, 2024

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.

@justinkekeocha
Copy link
Contributor Author

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

@manniL
Copy link
Member

manniL commented May 12, 2024

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 / ... 👍🏻) 😋

@justinkekeocha
Copy link
Contributor Author

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.

@manniL
Copy link
Member

manniL commented May 13, 2024

@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.

@justinkekeocha
Copy link
Contributor Author

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?

@warflash
Copy link
Member

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.

@justinkekeocha
Copy link
Contributor Author

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.

@warflash
Copy link
Member

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 warflash closed this as not planned Won't fix, can't repro, duplicate, stale May 14, 2024
@justinkekeocha
Copy link
Contributor Author

@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?

@warflash
Copy link
Member

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

@ChamkhiAnas
Copy link

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

@warflash
Copy link
Member

@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
Copy link

@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 ?

@warflash
Copy link
Member

warflash commented May 22, 2024

@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.

@justinkekeocha
Copy link
Contributor Author

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.

@ChamkhiAnas
Copy link

ChamkhiAnas commented May 22, 2024

@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.

@warflash

im not using docker , nuxt app with pm2 on port 3000 and nginx reverse proxy windows server 2012

i didnt create a reproduction because i'm sure there is no problem with code it was working well in dev server , the problem appears when i build and deploy the app to nginx using pm2

here is my nginx.conf


 server {
        listen 80;
        server_name www.immocockpit.fr immocockpit.fr;
        return 301 https://$host$request_uri;
        charset utf-8;
     
    }

  

    server {
    listen   443 ssl;
    server_name www.immocockpit.fr immocockpit.fr;
    charset utf-8;

    ssl_certificate www.immocockpit.fr-crt.pem;
    ssl_certificate_key www.immocockpit.fr-key.pem;
    


    ssl_session_timeout 1d;
    ssl_protocols TLSv1.2 TLSv1.3; 
    ssl_ciphers EECDH+CHACHA20:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;

    gzip            on;
    gzip_types      text/plain application/xml text/css application/javascript;
    gzip_min_length 1000;


     location / {


        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          1m;
        proxy_connect_timeout       1m;
        proxy_pass http://127.0.0.1:3000;

           
        }


    }

anad ecosystem.config.cjs that run with pm2

module.exports = { apps: [ { name: 'EstimationFront', port: '3000', exec_mode: 'cluster', instances: 'max', // Or a number of instances script: './.output/server/index.mjs', args: 'start' } ] }

i would be grateful for your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants