0

I am trying to run a React project using Vite inside a Docker container with Code-Server. The app is proxied through Code-Server at http://localhost:8080/proxy/5173/, but I'm facing issues loading the app in the browser.

Here is my Dockerfile:

FROM node:latest
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update
RUN apt install -y curl
WORKDIR /workspace
RUN curl -fsSL https://code-server.dev/install.sh | sh
COPY ./init.sh .
CMD ["bash", "init.sh"]

The init.sh script initializes the project:

#!/bin/bash

# Check if FRAMEWORK is set
if [ -z "$FRAMEWORK" ]; then
    echo "FRAMEWORK is not set"
    exit 1
fi

# Check if PROJECT is set
if [ -z "$PROJECT" ]; then
    echo "PROJECT is not set"
    exit 1
fi

# Create project based on FRAMEWORK
if [ "$FRAMEWORK" = "react" ]; then
    npm create vite@latest "$PROJECT" -- --template react --yes
elif [ "$FRAMEWORK" = "vue" ]; then
    npm create vite@latest "$PROJECT" -- --template vue --yes
else 
    echo "Unknown framework: $FRAMEWORK"
    exit 1
fi

# Install dependencies
cd "$PROJECT" && npm install

# Start Code-Server
code-server --host 0.0.0.0

I run the container with the following command:

docker run -p 8080:8080 -e FRAMEWORK="react" -e PROJECT="my-app" -e PASSWORD="codepwd" vite-node-portos

Vite Configuration

Initially, I used this vite.config.js:

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

export default defineConfig({
  plugins: [react()],
})

To address the error connect ECONNREFUSED 0.0.0.0:5172, I modified the config to explicitly bind to 0.0.0.0: error image

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

export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',
    port: 5173,
  },
})

However, this caused errors in the browser console:

Loading failed for the module with source “http://localhost:8080/proxy/5173/src/main.jsx”.
Loading failed for the module with source “http://localhost:8080/proxy/5173/@react-refresh”.
Loading failed for the module with source “http://localhost:8080/proxy/5173/@vite/client”.

I then updated the vite.config.js to include a base configuration:

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

export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',
    port: 5173,
  },
  base: '/proxy/5173/',
})

However, this caused the same errors in the browser console:

Loading failed for the module with source “http://localhost:8080/proxy/5173/src/main.jsx”.
Loading failed for the module with source “http://localhost:8080/proxy/5173/@react-refresh”.
Loading failed for the module with source “http://localhost:8080/proxy/5173/@vite/client”.

error image

How can I resolve the module loading errors and correctly serve my Vite app through the Code-Server proxy?

In tools like Project IDX or GitHub Codespaces, Vite projects work without requiring edits to the vite.config.js file to handle proxy paths. Is there a similar way to resolve the proxy issue with Code-Server, so I don't need to modify the Vite config directly?

1 Answer 1

0

I fixed this issues with Vite when running a React app in a Docker container using Code-Server and resolved them by setting up a reverse proxy inside the container and using npm run dev -- --host 0.0.0.0. Here's how I fixed the problem.


Dockerfile

FROM node:18

# Install necessary packages
RUN apt-get update && apt-get install -y \
    curl \
    git \
    nginx \
    nano \
    supervisor \
    && rm -rf /var/lib/apt/lists/*

# Install openvscode-server
ENV VSCODE_VERSION=1.84.2
ENV ARCH=x64
RUN curl -L "https://github.com/gitpod-io/openvscode-server/releases/download/openvscode-server-v${VSCODE_VERSION}/openvscode-server-v${VSCODE_VERSION}-linux-${ARCH}.tar.gz" | tar -xz -C /opt/
RUN ln -s /opt/openvscode-server-v${VSCODE_VERSION}-linux-${ARCH} /opt/openvscode-server

# Set working directory
WORKDIR /workspace

# Copy configuration files
COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY ./init.sh .
COPY ./generate-nginx-conf.sh /generate-nginx-conf.sh
RUN chmod +x /generate-nginx-conf.sh
RUN chmod +x init.sh

# Expose only the main port
EXPOSE 80

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

init.sh

This script initializes the React project and starts the Vite development server.

#!/bin/bash

# Check if FRAMEWORK is set
if [ -z "$FRAMEWORK" ]; then
    echo "FRAMEWORK is not set"
    exit 1
fi

# Check if PROJECT is set
if [ -z "$PROJECT" ]; then
    echo "PROJECT is not set"
    exit 1
fi

# Create project based on FRAMEWORK
if [ "$FRAMEWORK" = "react" ]; then
    npm create vite@latest "$PROJECT" -- --template react --yes
elif [ "$FRAMEWORK" = "vue" ]; then
    npm create vite@latest "$PROJECT" -- --template vue --yes
else 
    echo "Unknown framework: $FRAMEWORK"
    exit 1
fi

cd $PROJECT
npm install
npm run dev -- --host 0.0.0.0

generate-nginx-conf.sh

This script generates the nginx configuration dynamically for both the Vite app and Code-Server.

#!/bin/bash

# Set default values if not provided
VSCODE_DOMAIN=${VSCODE_DOMAIN:-"reactapp.localhost"}
APP_DOMAIN=${APP_DOMAIN:-"reactapp-port-5173.localhost"}
APP_PROXY_PASS=${APP_PROXY_PASS:-"http://localhost:5173"}

# Generate nginx configuration
cat > /etc/nginx/nginx.conf << EOL
user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    map \$http_upgrade \$connection_upgrade {
        default upgrade;
        '' close;
    }
    
    server {
        listen 80;
        server_name ${VSCODE_DOMAIN};
        access_log /var/log/nginx/vscode.access.log;
        
        location / {
            proxy_pass http://127.0.0.1:3001;
            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_set_header Upgrade \$http_upgrade;
            proxy_set_header Connection \$connection_upgrade;
            proxy_buffering off;
            proxy_http_version 1.1;
            proxy_connect_timeout 300s;
            proxy_send_timeout 300s;
            proxy_read_timeout 300s;
        }
    }
    
    server {
        listen 80;
        server_name ${APP_DOMAIN};
        
        location / {
            proxy_pass ${APP_PROXY_PASS};
            proxy_http_version 1.1;
            proxy_set_header Upgrade \$http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host \$host;
            proxy_cache_bypass \$http_upgrade;
            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;
        }
    }
}
EOL

# Test nginx configuration
nginx -t

supervisord.conf

This supervisord configuration ensures both Nginx and Code-Server run inside the container.

[supervisord]
nodaemon=true

[program:nginx]
command=/usr/sbin/nginx -g 'daemon off;'
autostart=true
autorestart=true

[program:code-server]
command=/opt/openvscode-server/bin/openvscode-server --host 0.0.0.0
autostart=true
autorestart=true

Running the Container

To run the container:

docker build -t react-app-container .
docker run -p 80:80 \
    -e FRAMEWORK="react" \
    -e PROJECT="my-app" \
    -e VSCODE_DOMAIN="reactapp.localhost" \
    -e APP_DOMAIN="reactapp-port-5173.localhost" \
    react-app-container
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.