From 76c90f82b6a0a4983b981dc5ef2be30a1a6cf7e7 Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 13:29:56 +0400 Subject: [PATCH 01/20] feat: add compose.yml (full stack, pre-built image) Signed-off-by: tdruez --- .devcontainer/demo/devcontainer.json | 2 +- docker-compose.demo.yml => compose.demo.yml | 8 +- compose.yml | 135 ++++++++++++++++++++ 3 files changed, 142 insertions(+), 3 deletions(-) rename docker-compose.demo.yml => compose.demo.yml (73%) create mode 100644 compose.yml diff --git a/.devcontainer/demo/devcontainer.json b/.devcontainer/demo/devcontainer.json index e016c8ee..fc140056 100644 --- a/.devcontainer/demo/devcontainer.json +++ b/.devcontainer/demo/devcontainer.json @@ -1,6 +1,6 @@ { "name": "DejaCode Demo (Codespaces only)", - "dockerComposeFile": "../../docker-compose.demo.yml", + "dockerComposeFile": "../../compose.demo.yml", "service": "web", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "overrideCommand": false, diff --git a/docker-compose.demo.yml b/compose.demo.yml similarity index 73% rename from docker-compose.demo.yml rename to compose.demo.yml index 6ea5fff9..c4aa6f8a 100644 --- a/docker-compose.demo.yml +++ b/compose.demo.yml @@ -1,4 +1,7 @@ -name: dejacode +name: dejacode-demo + +x-description: "Minimal demo stack: web + db only, auto-created superuser, Codespaces-ready" + services: db: image: docker.io/library/postgres:16.13 @@ -7,8 +10,9 @@ services: volumes: - ./data/postgresql:/docker-entrypoint-initdb.d/ shm_size: "1gb" + restart: always healthcheck: - test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" ] + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 diff --git a/compose.yml b/compose.yml new file mode 100644 index 00000000..ceefe5d0 --- /dev/null +++ b/compose.yml @@ -0,0 +1,135 @@ +name: dejacode + +x-description: "Full DejaCode stack: all services, pre-built image, no checkout required" + +services: + db: + image: docker.io/library/postgres:16.13 + env_file: + - docker.env + volumes: + - db_data:/var/lib/postgresql/data/ + - ./data/postgresql:/docker-entrypoint-initdb.d/ + shm_size: "1gb" + restart: always + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: docker.io/library/redis:8.6-alpine + # Enable redis data persistence using the "Append Only File" with the + # default policy of fsync every second. See https://redis.io/topics/persistence + command: redis-server --appendonly yes + volumes: + - redis_data:/data + restart: always + + web: + image: ghcr.io/aboutcode-org/dejacode:latest + command: sh -c " + ./manage.py migrate && + ./manage.py collectstatic --no-input --verbosity 0 --clear && + gunicorn dejacode.wsgi:application --bind :8000 --timeout 600 \ + --workers 4 --worker-tmp-dir /dev/shm" + env_file: + - docker.env + expose: + - 8000 + volumes: + - .env:/opt/dejacode/.env + - static:/var/dejacode/static + - media:/var/dejacode/media + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + clamav: + condition: service_started + + worker: + image: ghcr.io/aboutcode-org/dejacode:latest + # Ensure that potential db migrations run first by waiting until "web" is up + command: wait-for-it --strict --timeout=180 web:8000 -- sh -c " + ./manage.py rqworker-pool --num-workers 2 --verbosity 1" + env_file: + - docker.env + volumes: + - .env:/opt/dejacode/.env + # The media volume is required to access uploaded files from the worker + - media:/var/dejacode/media + depends_on: + - redis + - db + - web + + scheduler: + image: ghcr.io/aboutcode-org/dejacode:latest + command: wait-for-it web:8000 -- sh -c "./manage.py rqcron dje.cron_jobs" + env_file: + - docker.env + volumes: + - .env:/opt/dejacode/.env + depends_on: + - redis + - db + - web + + nginx: + image: docker.io/library/nginx:1.29-alpine + ports: + - "${NGINX_PUBLISHED_HTTP_PORT:-80}:80" + - "${NGINX_PUBLISHED_HTTPS_PORT:-443}:443" + volumes: + - static:/var/dejacode/static/ + - webroot:/var/www/html/ + configs: + - source: nginx_conf + target: /etc/nginx/conf.d/default.conf + depends_on: + - web + restart: always + + clamav: + image: docker.io/clamav/clamav:1.5_base + volumes: + - clamav_data:/var/lib/clamav + - media:/var/dejacode/media + restart: always + +volumes: + db_data: + redis_data: + clamav_data: + static: + media: + webroot: + +configs: + nginx_conf: + content: | + upstream gunicorn_app { + server web:8000; + } + server { + listen 80; + http2 on; + server_tokens off; + gzip on; + gzip_comp_level 6; + gzip_types text/css text/javascript application/javascript image/svg+xml; + location / { + proxy_pass http://gunicorn_app; + proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for; + proxy_set_header Host $$http_host; + proxy_redirect off; + client_max_body_size 1G; + proxy_read_timeout 600s; + } + location /static/ { + alias /var/dejacode/static/; + } + } From 5983a320b2bd985ccc7b4bcb57dd52d4e0fce8e0 Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 14:30:51 +0400 Subject: [PATCH 02/20] add compose dev config Signed-off-by: tdruez --- Makefile | 18 ++++++++++++-- compose.dev.yml | 58 ++++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 3 +++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 compose.dev.yml diff --git a/Makefile b/Makefile index e75699ec..7b08adc6 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,20 @@ # See https://aboutcode.org for more information about AboutCode FOSS projects. # +######################################################################################## +# Docker dev commands +######################################################################################## + +IMAGE_NAME=dejacode:dev +COMPOSE=docker compose -f compose.dev.yml +MANAGE=${COMPOSE} exec web ./manage.py + +run: + @echo "-> Run the Docker compose services in dev mode (hot reload on code changes)" + ${COMPOSE} up + +######################################################################################## + VENV_LOCATION=.venv ACTIVATE?=. ${VENV_LOCATION}/bin/activate; MANAGE=${VENV_LOCATION}/bin/python manage.py @@ -161,8 +175,8 @@ postgresdb_clean: @${SUDO_POSTGRES} dropdb ${DB_NAME} || true @${SUDO_POSTGRES} dropuser '${DB_USERNAME}' || true -run: - DJANGO_RUNSERVER_HIDE_WARNING=true ${MANAGE} runserver 8000 --insecure +# run: +# DJANGO_RUNSERVER_HIDE_WARNING=true ${MANAGE} runserver 8000 --insecure worker: ${MANAGE} rqworker diff --git a/compose.dev.yml b/compose.dev.yml new file mode 100644 index 00000000..76353a50 --- /dev/null +++ b/compose.dev.yml @@ -0,0 +1,58 @@ +name: dejacode-dev + +x-description: "Development stack — source mounted, runserver with auto-reload" + +services: + db: + image: docker.io/library/postgres:16.13 + env_file: + - docker.env + volumes: + - db_data:/var/lib/postgresql/data/ + - ./data/postgresql:/docker-entrypoint-initdb.d/ + shm_size: "1gb" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + start_interval: 1s + + web: + build: . + image: dejacode:dev + env_file: + - .env + environment: + - DATABASE_HOST=db + - DATABASE_PASSWORD=dejacode + - DEJACODE_DEBUG=True + - DEJACODE_ASYNC=False + - CLAMD_ENABLED=False + # Skip migrate when the DB schema is already up to date (faster reload) + command: sh -c " + ./manage.py migrate --check || ./manage.py migrate; + DJANGO_RUNSERVER_HIDE_WARNING=true ./manage.py runserver --skip-checks 0.0.0.0:8000" + ports: + - "8000:8000" + volumes: + - ./component_catalog:/opt/dejacode/component_catalog + - ./dejacode:/opt/dejacode/dejacode + - ./dejacode_toolkit:/opt/dejacode/dejacode_toolkit + - ./dje:/opt/dejacode/dje + - ./license_library:/opt/dejacode/license_library + - ./notification:/opt/dejacode/notification + - ./organisation:/opt/dejacode/organisation + - ./policy:/opt/dejacode/policy + - ./product_portfolio:/opt/dejacode/product_portfolio + - ./purldb:/opt/dejacode/purldb + - ./reporting:/opt/dejacode/reporting + - ./vulnerabilities:/opt/dejacode/vulnerabilities + - ./workflow:/opt/dejacode/workflow + depends_on: + db: + condition: service_healthy + +volumes: + db_data: diff --git a/docker-compose.yml b/docker-compose.yml index 1a5b033d..a0fb3beb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,7 @@ name: dejacode + +x-description: "Legacy file — kept for backward compatibility, use compose.yml instead" + services: db: image: docker.io/library/postgres:16.13 From 722970379a941d03909e3b569c00dfaedfe1f407 Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 14:41:34 +0400 Subject: [PATCH 03/20] add a production compose config Signed-off-by: tdruez --- compose.prod.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 compose.prod.yml diff --git a/compose.prod.yml b/compose.prod.yml new file mode 100644 index 00000000..9c24d504 --- /dev/null +++ b/compose.prod.yml @@ -0,0 +1,27 @@ +name: dejacode + +x-description: "Production overrides — external config bind mounts for prod/staging deployments" + +services: + web: + build: . + image: dejacode:prod + volumes: + - /etc/dejacode/:/etc/dejacode/ + + worker: + build: . + image: dejacode:prod + volumes: + - /etc/dejacode/:/etc/dejacode/ + + scheduler: + build: . + image: dejacode:prod + volumes: + - /etc/dejacode/:/etc/dejacode/ + + nginx: + configs: [] + volumes: + - ./etc/nginx/conf.d/:/etc/nginx/conf.d/ From 4470224cf5daff686f68b3f791d497f31eac3efa Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 17:39:04 +0400 Subject: [PATCH 04/20] adapt Makefile Signed-off-by: tdruez --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 7b08adc6..46f3b4fe 100644 --- a/Makefile +++ b/Makefile @@ -18,11 +18,14 @@ run: @echo "-> Run the Docker compose services in dev mode (hot reload on code changes)" ${COMPOSE} up +superuser: + ${MANAGE} createsuperuser + ######################################################################################## VENV_LOCATION=.venv ACTIVATE?=. ${VENV_LOCATION}/bin/activate; -MANAGE=${VENV_LOCATION}/bin/python manage.py +#MANAGE=${VENV_LOCATION}/bin/python manage.py # Do not depend on Python to generate the SECRET_KEY GET_SECRET_KEY=`head -c50 /dev/urandom | base64 | head -c50` # Customize with `$ make envfile ENV_FILE=/etc/dejacode/.env` @@ -208,7 +211,4 @@ psql: log: ${DOCKER_COMPOSE} logs --tail="100" ${SERVICE} -createsuperuser: - ${DOCKER_EXEC} web ./manage.py createsuperuser - -.PHONY: virtualenv conf dev lock upgrade envfile envfile_dev check outdated doc8 valid check-deploy clean initdb postgresdb postgresdb_clean migrate run test docs build psql bash shell log createsuperuser +.PHONY: virtualenv conf dev lock upgrade envfile envfile_dev check outdated doc8 valid check-deploy clean initdb postgresdb postgresdb_clean migrate run test docs build psql bash shell log superuser From 7fdced80c33fab7b663d986eb8fab4a7e060914f Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 17:41:57 +0400 Subject: [PATCH 05/20] add install script Signed-off-by: tdruez --- install.sh | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..b88f23cb --- /dev/null +++ b/install.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# DejaCode installer — no root required, works on macOS and Linux. +# Usage: curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files/install.sh | bash +set -euo pipefail + +REPO="https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files" +INSTALL_DIR="${DEJACODE_HOME:-$HOME/dejacode}" +BIN_DIR="$HOME/.local/bin" +WRAPPER="$BIN_DIR/dejacode" + +# ── Output helpers ──────────────────────────────────────────────────────────── +BOLD='\033[1m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; RED='\033[0;31m'; NC='\033[0m' +info() { echo -e "${BLUE}→${NC} $1"; } +success() { echo -e "${GREEN}✓${NC} $1"; } +die() { echo -e "${RED}✗${NC} $1" >&2; exit 1; } + +# ── Prerequisites ───────────────────────────────────────────────────────────── +command -v docker &>/dev/null || die "Docker is required. See https://docs.docker.com/get-docker/" +docker info &>/dev/null || die "Docker daemon is not running. Please start Docker first." +command -v curl &>/dev/null || die "curl is required." + +# ── Installation directory ──────────────────────────────────────────────────── +info "Installing DejaCode in ${BOLD}$INSTALL_DIR${NC}" +mkdir -p "$INSTALL_DIR/data/postgresql" +cd "$INSTALL_DIR" + +# ── Download files ──────────────────────────────────────────────────────────── +info "Downloading compose.yml" +curl -sSL "$REPO/compose.yml" -o compose.yml + +info "Downloading database seed data" +curl -sSL "$REPO/data/postgresql/initdb.sql.gz" -o data/postgresql/initdb.sql.gz + +info "Downloading environment template" +curl -sSL "$REPO/.env.run" -o .env.run + +# ── Generate docker.env with a secure secret key ────────────────────────────── +info "Generating secret key" +SECRET_KEY=$(LC_ALL=C tr -dc 'A-Za-z0-9!@#%^&*(-_=+)' < /dev/urandom | head -c 50) +sed "s|^SECRET_KEY=.*|SECRET_KEY=$SECRET_KEY|" .env.run > docker.env +rm .env.run + +# ── Install wrapper command ─────────────────────────────────────────────────── +info "Installing dejacode command to $WRAPPER" +mkdir -p "$BIN_DIR" +curl -sSL "$REPO/bin/dejacode" -o "$WRAPPER" +# Hardcode install dir into the wrapper +sed -i.bak "s|^INSTALL_DIR=.*|INSTALL_DIR=\"$INSTALL_DIR\"|" "$WRAPPER" && rm "$WRAPPER.bak" +chmod +x "$WRAPPER" + +# ── Add ~/.local/bin to PATH if needed ─────────────────────────────────────── +add_to_path() { + local rc="$1" + [ -f "$rc" ] || return + grep -q '\.local/bin' "$rc" && return + echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$rc" + info "Added ~/.local/bin to PATH in $rc" +} + +if [[ "$OSTYPE" == "darwin"* ]]; then + add_to_path "$HOME/.zshrc" +else + add_to_path "$HOME/.bashrc" + add_to_path "$HOME/.profile" +fi + +# ── Start services ──────────────────────────────────────────────────────────── +info "Starting DejaCode" +docker compose up -d + +# ── Wait for web to respond ─────────────────────────────────────────────────── +info "Waiting for DejaCode to be ready" +RETRIES=40 +until curl -fsS --max-time 5 http://localhost/ -o /dev/null 2>&1; do + RETRIES=$((RETRIES - 1)) + [ $RETRIES -eq 0 ] && die "Timed out waiting for DejaCode to start. Run: dejacode logs" + echo -n "." + sleep 3 +done +echo "" + +# ── Done ────────────────────────────────────────────────────────────────────── +success "DejaCode is running at ${BOLD}http://localhost${NC}" +echo "" +echo " Create your admin user: dejacode createsuperuser" +echo " Stop: dejacode stop" +echo " Logs: dejacode logs" +echo "" +echo " Reload your shell or run: source ~/.zshrc (or ~/.bashrc)" From a3e39adec68fd9e14738bab98e81d0f3ca4f8697 Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 17:48:11 +0400 Subject: [PATCH 06/20] update install script Signed-off-by: tdruez --- install.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index b88f23cb..9cb16cb4 100755 --- a/install.sh +++ b/install.sh @@ -31,14 +31,15 @@ curl -sSL "$REPO/compose.yml" -o compose.yml info "Downloading database seed data" curl -sSL "$REPO/data/postgresql/initdb.sql.gz" -o data/postgresql/initdb.sql.gz -info "Downloading environment template" -curl -sSL "$REPO/.env.run" -o .env.run +info "Downloading docker.env" +curl -sSL "$REPO/docker.env" -o docker.env -# ── Generate docker.env with a secure secret key ────────────────────────────── -info "Generating secret key" +# ── Generate .env with a secure secret key ──────────────────────────────────── +info "Generating .env" SECRET_KEY=$(LC_ALL=C tr -dc 'A-Za-z0-9!@#%^&*(-_=+)' < /dev/urandom | head -c 50) -sed "s|^SECRET_KEY=.*|SECRET_KEY=$SECRET_KEY|" .env.run > docker.env -rm .env.run +cat > .env < Date: Tue, 9 Jun 2026 18:07:27 +0400 Subject: [PATCH 07/20] add documentation Signed-off-by: tdruez --- docs/installation.rst | 86 ++++++++++++++++++++++++++++++++++++++----- install.sh | 7 ++-- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 3a5e127f..782684a4 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -8,31 +8,99 @@ Welcome to the **DejaCode** installation guide! This guide explains how to insta DejaCode on various platforms. Please follow the instructions carefully for a smooth installation experience. -The **recommended DejaCode installation** method is to :ref:`run_with_docker`, which -is the easiest and ensures all features work with minimal configuration. -This installation works on all operating systems. +There are three ways to run DejaCode: -Alternatively, if you prefer, you can install DejaCode locally as a development server -with some limitations. -In this case, you may refer to the :ref:`local_development_installation` section for -more details. +- :ref:`run_with_docker` — **simplest option**, no repository checkout or build step + required. Uses the pre-built Docker image published on GitHub. +- :ref:`run_with_docker_build` — build and run from source using Docker. + Recommended for enterprise deployments. +- :ref:`local_development_installation` — for contributors to DejaCode itself. .. _run_with_docker: Run with Docker =============== +This is the simplest way to get DejaCode running. You only need **Docker** — +no repository checkout, no build step required. + 1. Get Docker ------------- -Start by downloading and **installing Docker on your platform**. -Refer to Docker's documentation for the best installation path for your system: +Download and **install Docker** on your platform: |get_docker_link|. .. |get_docker_link| raw:: html Get Docker +2. Run the installer +-------------------- + +Run the one-liner installer:: + + curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/main/install.sh | bash + +This script will: + +- Create ``~/.dejacode/`` as the installation directory +- Download ``compose.yml``, ``docker.env``, and the database seed data +- Generate ``.env`` with a secure secret key +- Install the ``dejacode`` command in ``~/.local/bin/`` +- Start all services and wait until the application is ready + +.. note:: + Override the default installation directory with: + ``DEJACODE_HOME=/path/to/dir bash install.sh`` + +3. Create an application user +------------------------------ + +:: + + dejacode createsuperuser + +Follow the prompt instructions, providing the required information: + +- **Username**: Choose a unique username. +- **Email Address**: Provide a valid email address. +- **Strong Password**: Create a password following security guidelines. + +4. Access the application +-------------------------- + +.. admonition:: Congratulations! + :class: tip + + Open a web browser and visit |localhost_link| to **access the web UI**. + + You can sign-in with the credentials you created above. + + You can move onto the Tutorials section starting with the :ref:`user_tutorial_1`. + +.. note:: + The pre-built image always corresponds to the most recent release and is tagged + ``latest``. + +.. _run_with_docker_build: + +Run with Docker — build from source +===================================== + +This method builds the Docker image locally from the DejaCode source repository. +It is the recommended approach for enterprise deployments. + +1. Get Docker +------------- + +Start by downloading and **installing Docker on your platform**. +Refer to Docker's documentation for the best installation path for your system: +|get_docker_link2|. + +.. |get_docker_link2| raw:: html + + Get Docker + 2. Build the image ------------------ diff --git a/install.sh b/install.sh index 9cb16cb4..6355e019 100755 --- a/install.sh +++ b/install.sh @@ -4,7 +4,7 @@ set -euo pipefail REPO="https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files" -INSTALL_DIR="${DEJACODE_HOME:-$HOME/dejacode}" +INSTALL_DIR="${DEJACODE_HOME:-$HOME/.dejacode}" BIN_DIR="$HOME/.local/bin" WRAPPER="$BIN_DIR/dejacode" @@ -37,9 +37,8 @@ curl -sSL "$REPO/docker.env" -o docker.env # ── Generate .env with a secure secret key ──────────────────────────────────── info "Generating .env" SECRET_KEY=$(LC_ALL=C tr -dc 'A-Za-z0-9!@#%^&*(-_=+)' < /dev/urandom | head -c 50) -cat > .env < .env # ── Install wrapper command ─────────────────────────────────────────────────── info "Installing dejacode command to $WRAPPER" From 181c5ce1ae18eb3ef2b8d870e62f504661c96ab0 Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 18:12:36 +0400 Subject: [PATCH 08/20] update script Signed-off-by: tdruez --- docs/installation.rst | 31 ++++++++++++++++++++++++++++--- install.sh | 23 ++++++++++++++++++++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 782684a4..730a4b1c 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -54,11 +54,11 @@ This script will: ``DEJACODE_HOME=/path/to/dir bash install.sh`` 3. Create an application user ------------------------------- +----------------------------- :: - dejacode createsuperuser + dejacode exec web ./manage.py createsuperuser Follow the prompt instructions, providing the required information: @@ -67,7 +67,7 @@ Follow the prompt instructions, providing the required information: - **Strong Password**: Create a password following security guidelines. 4. Access the application --------------------------- +------------------------- .. admonition:: Congratulations! :class: tip @@ -82,6 +82,31 @@ Follow the prompt instructions, providing the required information: The pre-built image always corresponds to the most recent release and is tagged ``latest``. +.. _dejacode_command: + +Managing your installation +-------------------------- + +The ``dejacode`` command is a thin wrapper around ``docker compose``. All standard +``docker compose`` subcommands work directly:: + + dejacode up -d # start all services in the background + dejacode down # stop and remove containers + dejacode restart # restart all services + dejacode ps # show service status + dejacode logs -f # follow all logs + dejacode logs -f web # follow logs for a specific service + dejacode pull # pull the latest image + dejacode exec web ./manage.py createsuperuser + +To update DejaCode to the latest release:: + + dejacode pull && dejacode up -d + +To completely remove DejaCode and all its data:: + + dejacode uninstall + .. _run_with_docker_build: Run with Docker — build from source diff --git a/install.sh b/install.sh index 6355e019..fa8c1234 100755 --- a/install.sh +++ b/install.sh @@ -43,9 +43,26 @@ printf 'SECRET_KEY=%s\nALLOWED_HOSTS=localhost\nCSRF_TRUSTED_ORIGINS=http://loca # ── Install wrapper command ─────────────────────────────────────────────────── info "Installing dejacode command to $WRAPPER" mkdir -p "$BIN_DIR" -curl -sSL "$REPO/bin/dejacode" -o "$WRAPPER" -# Hardcode install dir into the wrapper -sed -i.bak "s|^INSTALL_DIR=.*|INSTALL_DIR=\"$INSTALL_DIR\"|" "$WRAPPER" && rm "$WRAPPER.bak" +cat > "$WRAPPER" << EOF +#!/usr/bin/env bash +set -euo pipefail +INSTALL_DIR="$INSTALL_DIR" + +case "\${1:-}" in + uninstall) + printf "This will permanently delete all DejaCode data. Type 'yes' to confirm: " + read -r CONFIRM + [ "\$CONFIRM" = "yes" ] || { echo "Aborted."; exit 1; } + docker compose --project-directory "\$INSTALL_DIR" down -v --remove-orphans 2>/dev/null || true + rm -rf "\$INSTALL_DIR" + rm -f "\$0" + echo "DejaCode has been uninstalled." + ;; + *) + cd "\$INSTALL_DIR" && exec docker compose "\$@" + ;; +esac +EOF chmod +x "$WRAPPER" # ── Add ~/.local/bin to PATH if needed ─────────────────────────────────────── From a6732d295b4d9ff24cb24bc5194cdc2a8a448e78 Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 18:16:16 +0400 Subject: [PATCH 09/20] adjust script Signed-off-by: tdruez --- install.sh | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/install.sh b/install.sh index fa8c1234..7320d471 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # DejaCode installer — no root required, works on macOS and Linux. # Usage: curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files/install.sh | bash -set -euo pipefail +set -eu REPO="https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files" INSTALL_DIR="${DEJACODE_HOME:-$HOME/.dejacode}" @@ -36,33 +36,37 @@ curl -sSL "$REPO/docker.env" -o docker.env # ── Generate .env with a secure secret key ──────────────────────────────────── info "Generating .env" -SECRET_KEY=$(LC_ALL=C tr -dc 'A-Za-z0-9!@#%^&*(-_=+)' < /dev/urandom | head -c 50) +# Read enough bytes from urandom so tr has enough after filtering, then cut to 50 chars. +# Avoids SIGPIPE/pipefail issues by not reading from an infinite stream. +SECRET_KEY=$(dd if=/dev/urandom bs=512 count=1 2>/dev/null \ + | LC_ALL=C tr -dc 'A-Za-z0-9!@#%^&*(-_=+)' \ + | cut -c1-50) printf 'SECRET_KEY=%s\nALLOWED_HOSTS=localhost\nCSRF_TRUSTED_ORIGINS=http://localhost\n' \ "$SECRET_KEY" > .env # ── Install wrapper command ─────────────────────────────────────────────────── info "Installing dejacode command to $WRAPPER" mkdir -p "$BIN_DIR" -cat > "$WRAPPER" << EOF -#!/usr/bin/env bash -set -euo pipefail -INSTALL_DIR="$INSTALL_DIR" - -case "\${1:-}" in - uninstall) - printf "This will permanently delete all DejaCode data. Type 'yes' to confirm: " - read -r CONFIRM - [ "\$CONFIRM" = "yes" ] || { echo "Aborted."; exit 1; } - docker compose --project-directory "\$INSTALL_DIR" down -v --remove-orphans 2>/dev/null || true - rm -rf "\$INSTALL_DIR" - rm -f "\$0" - echo "DejaCode has been uninstalled." - ;; - *) - cd "\$INSTALL_DIR" && exec docker compose "\$@" - ;; -esac -EOF +# Write the wrapper using printf to avoid heredoc stdin conflicts when piped via curl | bash. +printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'set -eu' \ + "INSTALL_DIR=\"$INSTALL_DIR\"" \ + 'case "${1:-}" in' \ + ' uninstall)' \ + ' printf "This will permanently delete all DejaCode data. Type '\''yes'\'' to confirm: "' \ + ' read -r CONFIRM' \ + ' [ "$CONFIRM" = "yes" ] || { echo "Aborted."; exit 1; }' \ + ' docker compose --project-directory "$INSTALL_DIR" down -v --remove-orphans 2>/dev/null || true' \ + ' rm -rf "$INSTALL_DIR"' \ + ' rm -f "$0"' \ + ' echo "DejaCode has been uninstalled."' \ + ' ;;' \ + ' *)' \ + ' cd "$INSTALL_DIR" && exec docker compose "$@"' \ + ' ;;' \ + 'esac' \ + > "$WRAPPER" chmod +x "$WRAPPER" # ── Add ~/.local/bin to PATH if needed ─────────────────────────────────────── @@ -99,8 +103,8 @@ echo "" # ── Done ────────────────────────────────────────────────────────────────────── success "DejaCode is running at ${BOLD}http://localhost${NC}" echo "" -echo " Create your admin user: dejacode createsuperuser" -echo " Stop: dejacode stop" -echo " Logs: dejacode logs" +echo " Create your admin user: dejacode exec web ./manage.py createsuperuser" +echo " Stop: dejacode down" +echo " Logs: dejacode logs -f" echo "" echo " Reload your shell or run: source ~/.zshrc (or ~/.bashrc)" From 257b5b757661d6ce74d3b7c61844ac229f69112a Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 18:30:35 +0400 Subject: [PATCH 10/20] adjust the script Signed-off-by: tdruez --- docs/installation.rst | 2 +- install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 730a4b1c..72a15544 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -110,7 +110,7 @@ To completely remove DejaCode and all its data:: .. _run_with_docker_build: Run with Docker — build from source -===================================== +=================================== This method builds the Docker image locally from the DejaCode source repository. It is the recommended approach for enterprise deployments. diff --git a/install.sh b/install.sh index 7320d471..aed8603e 100755 --- a/install.sh +++ b/install.sh @@ -92,7 +92,7 @@ docker compose up -d # ── Wait for web to respond ─────────────────────────────────────────────────── info "Waiting for DejaCode to be ready" RETRIES=40 -until curl -fsS --max-time 5 http://localhost/ -o /dev/null 2>&1; do +until curl -fsS --max-time 5 http://localhost/ -o /dev/null 2>/dev/null; do RETRIES=$((RETRIES - 1)) [ $RETRIES -eq 0 ] && die "Timed out waiting for DejaCode to start. Run: dejacode logs" echo -n "." From d53bb16a110b9f0436f89b36d382e01fa272108e Mon Sep 17 00:00:00 2001 From: tdruez Date: Tue, 9 Jun 2026 18:41:35 +0400 Subject: [PATCH 11/20] set the main branch Signed-off-by: tdruez --- install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index aed8603e..512610e6 100755 --- a/install.sh +++ b/install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash # DejaCode installer — no root required, works on macOS and Linux. -# Usage: curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files/install.sh | bash +# Usage: curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/main/install.sh | bash set -eu -REPO="https://raw.githubusercontent.com/aboutcode-org/dejacode/compose-files" +REPO="https://raw.githubusercontent.com/aboutcode-org/dejacode/main" INSTALL_DIR="${DEJACODE_HOME:-$HOME/.dejacode}" BIN_DIR="$HOME/.local/bin" WRAPPER="$BIN_DIR/dejacode" From 64bd16f207d459aec042c1c2b3126dd752dcefa2 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 08:29:38 +0400 Subject: [PATCH 12/20] update and simplify install docs Signed-off-by: tdruez --- docs/installation.rst | 253 ++++++++++++++---------------------------- 1 file changed, 86 insertions(+), 167 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 72a15544..298841e7 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -12,9 +12,9 @@ There are three ways to run DejaCode: - :ref:`run_with_docker` — **simplest option**, no repository checkout or build step required. Uses the pre-built Docker image published on GitHub. -- :ref:`run_with_docker_build` — build and run from source using Docker. - Recommended for enterprise deployments. -- :ref:`local_development_installation` — for contributors to DejaCode itself. +- :ref:`enterprise_deployment` — same pre-built image with custom nginx, domain + configuration, and hardware recommendations for production servers. +- :ref:`local_development_installation` — Docker-based setup for contributors. .. _run_with_docker: @@ -78,6 +78,10 @@ Follow the prompt instructions, providing the required information: You can move onto the Tutorials section starting with the :ref:`user_tutorial_1`. +.. |localhost_link| raw:: html + + http://localhost/ + .. note:: The pre-built image always corresponds to the most recent release and is tagged ``latest``. @@ -107,229 +111,144 @@ To completely remove DejaCode and all its data:: dejacode uninstall -.. _run_with_docker_build: - -Run with Docker — build from source -=================================== - -This method builds the Docker image locally from the DejaCode source repository. -It is the recommended approach for enterprise deployments. - -1. Get Docker -------------- - -Start by downloading and **installing Docker on your platform**. -Refer to Docker's documentation for the best installation path for your system: -|get_docker_link2|. - -.. |get_docker_link2| raw:: html - - Get Docker - -2. Build the image ------------------- - -DejaCode comes with the necessary ``Dockerfile`` and ``docker-compose.yml`` files to -create the Docker images and to manage the services (database, cache, webserver). - -.. warning:: For **Windows** users, before cloning the repository, ensure that your git - ``autocrlf`` configuration is set to ``false``:: - - git config --global core.autocrlf false - -Clone the DejaCode repository -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _enterprise_deployment: -Open your terminal and clone the `DejaCode repo `_ -with the following command:: - - git clone --depth=1 https://github.com/aboutcode-org/dejacode.git - -Build the Docker image -^^^^^^^^^^^^^^^^^^^^^^ - -Create an **environment file**, and **build the Docker image** with:: - - cd dejacode && make envfile - docker compose build - -3. Run the app --------------- +Enterprise deployment +===================== -To **run the DejaCode images as containers**, use the following command:: +Enterprise deployments use the same pre-built image as the standard install, +with additional configuration for your domain, a custom nginx setup, and +dedicated server hardware. - docker compose up -d +1. Install +---------- -4. Create an application user ------------------------------ +Follow the :ref:`run_with_docker` steps. Once the stack is running, continue +below to adapt it for production. -To create a superuser for the application, use the following command:: +2. Configure your domain +------------------------ - make createsuperuser +Edit ``~/.dejacode/.env`` and update the following settings to match your +server's hostname or IP:: -Follow the prompt instructions, providing the required information: + ALLOWED_HOSTS=dejacode.example.com + CSRF_TRUSTED_ORIGINS=https://dejacode.example.com -- **Username**: Choose a unique username. -- **Email Address**: Provide a valid email address. -- **Strong Password**: Create a password following security guidelines. +Restart the stack to apply:: -Use these credentials to access the application. + dejacode restart -.. admonition:: Congratulations! - :class: tip +3. Configure nginx +------------------ - Congratulations, you are now ready to use DejaCode. +The default nginx configuration embedded in ``compose.yml`` is suitable for +local use. For production, replace it with your own configuration file. - Open a web browser and visit |localhost_link| to **access the web UI**. +Create a ``compose.override.yml`` in your installation directory +(``~/.dejacode/``) with the following content: - You can sign-in with your user credentials generated above. +.. code-block:: yaml - You can move onto the Tutorials section starting with the :ref:`user_tutorial_1`. + services: + nginx: + configs: [] + volumes: + - ./nginx.conf:/etc/nginx/conf.d/default.conf -.. |localhost_link| raw:: html +Then create ``~/.dejacode/nginx.conf`` with your production nginx configuration +(TLS termination, custom headers, upstream settings, etc.) and restart:: - http://localhost/ + dejacode down && dejacode up -d -.. important:: - DejaCode will utilize all available CPUs according to your Docker configuration, - ensuring faster processing. - - **Make sure to allocate enough memory to support each CPU process.** - - A good rule of thumb is to allocate **1 GB of memory per CPU**. - For example, with Docker configured for 8 CPUs, allocate a minimum of 8 GB of - memory. +.. note:: + Docker Compose automatically picks up ``compose.override.yml`` when present + in the same directory as ``compose.yml``. -5. Dataspace setup and AboutCode integrations ---------------------------------------------- +4. AboutCode integrations +-------------------------- -Upon the initialization of the DejaCode application, the ``nexB`` reference -:ref:`dataspace` is created with a **default set of data**, including license and -organization libraries. +Upon initialization, the ``nexB`` reference :ref:`dataspace` is created with a +default set of data, including license and organization libraries. -Additionally, **AboutCode integrations are pre-configured** to connect to -**public instances** of the following AboutCode applications: +**AboutCode integrations are pre-configured** to connect to public instances of: -- **ScanCode.io**: Facilitates package scanning. - Refer to :ref:`dejacode_dataspace_scancodeio`. -- **PurlDB**: Provides access to a database of scanned packages. - Refer to :ref:`dejacode_dataspace_purldb`. -- **VulnerableCodeDB**: Enables access to a database containing information on package - vulnerabilities. - Refer to :ref:`dejacode_dataspace_vulnerablecode`. +- **ScanCode.io** — package scanning. See :ref:`dejacode_dataspace_scancodeio`. +- **PurlDB** — database of scanned packages. See :ref:`dejacode_dataspace_purldb`. +- **VulnerableCode** — package vulnerability data. See :ref:`dejacode_dataspace_vulnerablecode`. .. warning:: - In the scenario of **deploying DejaCode as an enterprise service** within your - organization, it is **strongly recommended to review these configurations**. - Consideration should be given to **running your own instances** of these - applications to ensure that **sensitive or private data** is not inadvertently - submitted to public services. This strategic approach helps to safeguard - organizational data and privacy during package scanning and vulnerability - assessments. + For enterprise deployments it is **strongly recommended to run your own + instances** of these services to ensure that sensitive or private data is + not submitted to public endpoints. Hardware requirements -===================== - -The minimum hardware/system requirements for running DejaCode as an enterprise -server are: +--------------------- +-----------+------------------------------------------------------------------+ | Item | Minimum | +===========+==================================================================+ -| Processor | Modern X86 64 bit Multi Core, with at least **4 physical cores** | +| OS | **Ubuntu 24.04 LTS 64-bit** server | +-----------+------------------------------------------------------------------+ -| Memory | **64 GB** or more (ECC preferred) | +| Processor | Modern x86-64 multi-core, at least **4 physical cores** | +-----------+------------------------------------------------------------------+ -| Disk | 2 * 500GB SDD in RAID mirror setup (enterprise disk preferred) | +| Memory | **64 GB** or more (ECC preferred) | +-----------+------------------------------------------------------------------+ -| OS | **Ubuntu 22.04 LTS 64-bit** server clean installation | +| Disk | 2 x 500 GB SSD in RAID mirror (enterprise disk preferred) | +-----------+------------------------------------------------------------------+ +.. important:: + DejaCode uses all available CPUs for worker processes. + Allocate at least **1 GB of memory per CPU core**. + .. _local_development_installation: Local development installation ============================== .. note:: - This section is designed for those interested in actively contributing to the - development and enhancement of DejaCode. After setting up DejaCode, please refer - to our Contributing chapter for comprehensive instructions on submitting - code changes. - -Supported Platforms -------------------- - -**DejaCode** has been tested and is supported on the following operating systems: - -#. **Debian-based** Linux distributions. It is reported to work well Fedora. -#. **macOS** 10.14 and up - -.. warning:: - On **Windows** DejaCode can **only** be :ref:`run_with_docker`. - -Pre-installation Checklist --------------------------- - -Before you install DejaCode, make sure you have the following prerequisites: - -#. **Python: versions 3.14** found at https://www.python.org/downloads/ -#. **Git**: most recent release available at https://git-scm.com/ -#. **PostgreSQL**: release 16 or later found at https://www.postgresql.org/ or - https://postgresapp.com/ on macOS -#. **ldap** development libraries to build python-ldap on Linux. - For instance on Debian:: - - apt-get install -y libldap2-dev libsasl2-dev slapd ldap-utils - -.. _system_dependencies: + This section is for contributors to DejaCode. The development environment + runs entirely in Docker — no local Python or PostgreSQL installation required. + Please refer to the Contributing guide for instructions on submitting changes. -Clone and Configure +Clone and configure ------------------- -#. Clone the `DejaCode GitHub repository `_:: +#. Clone the `DejaCode repository `_:: git clone https://github.com/aboutcode-org/dejacode.git && cd dejacode -#. Install the dependencies:: - - make dev +Run the app +----------- -#. Create an environment file:: +Build the development image and start all services:: - make envfile_dev + make run -Database --------- +The application is available at http://localhost:8000/. +Source code changes are reflected immediately without restarting the container. -**PostgreSQL** is the preferred database backend. -To set up the database user, database, and table, run:: +.. note:: + ``make run`` is a shortcut for ``docker compose -f compose.dev.yml up``. + All standard ``docker compose`` subcommands are available directly:: - make postgresdb + docker compose -f compose.dev.yml logs -f + docker compose -f compose.dev.yml exec web ./manage.py shell + docker compose -f compose.dev.yml down -To entirely delete the database user, database, and tables, run:: +Create an application user +-------------------------- - make postgresdb_clean +:: + make superuser Tests ----- -You can validate your DejaCode installation by running the test suite:: +:: make test -Run the App ------------ - -Start the local web server using:: - - make run - -Then, open your web browser and visit http://localhost:8000/ to access the web -application. - .. warning:: - This setup is **not suitable for deployments** and is - **only supported for local development**. - It is highly recommended to use the :ref:`run_with_docker` setup to ensure the - availability of all the features. + This setup is **not suitable for deployments** and is **only supported for local development**. From ad8ac4fbfc38a530ce616d18298614b5d79f0c0e Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 08:46:41 +0400 Subject: [PATCH 13/20] adjust Makefile Signed-off-by: tdruez --- Makefile | 100 ++++++++++++++++-------------------------- docs/installation.rst | 4 ++ 2 files changed, 43 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index 46f3b4fe..42858d2c 100644 --- a/Makefile +++ b/Makefile @@ -13,14 +13,53 @@ IMAGE_NAME=dejacode:dev COMPOSE=docker compose -f compose.dev.yml MANAGE=${COMPOSE} exec web ./manage.py +EXEC=${COMPOSE} exec run: @echo "-> Run the Docker compose services in dev mode (hot reload on code changes)" ${COMPOSE} up +bash: + # Open a bash session in the running web container + ${COMPOSE} exec web bash + +shell: + # Open a bash session in a standalone container (no stack required) + docker run -it $(IMAGE_NAME) bash + +test: + @echo "-> Run the test suite" + ${MANAGE} test --noinput --parallel auto + +migrations: + @echo "-> Creates new database migrations" + ${MANAGE} makemigrations + +migrate: + @echo "-> Apply database migrations" + ${MANAGE} migrate + +build: + @echo "-> Build the dev Docker images" + ${COMPOSE} build + superuser: ${MANAGE} createsuperuser +######################################################################################## +# Utilities +######################################################################################## + +doc8: + @echo "-> Run documentation .rst validation" + uvx doc8==2.0.0 --max-line-length 100 --ignore-path docs/_build/ --quiet docs/ + +valid: + @echo "-> Run Ruff format" + uvx ruff format + @echo "-> Run Ruff linter" + uvx ruff check --fix + ######################################################################################## VENV_LOCATION=.venv @@ -42,18 +81,6 @@ POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US. TIMESTAMP=$(shell date +"%Y-%m-%d_%H%M") IMAGE_NAME=dejacode -# Use sudo for postgres, only on Linux -UNAME := $(shell uname) -ifeq ($(UNAME), Linux) - SUDO_POSTGRES=sudo -u postgres -else - SUDO_POSTGRES= -endif - -virtualenv: - @echo "-> Bootstrap the virtualenv with uv" - uv venv --allow-existing ${VENV_LOCATION} - conf: virtualenv @echo "-> Install dependencies" uv sync --frozen @@ -108,16 +135,6 @@ envfile_dev: envfile @echo "-> Update the .env file for development" @echo DATABASE_PASSWORD=\"dejacode\" >> ${ENV_FILE} -doc8: - @echo "-> Run documentation .rst validation" - uvx doc8==2.0.0 --max-line-length 100 --ignore-path docs/_build/ --quiet docs/ - -valid: - @echo "-> Run Ruff format" - @${ACTIVATE} ruff format - @echo "-> Run Ruff linter" - @${ACTIVATE} ruff check --fix - check: @echo "-> Run Ruff linter validation (pycodestyle, bandit, isort, and more)" @${ACTIVATE} ruff check @@ -156,54 +173,15 @@ initdb: @echo "Starting Docker services" ${DOCKER_COMPOSE} start -migrate: - @echo "-> Apply database migrations" - ${MANAGE} migrate - -postgresdb: - @echo "-> Configure PostgreSQL database" - @echo "-> Create database user ${DB_NAME}" - @${SUDO_POSTGRES} createuser --no-createrole --no-superuser --login --inherit --createdb '${DB_USERNAME}' || true - @${SUDO_POSTGRES} psql -c "alter user ${DB_USERNAME} with encrypted password '${DB_PASSWORD}';" || true - @echo "-> Drop ${DB_NAME} database if exists" - @${SUDO_POSTGRES} dropdb ${DB_NAME} || true - @echo "-> Create ${DB_NAME} database: createdb --owner=${DB_USERNAME} ${POSTGRES_INITDB_ARGS} ${DB_NAME}" - @${SUDO_POSTGRES} createdb --owner=${DB_USERNAME} ${POSTGRES_INITDB_ARGS} ${DB_NAME} - @gunzip < ${DB_INIT_FILE} | psql --username=${DB_USERNAME} ${DB_NAME} - @echo "-> Apply database migrations" - ${MANAGE} migrate - -postgresdb_clean: - @echo "-> Drop PostgreSQL user and database" - @${SUDO_POSTGRES} dropdb ${DB_NAME} || true - @${SUDO_POSTGRES} dropuser '${DB_USERNAME}' || true - -# run: -# DJANGO_RUNSERVER_HIDE_WARNING=true ${MANAGE} runserver 8000 --insecure - worker: ${MANAGE} rqworker -test: - @echo "-> Run the test suite" - ${MANAGE} test --noinput --parallel auto - docs: @echo "-> Builds the documentation" rm -rf ${DOCS_LOCATION}/_build/ uvx --from sphinx==9.1.0 --with furo==2025.12.19 sphinx-build -b singlehtml ${DOCS_LOCATION} ${DOCS_LOCATION}/_build/singlehtml/ uvx --from sphinx==9.1.0 --with furo==2025.12.19 sphinx-build -b html ${DOCS_LOCATION} ${DOCS_LOCATION}/_build/html/ -build: - @echo "-> Build the Docker image" - docker build -t $(IMAGE_NAME) . - -bash: - docker run -it $(IMAGE_NAME) bash - -shell: - ${DOCKER_EXEC} web ./manage.py shell - psql: ${DOCKER_EXEC} ${DB_CONTAINER_NAME} psql --username=${DB_USERNAME} postgres diff --git a/docs/installation.rst b/docs/installation.rst index 298841e7..7648e0c7 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -218,6 +218,10 @@ Clone and configure git clone https://github.com/aboutcode-org/dejacode.git && cd dejacode +#. Create an environment file:: + + make envfile_dev + Run the app ----------- From d7763ff76c075dcb3086de1806d406ccb0c12da6 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 08:52:09 +0400 Subject: [PATCH 14/20] adapt the GH workflows Signed-off-by: tdruez --- .../check-code-and-docs-validation.yml | 34 +++++++++ .github/workflows/run-unit-tests.yml | 75 ------------------- README.rst | 3 +- 3 files changed, 36 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/check-code-and-docs-validation.yml delete mode 100644 .github/workflows/run-unit-tests.yml diff --git a/.github/workflows/check-code-and-docs-validation.yml b/.github/workflows/check-code-and-docs-validation.yml new file mode 100644 index 00000000..c61f398a --- /dev/null +++ b/.github/workflows/check-code-and-docs-validation.yml @@ -0,0 +1,34 @@ +name: Run unit tests + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +jobs: + check-code-and-docs-validation: + runs-on: ubuntu-24.04 + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false # do not keep the token around + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.14" + + - name: Install uv from vendored wheel + run: pip install --no-index --find-links=./thirdparty/dist uv + + - name: Validate code format + run: make check + + - name: Build the documentation + run: make docs diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml deleted file mode 100644 index 4f8bebd9..00000000 --- a/.github/workflows/run-unit-tests.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Run unit tests - -on: - workflow_dispatch: - pull_request: - push: - branches: - - main - -env: - DATABASE_NAME: dejacode - DATABASE_USER: dejacode - DATABASE_PASSWORD: dejacode - POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8 - -jobs: - run-unit-tests: - runs-on: ubuntu-24.04 - permissions: - contents: read - - services: - postgres: - image: postgres:16.13 - env: - POSTGRES_DB: ${{ env.DATABASE_NAME }} - POSTGRES_USER: ${{ env.DATABASE_USER }} - POSTGRES_PASSWORD: ${{ env.DATABASE_PASSWORD }} - POSTGRES_INITDB_ARGS: ${{ env.POSTGRES_INITDB_ARGS }} - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false # do not keep the token around - - - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.14" - - - name: Install python-ldap OS dependencies - run: | - sudo apt-get update - sudo apt-get install -y libldap2-dev libsasl2-dev slapd ldap-utils - - - name: Disable AppArmor for slapd - run: | - sudo ln -s /etc/apparmor.d/usr.sbin.slapd /etc/apparmor.d/disable/ - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.slapd - - - name: Install uv from vendored wheel - run: pip install --no-index --find-links=./thirdparty/dist uv - - - name: Install dependencies - run: make dev envfile - - - name: Validate code format - run: make check - - - name: Start Redis - uses: supercharge/redis-github-action@bc274cb7238cd63a45029db04ee48c07a72609fd # v1.8.1 - - - name: Build the documentation - run: make docs - - - name: Run tests - run: .venv/bin/python manage.py test --verbosity=2 --noinput --parallel diff --git a/README.rst b/README.rst index c7057e72..e022ecc3 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,8 @@ DejaCode ======== DejaCode provides an enterprise-level application to automate open source license -compliance and ensure software supply chain integrity, powered by `ScanCode `_, +compliance and ensure software supply chain integrity, powered by +`ScanCode `_, the industry-leading code scanner. Why Use DejaCode? From aaf89f5bef27785b9d4a18debf548c1ff9662725 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 08:58:21 +0400 Subject: [PATCH 15/20] adjust makefile Signed-off-by: tdruez --- Makefile | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 42858d2c..cf78903b 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,8 @@ superuser: # Utilities ######################################################################################## +DOCS_LOCATION=./docs + doc8: @echo "-> Run documentation .rst validation" uvx doc8==2.0.0 --max-line-length 100 --ignore-path docs/_build/ --quiet docs/ @@ -60,6 +62,19 @@ valid: @echo "-> Run Ruff linter" uvx ruff check --fix +check: + @echo "-> Run Ruff linter validation (pycodestyle, bandit, isort, and more)" + uvx ruff check + @echo "-> Run Ruff format validation" + uvx ruff format --check + @$(MAKE) doc8 + +docs: + @echo "-> Builds the documentation" + rm -rf ${DOCS_LOCATION}/_build/ + uvx --from sphinx==9.1.0 --with furo==2025.12.19 sphinx-build -b singlehtml ${DOCS_LOCATION} ${DOCS_LOCATION}/_build/singlehtml/ + uvx --from sphinx==9.1.0 --with furo==2025.12.19 sphinx-build -b html ${DOCS_LOCATION} ${DOCS_LOCATION}/_build/html/ + ######################################################################################## VENV_LOCATION=.venv @@ -69,7 +84,6 @@ ACTIVATE?=. ${VENV_LOCATION}/bin/activate; GET_SECRET_KEY=`head -c50 /dev/urandom | base64 | head -c50` # Customize with `$ make envfile ENV_FILE=/etc/dejacode/.env` ENV_FILE=.env -DOCS_LOCATION=./docs DOCKER_COMPOSE=docker compose -f docker-compose.yml DOCKER_EXEC=${DOCKER_COMPOSE} exec DB_NAME=dejacode_db @@ -79,7 +93,6 @@ DB_CONTAINER_NAME=db DB_INIT_FILE=./data/postgresql/initdb.sql.gz POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8 TIMESTAMP=$(shell date +"%Y-%m-%d_%H%M") -IMAGE_NAME=dejacode conf: virtualenv @echo "-> Install dependencies" @@ -135,18 +148,6 @@ envfile_dev: envfile @echo "-> Update the .env file for development" @echo DATABASE_PASSWORD=\"dejacode\" >> ${ENV_FILE} -check: - @echo "-> Run Ruff linter validation (pycodestyle, bandit, isort, and more)" - @${ACTIVATE} ruff check - @echo "-> Run Ruff format validation" - @${ACTIVATE} ruff format --check - @echo "-> Running ABOUT files validation" - @${ACTIVATE} about check ./thirdparty/ - @${ACTIVATE} about check ./data/ - @${ACTIVATE} about check ./dje/ - @${ACTIVATE} about check ./dejacode_toolkit/ - @$(MAKE) doc8 - check-deploy: @echo "-> Check Django deployment settings" ${MANAGE} check --deploy @@ -173,15 +174,6 @@ initdb: @echo "Starting Docker services" ${DOCKER_COMPOSE} start -worker: - ${MANAGE} rqworker - -docs: - @echo "-> Builds the documentation" - rm -rf ${DOCS_LOCATION}/_build/ - uvx --from sphinx==9.1.0 --with furo==2025.12.19 sphinx-build -b singlehtml ${DOCS_LOCATION} ${DOCS_LOCATION}/_build/singlehtml/ - uvx --from sphinx==9.1.0 --with furo==2025.12.19 sphinx-build -b html ${DOCS_LOCATION} ${DOCS_LOCATION}/_build/html/ - psql: ${DOCKER_EXEC} ${DB_CONTAINER_NAME} psql --username=${DB_USERNAME} postgres From ba227a3e057d44e74b93dda817cf1267e87c0b99 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 10:15:44 +0400 Subject: [PATCH 16/20] remove volume mount from prod compose Signed-off-by: tdruez --- compose.prod.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compose.prod.yml b/compose.prod.yml index 9c24d504..8dbbae2e 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -1,25 +1,19 @@ name: dejacode -x-description: "Production overrides — external config bind mounts for prod/staging deployments" +x-description: "Production overrides — build from source, external nginx config" services: web: build: . image: dejacode:prod - volumes: - - /etc/dejacode/:/etc/dejacode/ worker: build: . image: dejacode:prod - volumes: - - /etc/dejacode/:/etc/dejacode/ scheduler: build: . image: dejacode:prod - volumes: - - /etc/dejacode/:/etc/dejacode/ nginx: configs: [] From b51b6260bd894e1f7e8492da2ebbd6130e24321f Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 10:19:59 +0400 Subject: [PATCH 17/20] remove legacy docker-compose.yml file Signed-off-by: tdruez --- docker-compose.yml | 110 --------------------------------------------- 1 file changed, 110 deletions(-) delete mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index a0fb3beb..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: dejacode - -x-description: "Legacy file — kept for backward compatibility, use compose.yml instead" - -services: - db: - image: docker.io/library/postgres:16.13 - env_file: - - docker.env - volumes: - - db_data:/var/lib/postgresql/data/ - - ./data/postgresql:/docker-entrypoint-initdb.d/ - shm_size: "1gb" - restart: always - healthcheck: - test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" ] - interval: 10s - timeout: 5s - retries: 5 - - redis: - image: docker.io/library/redis:8.6-alpine - # Enable redis data persistence using the "Append Only File" with the - # default policy of fsync every second. See https://redis.io/topics/persistence - command: redis-server --appendonly yes - volumes: - - redis_data:/data - restart: always - - web: - build: . - command: sh -c " - ./manage.py migrate && - ./manage.py collectstatic --no-input --verbosity 0 --clear && - gunicorn dejacode.wsgi:application --bind :8000 --timeout 600 \ - --workers 4 --worker-tmp-dir /dev/shm" - env_file: - - docker.env - expose: - - 8000 - volumes: - - .env:/opt/dejacode/.env - - /etc/dejacode/:/etc/dejacode/ - - static:/var/dejacode/static - - media:/var/dejacode/media - depends_on: - db: - condition: service_healthy - redis: - condition: service_started - clamav: - condition: service_started - - worker: - build: . - # Ensure that potential db migrations run first by waiting until "web" is up - command: wait-for-it --strict --timeout=180 web:8000 -- sh -c " - ./manage.py rqworker-pool --num-workers 2 --verbosity 1" - env_file: - - docker.env - volumes: - - .env:/opt/dejacode/.env - - /etc/dejacode/:/etc/dejacode/ - # The media volume is required to access uploaded files from the worker - - media:/var/dejacode/media - depends_on: - - redis - - db - - web - - scheduler: - build: . - command: wait-for-it web:8000 -- sh -c "./manage.py rqcron dje.cron_jobs" - env_file: - - docker.env - volumes: - - .env:/opt/dejacode/.env - - /etc/dejacode/:/etc/dejacode/ - depends_on: - - redis - - db - - web - - nginx: - image: docker.io/library/nginx:1.29-alpine - ports: - - "${NGINX_PUBLISHED_HTTP_PORT:-80}:80" - - "${NGINX_PUBLISHED_HTTPS_PORT:-443}:443" - volumes: - - ./etc/nginx/conf.d/:/etc/nginx/conf.d/ - - static:/var/dejacode/static/ - - webroot:/var/www/html/ - depends_on: - - web - restart: always - - clamav: - image: docker.io/clamav/clamav:1.5_base - volumes: - - clamav_data:/var/lib/clamav - - media:/var/dejacode/media - restart: always - -volumes: - db_data: - redis_data: - clamav_data: - static: - media: - webroot: From 273c52e1b87992947cd6d6f34a0dae6a84da3d64 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 10:22:00 +0400 Subject: [PATCH 18/20] simplify prod compose Signed-off-by: tdruez --- compose.prod.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/compose.prod.yml b/compose.prod.yml index 8dbbae2e..f08cc0a3 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -5,15 +5,12 @@ x-description: "Production overrides — build from source, external nginx confi services: web: build: . - image: dejacode:prod worker: build: . - image: dejacode:prod scheduler: build: . - image: dejacode:prod nginx: configs: [] From 257ff5060194a1651f76f79ecbf52a6eac9b9757 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 10:43:17 +0400 Subject: [PATCH 19/20] refine the whole prod setup Signed-off-by: tdruez --- compose.build.yml | 13 +++++++++++++ compose.prod.yml | 18 ------------------ compose.yml | 30 +----------------------------- docs/installation.rst | 27 +++++++-------------------- install.sh | 4 ++++ 5 files changed, 25 insertions(+), 67 deletions(-) create mode 100644 compose.build.yml delete mode 100644 compose.prod.yml diff --git a/compose.build.yml b/compose.build.yml new file mode 100644 index 00000000..456ab4d4 --- /dev/null +++ b/compose.build.yml @@ -0,0 +1,13 @@ +name: dejacode + +x-description: "Build override — builds the app image from source instead of using the pre-built image" + +services: + web: + build: . + + worker: + build: . + + scheduler: + build: . diff --git a/compose.prod.yml b/compose.prod.yml deleted file mode 100644 index f08cc0a3..00000000 --- a/compose.prod.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: dejacode - -x-description: "Production overrides — build from source, external nginx config" - -services: - web: - build: . - - worker: - build: . - - scheduler: - build: . - - nginx: - configs: [] - volumes: - - ./etc/nginx/conf.d/:/etc/nginx/conf.d/ diff --git a/compose.yml b/compose.yml index ceefe5d0..9d4902ab 100644 --- a/compose.yml +++ b/compose.yml @@ -84,11 +84,9 @@ services: - "${NGINX_PUBLISHED_HTTP_PORT:-80}:80" - "${NGINX_PUBLISHED_HTTPS_PORT:-443}:443" volumes: + - ./etc/nginx/conf.d/:/etc/nginx/conf.d/ - static:/var/dejacode/static/ - webroot:/var/www/html/ - configs: - - source: nginx_conf - target: /etc/nginx/conf.d/default.conf depends_on: - web restart: always @@ -107,29 +105,3 @@ volumes: static: media: webroot: - -configs: - nginx_conf: - content: | - upstream gunicorn_app { - server web:8000; - } - server { - listen 80; - http2 on; - server_tokens off; - gzip on; - gzip_comp_level 6; - gzip_types text/css text/javascript application/javascript image/svg+xml; - location / { - proxy_pass http://gunicorn_app; - proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for; - proxy_set_header Host $$http_host; - proxy_redirect off; - client_max_body_size 1G; - proxy_read_timeout 600s; - } - location /static/ { - alias /var/dejacode/static/; - } - } diff --git a/docs/installation.rst b/docs/installation.rst index 7648e0c7..dfb086ad 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -12,8 +12,8 @@ There are three ways to run DejaCode: - :ref:`run_with_docker` — **simplest option**, no repository checkout or build step required. Uses the pre-built Docker image published on GitHub. -- :ref:`enterprise_deployment` — same pre-built image with custom nginx, domain - configuration, and hardware recommendations for production servers. +- :ref:`enterprise_deployment` — same pre-built image with custom nginx configuration, + domain settings, and hardware recommendations for production servers. - :ref:`local_development_installation` — Docker-based setup for contributors. .. _run_with_docker: @@ -44,7 +44,7 @@ Run the one-liner installer:: This script will: - Create ``~/.dejacode/`` as the installation directory -- Download ``compose.yml``, ``docker.env``, and the database seed data +- Download ``compose.yml``, ``docker.env``, the nginx configuration, and the database seed data - Generate ``.env`` with a secure secret key - Install the ``dejacode`` command in ``~/.local/bin/`` - Start all services and wait until the application is ready @@ -145,26 +145,13 @@ Restart the stack to apply:: The default nginx configuration embedded in ``compose.yml`` is suitable for local use. For production, replace it with your own configuration file. -Create a ``compose.override.yml`` in your installation directory -(``~/.dejacode/``) with the following content: - -.. code-block:: yaml - - services: - nginx: - configs: [] - volumes: - - ./nginx.conf:/etc/nginx/conf.d/default.conf - -Then create ``~/.dejacode/nginx.conf`` with your production nginx configuration -(TLS termination, custom headers, upstream settings, etc.) and restart:: +The installer downloads a default nginx configuration to +``~/.dejacode/etc/nginx/conf.d/default.conf``. Replace it with your own +configuration (TLS termination, custom headers, upstream settings, etc.) +and restart:: dejacode down && dejacode up -d -.. note:: - Docker Compose automatically picks up ``compose.override.yml`` when present - in the same directory as ``compose.yml``. - 4. AboutCode integrations -------------------------- diff --git a/install.sh b/install.sh index 512610e6..e6a4515b 100755 --- a/install.sh +++ b/install.sh @@ -34,6 +34,10 @@ curl -sSL "$REPO/data/postgresql/initdb.sql.gz" -o data/postgresql/initdb.sql.gz info "Downloading docker.env" curl -sSL "$REPO/docker.env" -o docker.env +info "Downloading nginx configuration" +mkdir -p etc/nginx/conf.d +curl -sSL "$REPO/etc/nginx/conf.d/default.conf" -o etc/nginx/conf.d/default.conf + # ── Generate .env with a secure secret key ──────────────────────────────────── info "Generating .env" # Read enough bytes from urandom so tr has enough after filtering, then cut to 50 chars. From 8066e83438db477b376a4a6a91eb88d7cce24ee4 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 10 Jun 2026 11:27:45 +0400 Subject: [PATCH 20/20] adjust consistency Signed-off-by: tdruez --- compose.build.yml | 2 +- compose.dev.yml | 2 +- install.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compose.build.yml b/compose.build.yml index 456ab4d4..bff5fa52 100644 --- a/compose.build.yml +++ b/compose.build.yml @@ -1,6 +1,6 @@ name: dejacode -x-description: "Build override — builds the app image from source instead of using the pre-built image" +x-description: "Build override: builds the app image from source instead of using the pre-built image" services: web: diff --git a/compose.dev.yml b/compose.dev.yml index 76353a50..14dcc333 100644 --- a/compose.dev.yml +++ b/compose.dev.yml @@ -1,6 +1,6 @@ name: dejacode-dev -x-description: "Development stack — source mounted, runserver with auto-reload" +x-description: "Development stack: source mounted, runserver with auto-reload" services: db: diff --git a/install.sh b/install.sh index e6a4515b..2b1b30c7 100755 --- a/install.sh +++ b/install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# DejaCode installer — no root required, works on macOS and Linux. +# DejaCode installer: no root required, works on macOS and Linux. # Usage: curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/main/install.sh | bash set -eu