skip to Main Content

I’ve got a dockerized app with a frontend in Sveltekit and a backend API in Laravel.

I’ve got two docker-compose files, one for development and the other for production.

When running development my app works as expected. I can fetch data from the backend and also create and update data.

But when building and running production I can only fetch data from the backend. Meaning that only GET requests are going through, all other requests (POST, PUT, etc) are not.

I added some logs in my frontend apps and this is the response from a POST:

{ status: 419, data: undefined }

the URL used to perform requests is:

baseURL = "http://host.docker.internal:8000/api/";

I don’t believe it’s an issue related to the URL since as I mentioned before GET requests from the frontend work just fine.

This is my production docker-compose file:

version: "3.9"
services:
  app:
    build:
      context: ./
      dockerfile: Dockerfile
    image: dmc
    container_name: dmc-app
    restart: unless-stopped
    working_dir: /var/www/
    depends_on:
      - db
      - nginx
    volumes:
      - ./:/var/www/
#      - ./docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
      - ./docker/php/conf.d/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini
      - ./images:/public/images
    networks:
      - dmc-net

  nginx:
    image: nginx:1.23.2-alpine
    container_name: dmc-nginx
    restart: unless-stopped
    ports:
      - "8000:80"
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d
    networks:
      - dmc-net

  supervisor:
    build: .
    container_name: dmc-supervisor
    command: /var/www/artisan queue:work --sleep=4 --tries=3
    restart: unless-stopped
    depends_on:
      - app
      - nginx
      - db
    volumes:
      - ./:/var/www/
    networks:
      - dmc-net

  db:
    image: mysql:8.0.31
    container_name: dmc-db
    restart: unless-stopped
    # using 3307 on the host machine to avoid collisions in case there's a local MySQL instance installed already.
    ports:
      - "3307:3306"
    # use the variables declared in .env file
    environment:
      MYSQL_HOST: ${DB_HOST}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: abcd1234
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker-compose/mysql:/docker-entrypoint-initdb.d
      - mysql-data:/var/lib/mysql
    networks:
      - dmc-net

  dmc-web:
    build:
      context: /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui
      dockerfile: /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui/Dockerfile
      target: prod
    container_name: dmc-web
    restart: always
    environment:
      - NODE_ENV=production
      - ORIGIN=http://localhost:3000
    ports:
      - "1313:3000"
      - "5137:5137"
      - "3000:3000"
    volumes:
      # it avoids mounting the workspace root
      # because it may cause OS specific node_modules folder
      # or build folder(.svelte-kit) to be mounted.
      # they conflict with the temporary results from docker space.
      # this is why many mono repos utilize ./src folder
      - /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui/src:/app/src
      - /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui/static:/app/app/static
      - /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui/static:/app/static/
    depends_on:
      - app
      - nginx
      - db
    links:
      - app
    networks:
      - dmc-net

networks:
  dmc-net:
    driver: bridge

volumes:
  mysql-data:

Any idea what’s going on?

Thanks.

2

Answers


  1. It could be a problem related to Laravel‘s CSRF (Cross-Site Request Forgery) protection, which can be disabled in the development environment (but not in production).
    Laravel requires a CSRF token for all POST, PUT, PATCH, DELETE, and POST requests to protect against CSRF attacks. That token must be included in the request’s headers or as a request parameter. A 419 status code typically indicates that the request failed CSRF verification.

    First, temporarily disable CSRF protection on a test route in Laravel to confirm that the issue is CSRF-related. If the request succeeds, the problem is almost certainly with how CSRF tokens are handled.

    Make sure your SvelteKit frontend is correctly configured to send the CSRF token with the requests. For Laravel, this token can be retrieved from a meta tag within your blade template (csrf_token() function) or from a cookie (XSRF-TOKEN). SvelteKit needs to include this token in the headers of the requests it sends to the Laravel backend.

    // Fetch the CSRF token from Laravel
    const csrfToken = document.head.querySelector('meta[name="csrf-token"]').content;
    
    // Include the CSRF token in your POST request headers
    fetch('http://host.docker.internal:8000/api/your-endpoint', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': csrfToken,
      },
      body: JSON.stringify({
        // Your request payload
      }),
    });
    

    If your Laravel application is setting cookies that are strictly SameSite, make sure your frontend and backend are served from the same domain or adjust the SameSite attribute of your cookies. In a production environment, differing domains or subdomains without proper SameSite configuration can cause issues.
    If the token is stored in a cookie (XSRF-TOKEN), you might need to configure your HTTP client to send this token as a header (X-XSRF-TOKEN) with each request.

    Also, make sure your CORS (Cross-Origin Resource Sharing) policy is correctly configured to allow requests from your SvelteKit frontend to your Laravel backend. Although this typically results in CORS errors rather than 419 errors, misconfiguration can lead to various request issues. See "How do I use a different backend API server?".

    Login or Signup to reply.
  2. What is an MDX file?
    MDX is an extension to Markdown that lets you include JSX in Markdown documents. MDX makes it possible to include React components in your Gatsby blog posts and pages. Markdown defines a plain text syntax for HTML elements such as h1 , strong , and a , but still supports inline HTML.

    volumes:
    

    mysql-data:mdx
    nginx:mdx
    file: /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui/docker

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search