How Should a Djebel App's .gitignore Look?
A Djebel site's repo should hold two things: code and content. Everything the app writes at runtime - logs, caches, counters, subscriber lists - belongs to the machine it runs on, not to the repo.
We went through the .gitignore of every Djebel site we run and compiled the result. The pattern is consistent, and the few places where a site missed a line are exactly where the risk was.
In a Djebel app all of that runtime state lives under .ht_djebel/, which makes the file short.
The Baseline: Logs and Caches
Every site carries these:
*.log
.ht_djebel/logs/
.ht_djebel/cache/
Logs and caches are regenerated and per-environment - a dev box's copy never matches live's, so there is nothing in them worth reviewing in a diff.
The Line That Protects Your Users
.ht_djebel/data/
This is the one line you do not want to learn about the hard way. .ht_djebel/data/ is where plugins keep their private runtime data: newsletter subscriber CSVs, contact form logs, download counters, plugin caches.
That is real user data. On a site missing this line, nothing is committed today - but one routine git add -A would publish real email addresses into the repo. We found exactly one of our sites in that state during the audit, and the fix was this single line.
Ignore the whole directory by default. The rare exception gets a deliberate re-include (see below), not a hole in the default.
Secrets: the .env Family
Djebel loads <conf>/.env (or .env_<env>, which fully replaces it) and putenv()s every value - that is how deploy secrets and API keys reach your plugins. Anyone with that file has your credentials, so it never travels in the repo; it is placed on each machine by hand.
.env*
One pattern covers the whole family: the base .env, the per-environment variants (.env_live, .env_dev), and any timestamped backup that keeps the prefix (.env.old.<ts>).
It is deliberately unanchored - no leading path. In .gitignore, a pattern without a slash matches in every directory, so this catches the file in .ht_djebel/conf/ where Djebel reads it, and a stray copy that somehow lands in the doc root or anywhere else. Djebel only loads it from <conf>/, but the stray copy is exactly the accident worth guarding against.
Two caveats, both from practice:
- Keep backups named under the
.envprefix. A rotation copy renamed to something likezzz_env.old.<ts>no longer starts with.env, escapes the pattern, and would land in the repo in plaintext - if you must name one that way, give it its own rule. - If you deliberately ship a template like
.env.example(with placeholder values, never real ones), re-include it with!.env.example.
Note that app.ini is not in this list - site config belongs in the repo. Only the secret-carrying env files stay out.
Tooling Noise
Editor, OS, and test-runner droppings round it out:
# OS noise
.DS_Store
Thumbs.db
# IDE / editor
.idea/
.vscode/
*.swp
*.swo
*~
# Test runner / tooling
.phpunit.cache/
.phpunit.result.cache
One note on .vscode/: some teams commit shared editor settings on purpose. If yours does, drop that line - the default here is to keep per-developer noise out.
The Full File
# Logs - regenerated, per-environment
*.log
.ht_djebel/logs/
# Caches - rebuilt on the next request
.ht_djebel/cache/
# Private runtime data - subscriber CSVs, contact logs, download counters,
# plugin caches. One `git add -A` without this line can publish real
# email addresses into the repo.
.ht_djebel/data/
# Secrets - Djebel loads <conf>/.env (or .env_<env>) and putenv()s every
# value. Unanchored on purpose: matches a .env anywhere, including a stray
# copy in the doc root. Also catches .env.old.<ts> rotation backups -
# keep backups named under the .env prefix so they stay covered.
.env*
# OS noise
.DS_Store
Thumbs.db
# IDE / editor
.idea/
.vscode/
*.swp
*.swo
*~
# Test runner / tooling
.phpunit.cache/
.phpunit.result.cache
Prefer to grab it as a file? Download djebel-app-gitignore.txt and save it as .gitignore in your site root.
When You Do Commit Runtime Data
One of our sites deliberately version-controls part of its runtime data: release binaries served for download, stored in git-LFS and deployed by the server's git pull. That flips the default - ignore everything under .ht_djebel/data/, then re-include the pieces you mean to keep:
.ht_djebel/data/**
!.ht_djebel/data/**/
!.ht_djebel/data/**/.gitkeep
!.ht_djebel/data/**/.gitattributes
The !.ht_djebel/data/**/ line matters: git must re-include a directory before it can re-include a file inside it. Without it, git never descends far enough to see the negations below.
Keep this pattern for the deliberate case only. The default stays "ignore the whole directory."
Your Next Step
Audit your own app. git ls-files .ht_djebel/ shows what is already tracked - anything under data/, logs/, cache/, or a .env there deserves a hard look. Remember that adding a line to .gitignore does not untrack an already-committed file; that takes git rm --cached <file> plus a commit.
Two minutes now beats explaining a leaked subscriber list later.