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/.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/Makefile b/Makefile index e75699ec..cf78903b 100644 --- a/Makefile +++ b/Makefile @@ -6,14 +6,84 @@ # 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 +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 +######################################################################################## + +DOCS_LOCATION=./docs + +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 + +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 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` ENV_FILE=.env -DOCS_LOCATION=./docs DOCKER_COMPOSE=docker compose -f docker-compose.yml DOCKER_EXEC=${DOCKER_COMPOSE} exec DB_NAME=dejacode_db @@ -23,19 +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 - -# 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" @@ -91,28 +148,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 - @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 @@ -139,54 +174,6 @@ 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 @@ -194,7 +181,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 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? diff --git a/compose.build.yml b/compose.build.yml new file mode 100644 index 00000000..bff5fa52 --- /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/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.dev.yml b/compose.dev.yml new file mode 100644 index 00000000..14dcc333 --- /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/compose.yml similarity index 88% rename from docker-compose.yml rename to compose.yml index 1a5b033d..9d4902ab 100644 --- a/docker-compose.yml +++ b/compose.yml @@ -1,4 +1,7 @@ name: dejacode + +x-description: "Full DejaCode stack: all services, pre-built image, no checkout required" + services: db: image: docker.io/library/postgres:16.13 @@ -10,7 +13,7 @@ services: 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 @@ -25,7 +28,7 @@ services: restart: always web: - build: . + image: ghcr.io/aboutcode-org/dejacode:latest command: sh -c " ./manage.py migrate && ./manage.py collectstatic --no-input --verbosity 0 --clear && @@ -37,7 +40,6 @@ services: - 8000 volumes: - .env:/opt/dejacode/.env - - /etc/dejacode/:/etc/dejacode/ - static:/var/dejacode/static - media:/var/dejacode/media depends_on: @@ -49,7 +51,7 @@ services: condition: service_started worker: - build: . + 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" @@ -57,7 +59,6 @@ services: - 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: @@ -66,13 +67,12 @@ services: - web scheduler: - build: . + 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 - - /etc/dejacode/:/etc/dejacode/ depends_on: - redis - db diff --git a/docs/installation.rst b/docs/installation.rst index 3a5e127f..dfb086ad 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -8,71 +8,57 @@ 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:`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: 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. 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 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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 -^^^^^^^^^^^^^^^^^^^^^^ +2. Run the installer +-------------------- -Create an **environment file**, and **build the Docker image** with:: +Run the one-liner installer:: - cd dejacode && make envfile - docker compose build + curl -sSL https://raw.githubusercontent.com/aboutcode-org/dejacode/main/install.sh | bash -3. Run the app --------------- +This script will: -To **run the DejaCode images as containers**, use the following command:: +- Create ``~/.dejacode/`` as the installation directory +- 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 - docker compose up -d +.. note:: + Override the default installation directory with: + ``DEJACODE_HOME=/path/to/dir bash install.sh`` -4. Create an application user +3. Create an application user ----------------------------- -To create a superuser for the application, use the following command:: +:: - make createsuperuser + dejacode exec web ./manage.py createsuperuser Follow the prompt instructions, providing the required information: @@ -80,16 +66,15 @@ Follow the prompt instructions, providing the required information: - **Email Address**: Provide a valid email address. - **Strong Password**: Create a password following security guidelines. -Use these credentials to access the application. +4. Access the application +------------------------- .. admonition:: Congratulations! :class: tip - Congratulations, you are now ready to use DejaCode. - Open a web browser and visit |localhost_link| to **access the web UI**. - You can sign-in with your user credentials generated above. + You can sign-in with the credentials you created above. You can move onto the Tutorials section starting with the :ref:`user_tutorial_1`. @@ -97,146 +82,164 @@ Use these credentials to access the application. http://localhost/ -.. important:: - DejaCode will utilize all available CPUs according to your Docker configuration, - ensuring faster processing. +.. note:: + The pre-built image always corresponds to the most recent release and is tagged + ``latest``. - **Make sure to allocate enough memory to support each CPU process.** +.. _dejacode_command: - 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. +Managing your installation +-------------------------- -5. Dataspace setup and AboutCode integrations ---------------------------------------------- +The ``dejacode`` command is a thin wrapper around ``docker compose``. All standard +``docker compose`` subcommands work directly:: -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. + 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 -Additionally, **AboutCode integrations are pre-configured** to connect to -**public instances** of the following AboutCode applications: +To update DejaCode to the latest release:: -- **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`. + dejacode pull && dejacode up -d -.. 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. +To completely remove DejaCode and all its data:: -Hardware requirements + dejacode uninstall + +.. _enterprise_deployment: + +Enterprise deployment ===================== -The minimum hardware/system requirements for running DejaCode as an enterprise -server are: +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. + +1. Install +---------- + +Follow the :ref:`run_with_docker` steps. Once the stack is running, continue +below to adapt it for production. + +2. Configure your domain +------------------------ + +Edit ``~/.dejacode/.env`` and update the following settings to match your +server's hostname or IP:: + + ALLOWED_HOSTS=dejacode.example.com + CSRF_TRUSTED_ORIGINS=https://dejacode.example.com + +Restart the stack to apply:: + + dejacode restart + +3. Configure nginx +------------------ + +The default nginx configuration embedded in ``compose.yml`` is suitable for +local use. For production, replace it with your own configuration file. + +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 + +4. AboutCode integrations +-------------------------- + +Upon initialization, the ``nexB`` reference :ref:`dataspace` is created with a +default set of data, including license and organization libraries. + +**AboutCode integrations are pre-configured** to connect to public instances of: + +- **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:: + 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 +--------------------- +-----------+------------------------------------------------------------------+ | 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. + 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. -Supported Platforms +Clone and configure ------------------- -**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: - -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 - #. Create an environment file:: make envfile_dev -Database --------- +Run the app +----------- -**PostgreSQL** is the preferred database backend. -To set up the database user, database, and table, run:: +Build the development image and start all services:: - make postgresdb + make run -To entirely delete the database user, database, and tables, run:: +The application is available at http://localhost:8000/. +Source code changes are reflected immediately without restarting the container. - make postgresdb_clean +.. note:: + ``make run`` is a shortcut for ``docker compose -f compose.dev.yml up``. + All standard ``docker compose`` subcommands are available directly:: + 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 -Tests ------ - -You can validate your DejaCode installation by running the test suite:: +Create an application user +-------------------------- - make test +:: -Run the App ------------ + make superuser -Start the local web server using:: +Tests +----- - make run +:: -Then, open your web browser and visit http://localhost:8000/ to access the web -application. + make test .. 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**. diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..2b1b30c7 --- /dev/null +++ b/install.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +# 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 + +REPO="https://raw.githubusercontent.com/aboutcode-org/dejacode/main" +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 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. +# 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" +# 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 ─────────────────────────────────────── +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>/dev/null; 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 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)"