Hello brothers and sisters,
I'm currently exploring how to deploy Remix Vite to my server and just found out that Vite "base" config have 1 major problem (in my case). So I've been reading that base option can be a relative (""
, "./"
) or specific like /remix/
.
So in production server, my Remix app is deployed to docker, let's say its IP is 10.20.30.40:3000
, and have it mapped to Kong Gateway with domain mydomain.com/myapp
Here are the two cases:
/remix/
as base:/remix/<routes>
and /remix/<assets>
working perfectly even when I visit deep subpath like localhost:4000/remix/dashboard/users/internal
, all assets and routes have no problem.mydomain.com/myapp/dashboard
, or mydomain.com/myapp/dashboard/users/internal
, but the assets paths is not read correctly, the correct assets path for this gateway becomes mydomain.com/myapp/myapp/assets/<assetfile>
(doubles the basepath). Because path from Kong Gateway and base from Vite are combined.""
or "./"
as base:localhost:3000/dashboard
or mydomain.com/myapp/dashboard
work fine, route and assets (like tailwind) are read correctly, url was normal localhost:3000/assets/<assetfile>
or mydomain.com/myapp/assets/<assetfile>
. But when I visit deep subpath like localhost:3000/dashboard/users
or mydomain.com/myapp/dashboard/users
the asset and other url don't work as they become localhost:3000/dashboard/assets/<assetfile>
or mydomain.com/myapp/dashboard/assets/<assetfile>
which is not found.Is there anything I'm missing? Here's the config I'm using:
export default defineConfig({
base: "/remix/", // or base: "",
...
other configs
});
Remix version : 2.8.1
Vite version : 5.0.1
I've tried using domain as base, edit the build.assetsDir
but nothing work.
There's a temporary working solution like setting the path for Kong as /
so when I visit mydomain.com
it points to Remix deployed at 10.20.30.40:3000
, with base as /remix/
everything works fine visiting myadomain.com/remix/*
but that means mydomain.com
is explicitly used by my Remix app even with no index page at its root /
(got 404 when visiting mydomain.com), which also interferes with other apps mapped to mydomain.com
.
Target I want to achieve is like below,
mydomain.com
-> empty map or other app
mydomain.com/app1
-> 10.20.30.40:3000
mydomain.com/app2
-> 10.20.30.50:3000
If I use current temporary solution, it will be like:
mydomain.com/
-> 10.20.30.40:3000 -> base /remix/
mydomain.com/
-> 10.20.30.50:3000 -> base /others/
Visiting mydomain.com/remix/
points me to app1
, visiting mydomain.com/others
points me to app2
.
But when I visit mydomain.com
only, Kong Gateway confused which of index / root to serve (app1
or app2
).
Remix allows you to mount your app on a different path than /
. You specify this in the remix()
plugin.
https://remix.run/docs/en/main/file-conventions/vite-config#basename
However, it still assumes the server still serves files from the root, so the default assets are served from /assets
.
You change this via the base
Vite config. This should only apply to production, not the Vite dev server.
https://vitejs.dev/config/shared-options.html#base
Here's the updated config that should serve your app correctly.
import { vitePlugin as remix } from "@remix-run/dev";
import { installGlobals } from "@remix-run/node";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
installGlobals();
export default defineConfig({
server: {
port: 3000,
},
// set the base for assets to /remix/ in production
base: process.env.NODE_ENV === "production" ? "/remix/" : undefined,
plugins: [
remix({
basename: "/remix",
}),
tsconfigPaths(),
],
});
Here is the nginx.conf file I used:
server {
listen 8000;
location /remix {
proxy_pass http://host.docker.internal:3000/remix;
}
location / {
proxy_pass http://host.docker.internal:3001/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}