Starting a new website
Every Cratly website is one GitLab repository holding three things: the content editors work on, the theme that turns it into pages, and the pipeline that builds and publishes it. The editor supplies the first. The other two come from a site template.
This page is the map; the step-by-step instructions live in the template you pick.
What a website repository contains
| Part | Files | Who owns it |
|---|---|---|
| Editorial | .cratly.config.yaml, pages/, media/ | Editors, through the Cratly editor |
| Technical | package.json, the framework's build configuration, .gitlab-ci.yml, the theme, public/ | Whoever maintains the site |
| Generated, committed | bun.lock, .cratly/sections.json | The build — regenerated on every framework upgrade |
The split matters because it decides who can create what. The editor knows the configuration spec and nothing about any theme framework, so it can write the editorial half into an empty repository — and deliberately stops there. The technical half is framework knowledge and belongs to a template.
Three ways to start
1. From a site template — the complete way
Copy a template repository into the new project and commit it. The repository is complete from its first commit: CI builds a preview the editor can read, and the deploy job is one setting away from publishing.
Available templates are listed in the template catalogue. Each one carries its own README with the steps that follow the copy: naming the site, checking the framework version, protecting the branch, activating deployment.
2. As a GitLab project template — the same thing, without the copying
If your templates live in a group that is registered under Settings → General → Custom project templates, new projects in that group can be created from Create from template → Group and start out as working websites. Same content as (1); GitLab does the copying.
3. Empty repository plus the editor — content first, theme later
Point the editor at a repository without commits and it offers to set it up — either from one of the templates above, or with the editorial half alone: a single commit containing .cratly.config.yaml, a start page, and the media folder.
Either way the editor lists every file before it writes anything, and writes all of them in one commit.
The editorial half alone is the right way in when the design is not decided yet, or when the site will be built with a framework no template covers. Authors can write pages immediately. Nothing is published until someone adds the technical half, because there is no build.
The repository exists — it is not configured yet
A first commit makes the repository editable. It does not make the website visible: that takes two settings in GitLab which no template and no editor can make for you, because both require permissions an editor does not have.
1. Protect the published branch
Drafts are branches and publishing is a merge — that is the editor's review workflow, not a preference. Editors must not be able to push into the published branch directly. The editor's repository check verifies this and names what is missing.
2. Switch deployment on and give it its secrets
A template ships its deploy job disabled, because a job that deploys the moment it exists would either fail or publish somewhere nobody chose. Switching it on takes two things — the job, and the secrets it needs:
- Enable the job. In
.gitlab-ci.yml, change thedeployjob fromwhen: nevertowhen: on_success. - Add its variables under Settings → CI/CD → Variables, each marked protected so they are never exposed to an unprotected branch.
Which variables exist depends on the template's pipeline, and the template's README is the authority. scavold-plain expects these four:
| Variable | Type | Value |
|---|---|---|
SSH_PRIVATE_KEY | File | private key of a deploy key the target server accepts, pasted as it is |
DEPLOY_HOST | Variable | hostname or IP of the target server |
DEPLOY_USER | Variable | SSH user on that server |
DEPLOY_PATH | Variable | absolute path to publish into, e.g. /var/www/example-site |
Generate the key pair, put the public half where the target server accepts it, and paste the private half into the variable — no encoding:
ssh-keygen -t ed25519 -C "gitlab-ci-example-site"Why type File for the key. GitLab saves a file variable's value to a temporary file and gives the job that file's path. The key is therefore never a value in the job's environment, so it cannot leak through a stray env in a debugging step — and nothing depends on masking, which a key could not satisfy anyway: masking requires a single line without whitespace, and a private key is neither.
Until both steps are done, pipelines run green and publish nothing. That is the expected state of a repository that was just created — not a fault to hunt for.
What the editor shows in the meantime
Editors can write immediately, and the preview works from the pipeline's build artifact. It is bound to a draft: the preview belongs to the merge request of a draft branch, so directly after setup — on the published branch, with no draft open — there is nothing to preview yet, even though the pipeline built an artifact. Create a draft and it appears.
Next: connect the editor to the repository.