Skip to main content

Example: Deploy Profiles (build & ship a release)

The reference apps don't just run in a task — every combination also ships a ready-to-run deploy profile, so you can see CoderFlow's Deployment Profiles feature end to end without authoring one. A deployment profile is a named, parameterized release action that runs in its own container (built from the environment's image, with the repo cloned in) — separate from the dev task that serves the live preview.

This page walks through running the bundled profile and explains what it does — and, just as importantly, what it deliberately does not do. For the full feature reference (every field, secrets, automations, run surfaces), see Deployment Profiles.

What you'll need

  • A reference environment imported and built — any combination works. The two-process Node.js + React is a good first one because Node is already in the base image, so the deploy container is quick to build.
  • Nothing else. The bundled profile is credential-free: it references no secrets, so it runs out of the box.

The bundled profile

Each combination carries a deploy profile next to its environment.json:

node-react/
environment.json # has "deployment_profile_order": ["deploy"]
deployment-profiles/
deploy.json # the profile definition + parameters
deploy.sh # the script that runs in the deploy container

Because the git import copies the whole combination folder into your environment, the profile travels with it — there's nothing to wire up. It appears on the environment's Deploy tab and in the task dashboard's Deploy menu.

The definition is the same for every combination — three parameters:

ParameterTypeDefaultPurpose
TARGETselect (qa / production)qaWhich environment this release is for. In a real setup each target has its own host and credentials.
DRY_RUNbooleanonWhen on, build the release but skip the upload step.
RELEASE_NOTEStextareaOptional notes recorded into the release bundle.

deployment_profile_order in environment.json lists the profile so it sorts ahead of any alphabetical fallback (see Ordering Profiles).


What it does (and doesn't)

The script does two things:

  1. Builds a genuine, deployable release artifact from the cloned source — the front end's static build plus the API's per-stack artifact — and assembles them into a release.tgz.
  2. Prints the command that would ship it, instead of pushing.
The ship step is a labeled placeholder, on purpose

A reference app is a hello-world: it has no real QA or production host, and no credentials to push with. So the profile builds something real (you get a true release bundle and build log), but the upload is a clearly-marked placeholder rather than a fake "deployed!" message. Making it a real deploy is a small, explicit change — see Make it a real deploy.

The artifact differs by stack, but the profile and its parameters are identical across the grid:

StackAPI artifact the script buildsFront end
Node.jsindex.js + production node_modules (npm ci --omit=dev)static build → web/dist
.NETdotnet publish -c Release outputstatic build → web/dist
Javathe Spring Boot executable jar (mvn package)static build → web/dist
Pythonsource + vendored dependencies (pip install … -t vendor)static build → web/dist
PHPthe PHP source (runs as-is)static build → web/dist
staticthe site's own files
php-htmlthe PHP source (single-origin)

Run it

  1. Import the reference combination if you haven't, and build it — the deploy container is built from the environment's image, so the environment must build first. (Already imported this combination earlier? Import it again under a different name: the importer never overwrites, so a fresh copy is how the profile reaches an existing setup.)

  2. Open the environment's Deploy tab (or the task dashboard's Deploy menu), choose deploy, and you'll get the parameter dialog: the Target dropdown, the Dry run toggle (on by default), and Release notes.

  3. Leave Dry run on and start it. The streamed log shows the front-end build, the API build/package, the assembled release.tgz, and the placeholder upload command — without shipping anything.

The run appears in the task list, streams output, and records status like any other task. The environment Deploy tab also keeps a per-profile history and supports a dry run — see Running Profiles.

The compiled stacks build more than Node

dotnet publish, mvn package, and the Angular build pull dependencies and take longer than the Node combinations. The first run also installs them over the network. That's expected; subsequent steps are faster.


Make it a real deploy

The script ends with the exact block to replace. It's a placeholder only because there's no host configured:

# Ship release.tgz to the target host over SSH. Provide DEPLOY_HOST, DEPLOY_USER,
# and an SSH key as environment Secrets (available_for: ["deploy"]), then
# replace this block with:
#
# scp release.tgz "${DEPLOY_USER}@${DEPLOY_HOST}:/var/www/app/"
# ssh "${DEPLOY_USER}@${DEPLOY_HOST}" \
# 'cd /var/www/app && tar -xzf release.tgz && systemctl restart app'

To turn it into a real deploy:

  1. On the environment's Secrets tab, add the host and an SSH key (or token), and include Deploy in Available For so they're injected into the deploy container. See Secrets.
  2. Reference them from deploy.json's secrets array.
  3. Replace the marked block in deploy.sh with the real upload, gated on DRY_RUN so a dry run still just builds.
  4. Commit and push the setup repo change.

For separate QA and production paths, you can either keep the single profile and branch on TARGET, or split it into named qa and production profiles (see Where Profiles Live).


Notes

  • The reference profile references no secrets — that's why it runs immediately. A real one almost always will; keep secret values out of the JSON and on the Secrets tab.
  • The bundle isn't stored anywhere. This is a demonstration: the value is the build and the log, not a retained artifact. A real profile uploads or publishes the bundle in its ship step.
  • It's regenerated, not hand-edited. The reference repo builds these profiles from a generator, so all combinations stay in sync. Edit your imported copy freely.