How deployment works
Kalenuxer deployment is a three-step process. After the build pipeline writes output to dist/release/, a sync script copies the output into the API project directory, and then a deploy script uploads the result to the production server over SSH and SCP.
All deploy operations are performed by the scripts in the api/ directory. No git push or CI/CD pipeline is involved.
git push to deploy. Changes are deployed exclusively through deploy.cjs. Using git push will not update the production server. Deploy steps
Build
Run the Kalenuxer build from the repository root. Use the -unsafe flag if you do not have FTP configured locally.
node run.js <site> prepare release -unsafe
Sync
Copy the built output from dist/release/ into the API project directory. Run from inside the api/ directory.
node sync-dist.js
Deploy
Upload to the production server. Choose the deploy mode that matches what changed. Run from inside the api/ directory.
node deploy.cjs <mode>
The three deploy modes
The deploy script accepts one of three mode arguments. Each mode determines which assets are uploaded and whether the Docker containers are restarted on the server.
| Mode | What it does | Use when |
|---|---|---|
frontend | Uploads CSS, JS, and HTML files only. No container restart. | Only templates, styles, or scripts changed. Fastest deploy. |
api | Rebuilds the Go binary, transfers it, and restarts Docker containers. | Go source code changed but frontend assets did not. |
full | Rebuilds the Go binary, uploads dist output, and performs a full Docker rebuild. | First deploy, major changes, or both frontend and API changed. |
node deploy.cjs frontend # CSS/JS/HTML only, no restartnode deploy.cjs api # Go binary rebuild + Docker restartnode deploy.cjs full # Everything: binary + dist + Docker rebuild
SSH key setup
The deploy script connects to the production server using SSH key authentication. The key must be placed at a path the script expects. By convention, the key is named after the site:
~/.ssh/<site-name>_key
$env:USERPROFILE\.ssh\<site-name>_key
$env:USERPROFILE\.ssh\ to reference the SSH directory in PowerShell. The tilde shorthand ~/.ssh/ may not resolve correctly in all PowerShell contexts. The key must have the correct permissions. On Linux and macOS, run chmod 600 ~/.ssh/<site-name>_key to restrict access to the owner only. SSH will refuse to use the key if permissions are too open.
Forcing a rebuild before deploy
If you want to guarantee all CSS or JS files are freshly rebuilt before a deploy — for example after a configuration change that does not touch source files — write an empty JSON object to the relevant timestamp file before running the build:
echo {} > store/times/release/css.jsonecho {} > store/times/release/js.jsonnode run.js <site> prepare release -unsafeThen run the sync and deploy steps as normal. This ensures that whatever you upload was produced from a complete build of all current source files.
Environment variables
The .env file in the api/ directory controls server-side configuration. It is read by the deploy script and by the Go API server at runtime:
| Variable group | Controls |
|---|---|
| Database | PostgreSQL connection string, database name, user, password, host, port. |
| CORS origins | Allowed origin domains for cross-origin requests to the API. |
| Email config | SMTP host, port, sender address, and credentials for transactional email. |
| Redis | Redis connection URL used for session and cache storage. |
.env file to version control. It contains secrets. Add it to .gitignore and manage it out-of-band.