Skip to content

Commit a6de1f2

Browse files
tdruezchinyeungli
authored andcommitted
feat!: Switch development workflow from local venv to Docker Compose (#2145)
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent 1a31682 commit a6de1f2

4 files changed

Lines changed: 100 additions & 60 deletions

File tree

Makefile

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,66 @@
2020
# ScanCode.io is a free software code scanning tool from nexB Inc. and others.
2121
# Visit https://github.com/aboutcode-org/scancode.io for support and download.
2222

23+
########################################################################################
24+
# Docker dev commands
25+
########################################################################################
26+
27+
IMAGE_NAME=scancodeio
28+
COMPOSE=docker compose -f docker-compose.yml -f docker-compose.dev.yml
29+
MANAGE=${COMPOSE} exec web ./manage.py
30+
31+
run:
32+
@echo "-> Run the Docker compose services in dev mode (hot reload on code changes)"
33+
${COMPOSE} up
34+
35+
bash:
36+
# Open a bash session in the running web container
37+
${COMPOSE} exec web bash
38+
39+
shell:
40+
# Open a bash session in a standalone container (no stack required)
41+
docker run -it $(IMAGE_NAME) bash
42+
43+
test:
44+
@echo "-> Run the test suite"
45+
${MANAGE} test --noinput
46+
47+
fasttest:
48+
@echo "-> Run the test suite without the PipelinesIntegrationTest"
49+
${MANAGE} test --noinput --exclude-tag slow
50+
51+
migrations:
52+
@echo "-> Creates new database migrations"
53+
${MANAGE} makemigrations
54+
55+
migrate:
56+
@echo "-> Apply database migrations"
57+
${MANAGE} migrate
58+
59+
restart-worker:
60+
${COMPOSE} restart worker
61+
62+
build:
63+
# Build the dev Docker images
64+
${COMPOSE} build
65+
66+
build-full:
67+
# Build the full production Docker image
68+
docker build --target full -t $(IMAGE_NAME) .
69+
70+
regen-fixtures:
71+
@echo "-> Regenerate test fixtures from the running Docker stack"
72+
${COMPOSE} exec -e SCANCODEIO_TEST_FIXTURES_REGEN=1 web ./manage.py test
73+
74+
########################################################################################
75+
# Local venv commands (legacy)
76+
########################################################################################
77+
2378
# Python version can be specified with `$ PYTHON_EXE=python3.x make conf`
2479
PYTHON_EXE?=python3
2580
VENV_LOCATION=.venv
2681
ACTIVATE?=. ${VENV_LOCATION}/bin/activate;
27-
MANAGE=${VENV_LOCATION}/bin/python manage.py
82+
VENV_MANAGE=${VENV_LOCATION}/bin/python manage.py
2883
VIRTUALENV_PYZ=etc/thirdparty/virtualenv.pyz
2984
PIP_ARGS=--find-links=./etc/thirdparty/dummy_dist
3085
# Do not depend on Python to generate the SECRET_KEY
@@ -37,7 +92,6 @@ SCANCODEIO_DB_USER=scancodeio
3792
SCANCODEIO_DB_PASSWORD=scancodeio
3893
POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8
3994
DATE=$(shell date +"%Y-%m-%d_%H%M")
40-
IMAGE_NAME=scancodeio
4195

4296
# Use sudo for postgres, only on Linux
4397
UNAME := $(shell uname)
@@ -70,6 +124,13 @@ envfile:
70124
@mkdir -p $(shell dirname ${ENV_FILE}) && touch ${ENV_FILE}
71125
@echo SECRET_KEY=\"${GET_SECRET_KEY}\" > ${ENV_FILE}
72126

127+
runserver:
128+
DJANGO_RUNSERVER_HIDE_WARNING=true ${VENV_MANAGE} runserver 8001 --insecure
129+
130+
check-deploy:
131+
@echo "-> Check Django deployment settings"
132+
${VENV_MANAGE} check --deploy
133+
73134
doc8:
74135
@echo "-> Run doc8 validation"
75136
@${ACTIVATE} doc8 --max-line-length 100 --ignore-path docs/_build/ --quiet docs/
@@ -89,24 +150,11 @@ check:
89150
@echo "-> Run ABOUT files validation"
90151
@${ACTIVATE} about check --exclude .venv/ --exclude scanpipe/tests/ .
91152

92-
check-deploy:
93-
@echo "-> Check Django deployment settings"
94-
${MANAGE} check --deploy
95-
96153
clean:
97154
@echo "-> Clean the Python env"
98155
rm -rf .venv/ .*cache/ *.egg-info/ build/ dist/
99156
find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete
100157

101-
migrate:
102-
@echo "-> Apply database migrations"
103-
${MANAGE} migrate
104-
105-
upgrade:
106-
@echo "-> Upgrade local git checkout"
107-
@git pull
108-
@$(MAKE) migrate
109-
110158
postgresdb:
111159
@echo "-> Configure PostgreSQL database"
112160
@echo "-> Create database user ${SCANCODEIO_DB_NAME}"
@@ -127,37 +175,13 @@ sqlitedb:
127175
@echo SCANCODEIO_DB_NAME=\"sqlite3.db\" >> ${ENV_FILE}
128176
@$(MAKE) migrate
129177

130-
run:
131-
DJANGO_RUNSERVER_HIDE_WARNING=true ${MANAGE} runserver 8001 --insecure
132-
133-
run-docker-dev:
134-
@echo "-> Run the Docker compose services in dev mode (hot reload on code changes)"
135-
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build --watch
136-
137-
test:
138-
@echo "-> Run the test suite"
139-
${MANAGE} test --noinput
140-
141-
fasttest:
142-
@echo "-> Run the test suite without the PipelinesIntegrationTest"
143-
${MANAGE} test --noinput --exclude-tag slow
144-
145178
worker:
146179
${MANAGE} rqworker --worker-class scancodeio.worker.ScanCodeIOWorker --queue-class scancodeio.worker.ScanCodeIOQueue --verbosity 2
147180

148181
docs:
149182
rm -rf docs/_build/
150183
@${ACTIVATE} sphinx-build docs/ docs/_build/
151184

152-
build:
153-
docker build --target base -t $(IMAGE_NAME) .
154-
155-
build-full:
156-
docker build --target full -t $(IMAGE_NAME) .
157-
158-
bash:
159-
docker run -it $(IMAGE_NAME) bash
160-
161185
docker-images:
162186
@echo "-> Build Docker services"
163187
docker compose build
@@ -174,4 +198,4 @@ offline-package: docker-images
174198
@mkdir -p dist/
175199
@tar -cf dist/scancodeio-offline-package-`git describe --tags`.tar build/
176200

177-
.PHONY: virtualenv conf dev envfile install doc8 check valid check-deploy clean migrate upgrade postgresdb sqlitedb backupdb run run-docker-dev test fasttest docs build bash docker-images offline-package
201+
.PHONY: virtualenv conf dev envfile install doc8 check valid check-deploy clean migrate makemigrations restart-worker postgresdb sqlitedb backupdb run test fasttest regen-fixtures docs build bash shell docker-images offline-package

docker-compose.dev.yml

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
# Dev mode, https://docs.docker.com/compose/how-tos/file-watch/
2-
3-
# Mount the local scanpipe/ directory in the containers
4-
# This can be used to refresh fixtures from the docker container:
5-
# $ docker compose -f docker-compose.yml -f docker-compose.dev.yml up
6-
# $ docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm web bash
7-
# $ SCANCODEIO_TEST_FIXTURES_REGEN=1 ./manage.py test
1+
# Dev mode: overlay for local development with hot reload.
2+
# Usage: $ make run
3+
# See the Makefile for all available commands (test, migrate, bash, etc.)
84

95
name: scancodeio
106

117
x-dev-env: &dev-env
128
SCANCODEIO_DEBUG: "True"
13-
GUNICORN_RELOAD_FLAG: "--reload"
9+
DJANGO_RUNSERVER_HIDE_WARNING: "true"
1410

1511
x-dev-build: &dev-build
1612
context: .
@@ -21,15 +17,29 @@ services:
2117
build: *dev-build
2218
environment:
2319
<<: *dev-env
20+
command: ./manage.py runserver --skip-checks 0.0.0.0:8001
2421
volumes:
2522
- ./scanpipe:/opt/scancodeio/scanpipe
23+
ports:
24+
- "8001:8001"
2625

26+
# Volume mount keeps code in sync. Restart manually with: make restart-worker
2727
worker:
2828
build: *dev-build
2929
environment:
3030
<<: *dev-env
31-
develop:
32-
watch:
33-
- action: sync+restart
34-
path: ./scanpipe
35-
target: /opt/scancodeio/scanpipe
31+
command: ./manage.py rqworker --worker-class scancodeio.worker.ScanCodeIOWorker
32+
--queue-class scancodeio.worker.ScanCodeIOQueue
33+
--verbosity 1
34+
volumes:
35+
- ./scanpipe:/opt/scancodeio/scanpipe
36+
37+
# Disable nginx in dev mode, the runserver serves requests directly.
38+
nginx:
39+
profiles:
40+
- production
41+
42+
# Disable clamav in dev mode, not needed for local development.
43+
clamav:
44+
profiles:
45+
- production

docker-compose.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ services:
1212
#
1313
# For fresh installations (no existing data), this check passes automatically.
1414
db-check:
15-
image: docker.io/library/postgres:17
15+
image: docker.io/library/postgres:17.9
1616
volumes:
1717
- db_data:/var/lib/postgresql/data/:ro
1818
entrypoint: [ "/bin/bash", "-c" ]
@@ -46,7 +46,7 @@ services:
4646
restart: "no"
4747

4848
db:
49-
image: docker.io/library/postgres:17
49+
image: docker.io/library/postgres:17.9
5050
depends_on:
5151
db-check:
5252
condition: service_completed_successfully
@@ -63,7 +63,7 @@ services:
6363
retries: 5
6464

6565
redis:
66-
image: docker.io/library/redis:latest
66+
image: docker.io/library/redis:8.6-alpine
6767
# Enable redis data persistence using the "Append Only File" with the
6868
# default policy of fsync every second. See https://redis.io/topics/persistence
6969
command: redis-server --appendonly yes
@@ -112,7 +112,7 @@ services:
112112
- web
113113

114114
nginx:
115-
image: docker.io/library/nginx:alpine
115+
image: docker.io/library/nginx:1.29-alpine
116116
ports:
117117
- "${NGINX_PUBLISHED_HTTP_PORT:-80}:80"
118118
- "${NGINX_PUBLISHED_HTTPS_PORT:-443}:443"
@@ -125,7 +125,7 @@ services:
125125
restart: always
126126

127127
clamav:
128-
image: docker.io/clamav/clamav:latest
128+
image: docker.io/clamav/clamav:1.5_base
129129
volumes:
130130
- clamav_data:/var/lib/clamav
131131
- workspace:/var/scancodeio/workspace/

scanpipe/tests/test_pipelines.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,10 @@ def test_scanpipe_pipeline_class_download_fetch_exception(self, mock_fetch):
265265
self.assertIn("https://download.url/file.zip could not be fetched.", run.log)
266266

267267
@mock.patch("git.repo.base.Repo.clone_from")
268-
def test_scanpipe_pipeline_class_download_missing_inputs_git_repo(self, mock_clone):
268+
@mock.patch("scanpipe.pipes.fetch.check_url", return_value=True)
269+
def test_scanpipe_pipeline_class_download_missing_inputs_git_repo(
270+
self, mock_check_url, mock_clone
271+
):
269272
project1 = make_project()
270273
run = project1.add_pipeline("do_nothing")
271274
pipeline = run.make_pipeline_instance()
@@ -818,7 +821,10 @@ def test_scanpipe_scan_package_single_file(self):
818821
self.assertPipelineResultEqual(expected_file, scancode_file)
819822

820823
@mock.patch("git.repo.base.Repo.clone_from")
821-
def test_scanpipe_scan_package_single_package_git_repo(self, mock_clone):
824+
@mock.patch("scanpipe.pipes.fetch.check_url", return_value=True)
825+
def test_scanpipe_scan_package_single_package_git_repo(
826+
self, mock_check_url, mock_clone
827+
):
822828
pipeline_name = "scan_single_package"
823829
project1 = make_project()
824830

0 commit comments

Comments
 (0)