What actually happens when you press Deploy
A step-by-step walk through a Kernel6 deployment — from the button to a live HTTPS address — using the exact lines you see in the build log.
A deploy button that hides everything is comfortable right up until something fails. Then you are staring at a red badge with no idea which of a dozen steps went wrong. So here is every step a Kernel6 deployment takes, in order, with the line it writes to your build log. Nothing here is simplified for the post: these are the steps the deployer runs.
1. Queued, then connected
Pressing Deploy creates a deployment record and marks the project as deploying. The log starts with ==> Deployment queued. The platform then opens an SSH session to the server your project lives on and logs ==> Connecting to ec2-user@….
Next it works out how much memory your app may use: half of the server, never less than 512 MB. On a 4 GB server that is 2,048 MB. You will see it as ==> Memory limit for this app: 2048 MB. If your app ever grows past that, the process manager restarts it rather than letting it take the whole machine down.
2. Getting your code
The first deploy clones your repository at the branch you chose: ==> Cloning https://github.com/you/site (branch: main). Every deploy after that fetches the branch and resets to it exactly — ==> Pulling latest main — so the server always matches what is on GitHub, with no leftover local edits.
If your site lives in a subfolder of a monorepo, set a root directory in Build settings and the deployer moves into it before doing anything else: ==> Using root directory /apps/web.
3. Your environment
If the project has environment variables, they are decrypted only at this moment, written to a .env file readable only by the app user, and exported into the environment the app starts with: ==> Writing 4 environment variable(s) to .env. They are never part of the script text itself — values travel encoded, so a quote or a dollar sign in a password cannot break or alter the deploy.
4. Stopping the old version
This is the step worth knowing about. Before installing and building, the deployer stops the running version of your app and frees its port. That keeps the server from running two copies side by side on a small machine — but it also means your site is offline while the new version installs and builds, and if the build fails, it stays offline until a deploy succeeds.
In practice: run npm run build locally before you deploy. A build that passes on your laptop almost always passes on the server, and it turns a failed deploy into a non-event.
5. Install, build, start
With a package.json, the deployer runs npm install (==> Installing dependencies), then npm run build if you have a build script (==> Running build). Each of these can be replaced in Build settings — for pnpm, yarn, or anything custom — and the log shows your command instead.
Builds run inside a resource ceiling where the server supports it: capped memory and at most 70% of the CPU. A runaway install would otherwise starve every other site on the server, including your own.
Then the app starts under pm2 with a PORT variable it must listen on: npm start if you have a start script, otherwise the main file from package.json. A repository with no package.json at all is served as a static site. Every case is spelled out in the log, for example ==> Starting app with pm2 (npm start) on port 4001.
6. Proving it actually started
A process that launched is not the same as an app that works. So the deployer asks the app for a page, every five seconds, for up to a minute: ==> Waiting for app to accept connections on port 4001. Any HTTP response counts — an API with no home page answers 404, and that is still a running app. If nothing answers in a minute, the deploy fails and the log shows the last 50 lines your app printed, which is usually the error you need.
7. Routing and the outside check
Once the app answers, the platform regenerates the web server configuration for your server so your app gets its own HTTPS address, and logs ==> Routing https://… to port 4001. The certificate is requested automatically.
Finally, the platform requests that public address from outside, the way a visitor would. Only then does it write ==> Deployment successful. If the app runs on the server but cannot be reached from the internet, the log says exactly that instead of claiming success — a green badge on a site nobody can open helps no one.
The whole log, end to end
==> Deployment queued
==> Connecting to ec2-user@203.0.113.10 (your server)
==> Memory limit for this app: 2048 MB
==> Preparing $HOME/kernel6/apps/…
==> Cloning https://github.com/you/site (branch: main)
==> Writing 4 environment variable(s) to .env
==> Installing dependencies
==> Running build
==> Starting app with pm2 (npm start) on port 4001
==> Waiting for app to accept connections on port 4001
responded with HTTP 200
==> App is up on port 4001
==> Routing https://a1b2c3d4.apps.kernel6.com to port 4001
==> Deployment successful: https://a1b2c3d4.apps.kernel6.comEvery deployment keeps its log in your deploy history, so when something does go wrong you can compare the failing run line by line with the last one that worked.