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
.
{
"$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.
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.
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.
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.
{
"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.