Executando verificação de segurança...
1
Mikw
2 min de leitura ·

Erro vite conexão recusada usando o Laravel 12 mais Docker e Nginx

Oi estou desenvolvendo um sistema para estudos usando Docker e Laravel, e estou enfrentando um erro depois de ter gerado a imagen, agora quando eu quero rodar o comando npm run dev e tento acessar o localhost:8081 onde foi a porta que eu setei porém esta dando erro de conexão recusada:

GET http://localhost:5173/@vite/client net::ERR_CONNECTION_REFUSED
localhost/:21
GET http://localhost:5173/resources/js/app.jsx net::ERR_CONNECTION_REFUSED
localhost/:21
GET http://localhost:5173/resources/js/Pages/Welcome.jsx net::ERR_CONNECTION_REFUSED
localhost/:16
GET http://localhost:5173/@react-refresh net::ERR_CONNECTION_REFUSED

Esse aqui é meu dockerfile:

FROM php:8.2-fpm

# Install required dependencies
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    libzip-dev \
    procps \
    && docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip

RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - \
    && apt-get install -y nodejs

# Install Composer
COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www/html

COPY . /var/www/html

Esse é meu docker-compose.yml:

services:
  economize-app:
    build:
      context: ./docker/php
    container_name: economize-app
    volumes:
      - .:/var/www/html
    ports:
      - "9000:9000"
    networks:
      - laravel

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8081:80"
    volumes:
      - .:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - economize-app
    networks:
      - laravel

networks:
  laravel:

E essa é minha config do nginx:

server {
    listen 80;
    server_name localhost;
    index index.php index.html;
    root /var/www/html/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass economize-app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }
}

Eu tentei setar um ip padrão no vite, mas ainda sim não consegui:

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

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.jsx',
            refresh: true,
        }),
        react(),
    ],
    server: {
        host: '0.0.0.0', // Acessível em qualquer interface de rede
        port: 5173, // Porta padrão do Vite
        https: false,
        cors: false,
        hmr: {
            host: 'localhost', // Host para Hot Module Replacement (HMR)
        },
    },
});

Alguém sabe como posso consertar esse problema?

Carregando publicação patrocinada...
1

O vite roda na porta 5173 mas ela não está aberta em nenhum container. Verifiquei que instalou o node no container do PHP. Seria mais interessante ter um container só para o node. Porém se quiser manter assim é só abrir essa porta no container que está rodando o npm run dev

Caso tenha problemas para fazer o setup do ambiente dê uma olhada no Laravel Sail

1

Eu usei o Laravel Sail algumas vezes mas eu quero algo que eu posso colocar em produção, depois do erro eu encontrei o problema da mesma forma, eu exportei a porta 5173 no container do PHP e fiz a configuração do vite.config.js, agradeço.

4

algo que eu posso colocar em produção

Não é recomendado colocar npm run dev em produção, já que ele expõe todos os seus sourcemaps e gera um overhead gigantesco por ter que verificar toda hora se os arquivos foram alterados.

Sendo assim a instalação do node poderia estar em um container totalmente separado, apenas para desenvolvimento.

Outro motivo para usar configurações separadas é a otimização de produção. O PHP precisa ficar alterando o tempo inteiro? Não, então deixa tudo compilado e quando alterar rebuilda a imagem inteira


Aqui vai uma ideia do que uso nos meus projetos em produção. Eu crio uma configuração totalmente personalizada para cada projeto, é uma boa base para começar.

Dockerfile

############ BUILD PHP #############
FROM php:8.3-fpm AS build-php

WORKDIR /app

RUN apt update && \
    apt install -y ca-certificates curl tar libxml2-dev libzip-dev wget libpq-dev && \
    apt clean
RUN docker-php-ext-install opcache
RUN docker-php-ext-configure zip
RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql
RUN docker-php-ext-install bcmath pdo_mysql zip xml sockets pgsql pdo_pgsql intl
RUN pecl install redis && docker-php-ext-enable redis
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

COPY . ./

RUN composer install --optimize-autoloader --no-dev
RUN cp /app/deploy/php.ini /usr/local/etc/php/conf.d/z_config.ini

########### STATIC BUILD ###########
FROM node:20-alpine AS static-build

WORKDIR /app

COPY package.json ./
RUN npm install --include=dev

COPY . ./

RUN npm run build

############### BASE ###############
FROM build-php AS base

COPY --from=static-build /app/public/build /app/public/build

########## STATIC SERVER ###########
FROM nginx:alpine AS static-server
WORKDIR /app/public

COPY ./deploy/static/nginx.conf /etc/nginx/nginx.conf
COPY ./deploy/static/static.conf /etc/nginx/conf.d/default.conf
COPY --from=static-build /app/public /app/public

############ WEB SERVER ############
FROM base AS web

RUN chmod +x deploy/web/docker_entrypoint.sh

########## WORKER SERVER ###########
FROM base AS worker

RUN apt update && apt install -y supervisor && apt clean

RUN chmod +x deploy/worker/docker_entrypoint.sh

# Config workers
RUN cp /app/deploy/worker/* /etc/supervisor/conf.d/ && \
    touch /app/storage/logs/schedule.log && \
    touch /app/storage/logs/worker.log

Docker compose

services:
    web:
        restart: always
        build:
            context: .
            target: web
        entrypoint: 'deploy/web/docker_entrypoint.sh'
        volumes:
            - ./storage:/app/storage
        ports:
            - 9000:9000
        env_file:
            - .env
        networks:
            - [appname]svc
        deploy:
            resources:
                limits:
                    cpus: '2'
                    memory: 2G
                reservations:
                    cpus: '0.25'
                    memory: 256M

    worker:
        restart: always
        build:
            context: .
            target: worker
        entrypoint: 'deploy/worker/docker_entrypoint.sh'
        volumes:
            - ./storage:/app/storage
        env_file:
            - .env
        networks:
            - [appname]svc
        deploy:
            resources:
                limits:
                    cpus: '1'
                    memory: 1.5G
                reservations:
                    memory: 256M

    static:
        restart: always
        build:
            context: .
            target: static-server
        ports:
            - 9001:9001
        networks:
            - [appname]svc
        deploy:
            resources:
                limits:
                    cpus: '1'
                    memory: 128M
                reservations:
                    cpus: '0.25'
                    memory: 32M

networks:
  [appname]svc:
    driver: bridge
    external: true
    name: [appname]_svc

static.conf

server {
    root /app/public;
    listen [::]:9001;
    listen 9001;
}

Sim, tem um nginx dedicado a apenas servir os estáticos deste projeto, e outro nginx para fazer o proxy de todos os serviços

entrypoint web

#!/bin/bash

php artisan migrate --force --isolated
php artisan db:seed --force

php artisan optimize:clear
php artisan optimize

php-fpm

entrypoint worker

#!/bin/bash

php artisan migrate --force --isolated

php artisan optimize:clear
php artisan optimize

supervisord -n

Conf supervisor worker

[program:[appname]-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /app/artisan queue:work --max-jobs=1000 --max-time=3600 --queue=high,default,low
autostart=true
autorestart=true
stopasgroup=true
numprocs=10
redirect_stderr=true
stdout_logfile=/app/storage/logs/worker.log
stopwaitsecs=30
user=www-data
[program:[appname]-schedule]
process_name=%(program_name)s_%(process_num)02d
command=php /app/artisan schedule:work
autostart=true
autorestart=true
stopasgroup=true
numprocs=1
redirect_stderr=true
stdout_logfile=/app/storage/logs/schedule.log
user=www-data

nginx conf

server {
    server_name [appname];
    root /app;

    location / {
        try_files $uri /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /app/public/index.php;
    }

    location /build {
        proxy_pass http://127.0.0.1:9001;
        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-Host $server_name;
    }

    listen [::]:443 ssl; 
0

bom parece que eu consertei na config do vite:

server: {
        host: '0.0.0.0',
        hmr: {
            host: 'localhost'
        }
    }

Agora o por que? é outros 5000