yufan.me ships a self-contained Docker image built on Node 25 Alpine. A two-stage build compiles the React Router application and assembles a lean runtime image that includes only production dependencies, the compiledDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/syhily/yufan.me/llms.txt
Use this file to discover all available pages before exploring further.
build/ output, and the Drizzle migration files. No separate asset upload step is required — generated Vite assets are bundled directly into the image.
Dockerfile
The full Dockerfile is included in the repository root:Dockerfile
build stage runs npm run build (react-router build). The runtime stage copies only the compiled output and the drizzle/ migration directory — leaving dev dependencies and source files behind. The postgresql-client package is included so migration tooling can connect to Postgres from within the container.
Deployment steps
Build the image
Run the following command from the repository root. BuildKit is recommended for cache-mount support:The build stage runs
react-router build and produces build/server/index.js (the Hono/Node entry point) and static assets under build/client/.Prepare environment variables
Create a Optional variables:
.env file with the required variables before starting the container. Three variables are mandatory:.env
.env
Apply database migrations
The This executes against the
drizzle/ directory is copied into the runtime image. Migrations must be applied against your Postgres database before the server starts for the first time, and again after any upgrade that adds new migration files.Run migrations from within a temporary container using drizzle-kit migrate:DATABASE_URL in your .env file. See Database setup and migrations for a detailed breakdown of each migration.Start the container
Pass your The server starts with
.env file and map the application port:npm run start which runs node ./build/server/index.js. On first boot, every request redirects to /admin/setup until an admin account is created. Stage 2 at /admin/setup/settings then seeds the 14 settings rows atomically.The default listen port is
4321. Override it by setting PORT in your environment. The HOST variable defaults to 0.0.0.0, which is required for the container to accept external connections.Docker Compose example
The followingdocker-compose.yml starts yufan.me together with Postgres and Redis. Adjust credentials and volume paths for your environment.
docker-compose.yml
The
pgvector/pgvector:pg17 image includes the pgvector extension pre-installed, which enables embedding-based search. Using a standard postgres:17 image works but falls back to SQL LIKE search. See Database setup and migrations for details.