SvelteKit Docker fetch issue

I have searched for many hours but haven’t found any answer to this problem:
I have 2 docker containers. One with FastAPI backend and one with Sveltekit app.

Containers

Sending requests with openapi docs is fine. Sveltekit with npm run dev works fine too. But SvelteKit fetch in docker container throws error:

frontend  | TypeError: fetch failed
frontend  |     at node:internal/deps/undici/undici:12443:11
frontend  |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
frontend  |     at async resolve2 (file:///app/build/server/index.js:4118:14)
frontend  |     at async respond (file:///app/build/server/index.js:3941:22)
frontend  |     at async fetch (file:///app/build/server/index.js:3696:26) {
frontend  |   cause: Error: Client network socket disconnected before secure TLS connection was established   
frontend  |       at TLSSocket.onConnectEnd (node:_tls_wrap:1727:19)
frontend  |       at TLSSocket.emit (node:events:531:35)
frontend  |       at endReadableNT (node:internal/streams/readable:1696:12)
frontend  |       at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
frontend  |     code: 'ECONNRESET',
frontend  |     path: undefined,
frontend  |     host: '192.168.0.13',
frontend  |     port: 443,
frontend  |     localAddress: null
frontend  |   }
frontend  | }

My vite config

export default defineConfig({
    plugins: [sveltekit()],

    server: {
        host: true,
        proxy: {
            '/api': {
                target: 'http://127.0.0.1:8000', // see here
                changeOrigin: true,
                secure: false,
                rewrite: (path) => path.replace(/^\/api/, '')
            }
        }
    }
});

Tried changing target to http://localhost:8000 and http://backend:8000 but nothing helped.

Frontend Dockerfile

FROM node:latest AS builder

RUN mkdir /app && mkdir /app/data

COPY . /app

RUN cd /app && yarn install && \
    yarn build 



FROM node:latest

RUN mkdir /app

COPY --from=builder /app/build /app/build
COPY --from=builder /app/package.json /app/yarn.lock /app/

RUN cd /app && \ 
    yarn install --production && \
    yarn cache clean

WORKDIR /app

CMD ["node", "build/index.js"]

Docker compose

services:
  api:
    build:
      context: ./backend
      target: builder
    container_name: backend
    environment:
      - PORT=8000
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_HOST=${POSTGRES_HOST}
      - POSTGRES_PORT=${POSTGRES_PORT}
      - POSTGRES_NAME=${POSTGRES_NAME}
      - POSTGRES_DB_URL=${POSTGRES_DB_URL}
      - POSTGRES_ECHO=${POSTGRES_ECHO}

      - EMAIL_USERNAME=${EMAIL_USERNAME}
      - EMAIL_PASSWORD=${EMAIL_PASSWORD}
      - EMAIL_FROM=${EMAIL_FROM}
      - EMAIL_PORT=${EMAIL_PORT}
      - EMAIL_HOST=${EMAIL_HOST}
      - EMAIL_STARTTLS=${EMAIL_STARTTLS}
      - EMAIL_SSL_TLS=${EMAIL_SSL_TLS}
      - USE_CREDENTIALS=${USE_CREDENTIALS}
      - VALIDATE_CERTS=${VALIDATE_CERTS}

      - REDIS_HOST=redis
      - REDIS_PORT=${REDIS_PORT}
      - REDIS_DB=${REDIS_DB}

      - OAUTH_SECRET_KEY=${OAUTH_SECRET_KEY}
      - OAUTH_ACCESS_TOKEN_EXPIRE_MINUTES=${OAUTH_ACCESS_TOKEN_EXPIRE_MINUTES}
    ports:
      - "8000:8000"
    expose:
      - "8000:8000"
    depends_on:
      - postgres
      - redis
  frontend:
    build:
      context: ./frontend
    container_name: frontend
    expose:
      - "80:3000"
    ports:
      - "80:3000"
  postgres:
    image: postgres:latest
    container_name: postgres
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_NAME}
      - POSTGRES_USER=${POSTGRES_USER}
    expose:
      - 5432
    volumes:
      - postgres_data:/var/lib/postgresql/data
  redis:
    image: redis
    ports:
      - "6380:6379"
    expose:
      - "6379"
    volumes:
      - redis_data:/data
  worker:
    build:
      context: ./backend
      dockerfile: Celerybuild

    environment:
      - PORT=8000
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_HOST=${POSTGRES_HOST}
      - POSTGRES_PORT=${POSTGRES_PORT}
      - POSTGRES_NAME=${POSTGRES_NAME}
      - POSTGRES_DB_URL=${POSTGRES_DB_URL}
      - POSTGRES_ECHO=${POSTGRES_ECHO}

      - EMAIL_USERNAME=${EMAIL_USERNAME}
      - EMAIL_PASSWORD=${EMAIL_PASSWORD}
      - EMAIL_FROM=${EMAIL_FROM}
      - EMAIL_PORT=${EMAIL_PORT}
      - EMAIL_HOST=${EMAIL_HOST}
      - EMAIL_STARTTLS=${EMAIL_STARTTLS}
      - EMAIL_SSL_TLS=${EMAIL_SSL_TLS}
      - USE_CREDENTIALS=${USE_CREDENTIALS}
      - VALIDATE_CERTS=${VALIDATE_CERTS}

      - REDIS_HOST=redis
      - REDIS_PORT=${REDIS_PORT}
      - REDIS_DB=${REDIS_DB}

      - OAUTH_SECRET_KEY=${OAUTH_SECRET_KEY}
      - OAUTH_ACCESS_TOKEN_EXPIRE_MINUTES=${OAUTH_ACCESS_TOKEN_EXPIRE_MINUTES}
    depends_on:
      - redis
  flower:
    image: mher/flower:0.9.7
    command: ["flower", "--broker=redis://redis:6379", "--port=5555"]
    expose:
      - 5555
    depends_on:
      - redis
volumes:
  postgres_data:
  redis_data:

  • 1

    How are you running your containers? Do you use docker compose? Do you use the network parameter when creating your containers allowing them to see each other? What does backend refer to?

    – 

  • Hi, I’m running containers with docker compose. I don’t use network parameter. I expose ports manually using PORTS in docker compose. Backend is the name of container running FastAPI.

    – 




  • 1

    Add your compose file to the question and verify that the request is happening towards http://backend (without https)

    – 




  • Added docker compose

    – 

  • 1

    Nothing in your docker compose is named backend, so http://backend won’t resolve to anything. Did you mean api? The service name is the important part.

    – 

I added this to hooks.server.js and it worked:
reference

import { backend_url } from './utils';

export async function handleFetch({ request, fetch }) {
    request = new Request(`http://api:8000${request.url.split(backend_url)[1]}`, request);
    return fetch(request);
}

Where api is name of docker container

Leave a Comment