Deployment
On your computer the application runs through node ace serve: TypeScript is compiled on the fly, and Vite serves the sources. On a server you do not do that — there you run JavaScript built in advance. The build turns the project into a build/ folder that plain Node.js can run.
Building
node ace buildThe command compiles TypeScript to JavaScript, bundles styles and scripts with Vite and copies everything needed into build/:
build/
├── app/ config/ start/ compiled code
├── bin/server.js the entry point
├── public/assets/ bundled CSS and JS
├── resources/views/ Edge templates
├── package.json
└── package-lock.jsonThe build does not copy node_modules or the .env file.
Running on the server
Copy the build/ folder to the server and run in it:
cd build
npm ci --omit=dev
node bin/server.jsnpm ci --omit=dev installs only the runtime dependencies, without development tools. After the third command the server listens on the port from the PORT variable.
Environment variables
On the server create .env next to bin/server.js or set the variables through your hosting:
NODE_ENV=production
PORT=3333
HOST=0.0.0.0
APP_KEY=another-long-random-key
LOG_LEVEL=info
SESSION_DRIVER=cookie
DB_HOST=127.0.0.1
DB_USER=blog
DB_PASSWORD=secret
DB_DATABASE=blogHOST=0.0.0.0 opens the server to outside connections, not only localhost. The server needs its own, permanent APP_KEY: if you change it, all users are logged out.
Migrations
Before the first start and after each update, apply the migrations:
node ace migration:run --forceThe --force flag is needed because in production mode Ace refuses to change the database by default — a guard against an accidental run.
The process must keep running
If you close the terminal, node bin/server.js stops. To keep the server running and restart it after crashes, use a process manager such as PM2:
npm install -g pm2
pm2 start bin/server.js --name blogUsually Nginx sits in front of Node.js: it accepts requests on ports 80 and 443, handles HTTPS and passes them to the application on port 3333.
Update steps
- On your computer:
node ace build. - Copy
build/to the server. - On the server:
npm ci --omit=dev. node ace migration:run --force.pm2 restart blog.
Common mistake
Uploaded files and the SQLite database live inside the folder that gets replaced on update — and after a deploy the post covers are gone. Keep storage/ and the database file outside the build folder (set a full path in the settings), or use PostgreSQL and a cloud Drive service.