Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ DATABASE_URL=postgres://myapp_dev:secret@localhost:5432/myapp_dev?sslmode=disabl
DEBUG=1
CSRF_TRUSTED_ORIGINS=http://localhost:8000
AUTH_USER_MODEL=myapp_user.User
# Must be unique per project on the same machine to avoid Docker container name collisions.
COMPOSE_PROJECT_NAME=myapp
70 changes: 70 additions & 0 deletions BACKGROUND.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Background

This document describes the evolution of `labzero-project` — how it started and why it ended up in its current form.

## Phase 1: Cookiecutter Template

The project originally started as a [Cookiecutter](https://cookiecutter.readthedocs.io/) template. Cookiecutter allows you to generate a project from a template by answering a few prompts, substituting variables throughout the generated files.

**Problems with this approach:**

- Maintaining a template is cumbersome — every change to the template requires a rebuild and re-testing of the generated output.
- Once a project is generated, it is permanently disconnected from the template. There is no way to receive future improvements or fixes.
- It adds a dependency on Cookiecutter itself, which users must install before they can get started.

## Phase 2: `rename.sh` Bash Script

To remove the Cookiecutter dependency, the project switched to a simpler approach: a plain bash script (`rename.sh`) that renames all key files and strings from the default project name (`myapp`) to whatever the user chooses.

**Improvements:**

- No external dependencies — just bash.

**Problems that remained:**

- The fundamental discontinuation problem was still there. Once the user ran `rename.sh`, the project diverged from the upstream template and could never receive updates.

## Phase 3: Git Submodules for Shared Features

As a workaround for the discontinuation problem, reusable features were extracted into separate applications:

- **[labzero](https://github.com/lalokalabs/labzero)** — core shared logic (admin dashboard, authentication, user management, etc.)
- **[django-umin](https://github.com/k4ml/django-umin)** — frontend asset integration with Vite

Both are included in `labzero-project` as git submodules under `ext-src/`. This allowed the shared code to evolve independently and be pulled in as updates.

**Problems that remained:**

- Some project-level files — `docker-compose.yml`, `Procfile`, `AGENTS.md`, deployment configs, etc. — still had to live directly in `labzero-project`.
- Any changes to those files in the upstream template were still lost once a user forked or cloned the project.
- The submodule model added friction: users had to understand and manage submodules.

## Phase 4: The Drupal Model (Current Direction)

The solution draws inspiration from how [Drupal](https://www.drupal.org/) was used in the early days of web development: you would check out Drupal core as your project, and build your own features as extensions (modules, themes) in sub-directories. Because you rarely touched Drupal core files, you could still run `git pull` to receive Drupal updates.

**The new approach for `labzero-project`:**

- Users **`git clone`** (or fork) `labzero-project` directly. They get a fully working project out of the box: admin dashboard, authentication, user management, frontend tooling, Docker setup, and more.
- The labzero core application lives in `src/labzero/`.
- Users add their own application code alongside it, e.g. `src/myapp/`, without touching the labzero core files.
- Because user code lives in its own directory and labzero core is rarely modified, users can periodically **`git pull`** (or sync their fork) from the upstream `labzero-project` to receive improvements, security fixes, and new features — just like pulling from Drupal core.

**Benefits:**

- No extra tooling required — just `git`.
- Continuous updates: user projects can stay in sync with the upstream template for the lifetime of the project.
- Clear separation between framework code (`src/labzero/`) and application code (`src/myapp/`).
- The full project structure — Docker Compose, Procfile, deployment configs, CI configuration — can also evolve upstream and be merged into user projects.

## Known Issue: Docker Container Name Collisions

Because multiple projects can be based on the same `labzero-project` template on the same developer machine, they would all share the same Docker container names if those names were hard-coded (e.g. `container_name: myapp_db`). Docker containers with the same name are reused, meaning data from different projects would end up in the same database container.

**Resolution:**

- All explicit `container_name:` directives have been removed from `docker-compose.yml`.
- The Docker Compose project name is now set via `name: ${COMPOSE_PROJECT_NAME:-myapp}` in `docker-compose.yml`, falling back to `myapp` if the variable is not set.
- `COMPOSE_PROJECT_NAME=myapp` is added to `.env.example`. Docker Compose reads this variable automatically from `.env`. After copying `.env.example` to `.env`, users set this to a name unique to their project (e.g., `COMPOSE_PROJECT_NAME=shopify`), giving each project its own container namespace (e.g., `shopify-db-1`, `shopify-redis-1`).

This ensures that each project on the same machine gets its own isolated set of Docker containers and data volumes.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ This is very opinionate Django project structure that we use at lalokalabs. It i
```
git submodule update --init --recursive
cp .env.example .env
```

Edit `.env` and set `COMPOSE_PROJECT_NAME` to a name unique to this project on your machine (e.g. `shopify`). This prevents Docker container name collisions when running multiple projects based on `labzero-project` on the same machine.

```
make up
```

Expand All @@ -33,9 +38,6 @@ make dev
make run
```

**IMPORTANT**
Run `./rename.sh myapp yourappname` before running your first `make dev` as that will run initial django migrations and `AUTH_USER_MODEL` is set by default to `myapp_user.User`. You should change it to your own custom user models.

Login to the dashboard at `/dashboard/` and using email `admin@myapp.co` and password `picard data`.

## Notes on Github Codespaces
Expand All @@ -50,4 +52,4 @@ Vite dev server run on different port than the django dev server and unless you
<img width="2463" height="1512" alt="Screenshot from 2025-12-06 11-16-59" src="https://github.com/user-attachments/assets/2110614c-0064-4d7e-81e7-669e7fb72edd" />

## Customize
The default project name is `myapp` and is used throughout the codebase for db name, settings and file/directory name. Run the script `rename.sh` to change this to your preferred project name.
The default project name is `myapp` and is used throughout the codebase for db name, settings and file/directory name. Add your own application code in `src/myapp/` without modifying the core `labzero` files so you can continue to pull upstream improvements.
4 changes: 1 addition & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
version: '3.7'
name: ${COMPOSE_PROJECT_NAME:-myapp}

services:
db:
image: postgres:15-alpine
container_name: myapp_db
command: >
postgres
-c log_statement=all
Expand All @@ -25,13 +25,11 @@ services:

redis:
image: redis:5.0.5
container_name: myapp_redis
ports:
- "6379:6379"

adminer:
image: adminer
container_name: myapp_adminer
command: ["php", "-S", "0.0.0.0:8081", "-t", "/var/www/html"]
links:
- "db:db"
Expand Down