2 min read

Running Laravel and Vite Behind Traefik with Devcontainers

Here’s how I expose both Laravel and Vite servers behind Traefik using Devcontainers.


1. Update Vite Dev Script

Make sure to add --host to the Vite dev script. This is required because Traefik accesses services using the Docker IP subnet, not localhost.

package.json
{
  "$schema": "https://json.schemastore.org/package.json",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "vite build",
    "dev": "vite --host"
  }
}

2. Configure Vite HMR

Set server.hmr.host to your custom local domain. By default, Vite will allow all .localhost domains.

vite.config.js
export default defineConfig({
  plugins: [
    laravel({
      input: ["resources/css/app.css", "resources/js/app.js"],
      refresh: true,
    }),
    tailwindcss(),
  ],
  server: {
    hmr: {
      host: "my-app.localhost",
    },
  },
});

3. Add Traefik Labels to Your Docker Compose

Add Traefik labels for both Laravel (port 8080) and Vite (port 5173) services. I’m using serversideup/docker-php, which exposes port 8080 by default.

Make sure your router and service names are unique across all applications sharing the same Traefik network.

docker-compose.yml
services:
  app:
    # ... other config
    labels:
      - traefik.enable=true
 
      - traefik.http.routers.my-app-vite.entrypoints=vite
      - traefik.http.routers.my-app-vite.rule=Host(`my-app.localhost`)
      - traefik.http.routers.my-app-vite.service=my-app-vite
      - traefik.http.services.my-app-vite.loadbalancer.server.port=5173
 
      - traefik.http.routers.my-app.entrypoints=web
      - traefik.http.routers.my-app.rule=Host(`my-app.localhost`)
      - traefik.http.routers.my-app.service=my-app
      - traefik.http.services.my-app.loadbalancer.server.port=8080

4. Expose Vite Port in Traefik Config

Make sure to expose port 5173 via a new vite entrypoint in your Traefik Docker service.

docker-compose.traefik.yml
services:
  traefik:
    image: traefik:3.1
    # ... other config
    command:
      # ... existing entrypoints
      - --entrypoints.web.address=:80
      - --entrypoints.vite.address=:5173
    ports:
      - 80:80
      - 8080:8080
      - 5173:5173

5. Add VS Code Dev Shortcut (Optional)

Use this .vscode/launch.json file to easily run npm run dev with F5 in VS Code.

.vscode/launch.json
{
  "version": "0.0.1",
  "configurations": [
    {
      "name": "Run Vite",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "npm",
      "runtimeArgs": ["run", "dev"],
      "console": "integratedTerminal"
    }
  ]
}

That’s it! You can now run Laravel and Vite seamlessly behind Traefik inside a Devcontainer, without port conflicts between multiple projects.