From d794ee032c4c01f20660775d0e6833c4ed3d8fae Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 25 Oct 2025 19:49:34 +0200 Subject: [PATCH 01/17] feat: Adds healthcheck to web server --- docker-compose.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 8954b73..77cf550 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,14 @@ services: depends_on: data_handler: condition: service_started + # all the way zoomed out, with hamburg at the center, at least one camera should be returned + healthcheck: + test: > + ["CMD", "curl -s 'http://localhost/camera.php?bbox=-92.52991540527346,30.683278176916133,131.7689595947266,72.87186315234298&zoom=4&width=2552&height=867' | grep '^\[.+\]$'"] + interval: 10s + timeout: 5s + start_period: 30s + retries: 5 data_handler: image: git.hamburg.ccc.de/ccchh/sunders/data_handler:latest From 7332dd8d3c71c9f9c28745e4ad91546a1af7a529 Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 25 Oct 2025 21:20:09 +0200 Subject: [PATCH 02/17] refactor: Increases verbosity of data_handler --- data_handler/Containerfile | 2 +- data_handler/utils/entrypoint.sh | 2 +- data_handler/utils/update_camera.sh | 4 ++-- home/sunders/update_cameras/update_camera.sh | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data_handler/Containerfile b/data_handler/Containerfile index 7215bf9..4c08fa6 100644 --- a/data_handler/Containerfile +++ b/data_handler/Containerfile @@ -5,4 +5,4 @@ COPY ./data_init/*.sql /opt/init/init.sql ENTRYPOINT ["/opt/entrypoint.sh"] -CMD ["/usr/sbin/dcrond", "-f" ] \ No newline at end of file +CMD ["/bin/sh", "-c", "/usr/sbin/dcrond -f -d 5 > /var/log/dcrond.log 2>&1"] \ No newline at end of file diff --git a/data_handler/utils/entrypoint.sh b/data_handler/utils/entrypoint.sh index c4dc346..2109d85 100755 --- a/data_handler/utils/entrypoint.sh +++ b/data_handler/utils/entrypoint.sh @@ -8,7 +8,7 @@ set -e cat<> /var/log/update_camera_$(date +\%Y\%m\%d\%H\%M\%S).log 2>&1 EOF #################################################################################################### diff --git a/data_handler/utils/update_camera.sh b/data_handler/utils/update_camera.sh index 25d23c8..4107d9f 100644 --- a/data_handler/utils/update_camera.sh +++ b/data_handler/utils/update_camera.sh @@ -63,7 +63,7 @@ do rm "change_file.osc.gz" fi - echo `date "+%d/%m/%Y %H:%M"`" - Start processing sequence number $curSeqNum" > "$logFileName" + echo `date "+%d/%m/%Y %H:%M"`" - Start processing sequence number $curSeqNum of $newSeqNum" > "$logFileName" targetDirName=`echo "000000000$curSeqNum" | sed 's#.*\(...\)\(...\)\(...\)$#\1/\2/\3.osc.gz#'` targetDirName="$REPLICATE_URL/$targetDirName" @@ -87,7 +87,7 @@ do targetDirName=`echo "$targetDirName" | sed 's/.osc.gz$/.state.txt/'` curl -L "$targetDirName" -o lastState.txt 2>&1 | tee -a $logFileName - echo `date "+%d/%m/%Y %H:%M"`" - Finish processing sequence number $curSeqNum" | tee -a "$logFileName" + echo `date "+%d/%m/%Y %H:%M"`" - Finish processing sequence number $curSeqNum of $newSeqNum" | tee -a "$logFileName" done rm "/var/lock/update_camera" diff --git a/home/sunders/update_cameras/update_camera.sh b/home/sunders/update_cameras/update_camera.sh index b605ee4..b6d3338 100644 --- a/home/sunders/update_cameras/update_camera.sh +++ b/home/sunders/update_cameras/update_camera.sh @@ -60,7 +60,7 @@ do rm "change_file.osc.gz" fi - echo `date "+%d/%m/%Y %H:%M"`" - Start processing sequence number $curSeqNum" > "$logFileName" + echo `date "+%d/%m/%Y %H:%M"`" - Start processing sequence number $curSeqNum of $newSeqNum" > "$logFileName" targetDirName=`echo "000000000$curSeqNum" | sed 's#.*\(...\)\(...\)\(...\)$#\1/\2/\3.osc.gz#'` targetDirName="$REPLICATE_URL/$targetDirName" @@ -84,7 +84,7 @@ do targetDirName=`echo "$targetDirName" | sed 's/.osc.gz$/.state.txt/'` wget -nv "$targetDirName" -O lastState.txt 2>&1 | tee -a $logFileName - echo `date "+%d/%m/%Y %H:%M"`" - Finish processing sequence number $curSeqNum" | tee -a "$logFileName" + echo `date "+%d/%m/%Y %H:%M"`" - Finish processing sequence number $curSeqNum of $newSeqNum" | tee -a "$logFileName" done rm "/var/lock/update_camera" From ddc73f7207cb7c39a888a0882da0ee41b3481edd Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 25 Oct 2025 21:20:27 +0200 Subject: [PATCH 03/17] chore: Immediately starts `update_camera` on container startup --- data_handler/utils/entrypoint.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/data_handler/utils/entrypoint.sh b/data_handler/utils/entrypoint.sh index 2109d85..9e726e8 100755 --- a/data_handler/utils/entrypoint.sh +++ b/data_handler/utils/entrypoint.sh @@ -20,7 +20,15 @@ php /opt/init_db.php echo "Prescripts done" #################################################################################################### -### Run cmd +### Run script once immediately +#################################################################################################### + +echo "Running update once initially..." +sh /opt/update_camera.sh >> /var/log/update_camera_$(date +\%Y\%m\%d\%H\%M\%S).log 2>&1 +echo "Initial update done" + +#################################################################################################### +### Run cron to schedule periodic task #################################################################################################### # see: https://github.com/dubiousjim/dcron/issues/13 From c53b37e8f0197de78a38508f28e7f4c9ef1fbef8 Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 25 Oct 2025 21:21:06 +0200 Subject: [PATCH 04/17] feat: Adds healthcheck that restarts `data_handler`, when any error is printed to log files --- docker-compose.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 77cf550..a74b7a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,6 +57,13 @@ services: db: condition: service_healthy restart: true + # if the latest `update_camera_*.log` contains "error", fail the healthcheck + healthcheck: + test: ["CMD", "sh", "-c", "ls /var/log | grep '^update_camera_' | xargs -I {} sh -c 'grep -q error /var/log/{} || exit 0; exit 1'"] + interval: 10s + timeout: 5s + start_period: 30s + retries: 5 volumes: mariadb: \ No newline at end of file From f1dd6f9b2f55a16d99e38efd5a8e86249018940e Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 25 Oct 2025 21:22:23 +0200 Subject: [PATCH 05/17] fix: Restarts any container unless stopped by user --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index a74b7a9..c957f4c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ services: db: image: mariadb:13.0.2 + restart: unless-stopped command: --max_allowed_packet=3250585600 environment: MYSQL_ROOT_PASSWORD: rootpassword # ${{secrets.MYSQL_ROOT_PASSWORD}} @@ -18,6 +19,7 @@ services: web: image: git.hamburg.ccc.de/ccchh/sunders/web:latest + restart: unless-stopped environment: MYSQL_HOST: db MYSQL_DB: camera # ${{secrets.MYSQL_DATABASE}} @@ -44,6 +46,7 @@ services: data_handler: image: git.hamburg.ccc.de/ccchh/sunders/data_handler:latest + restart: unless-stopped environment: MYSQL_HOST: db MYSQL_DB: camera # ${{secrets.MYSQL_DATABASE}} From 6f633a400c8173dbf1177ad79431dcaff12c7254 Mon Sep 17 00:00:00 2001 From: aso Date: Sat, 1 Nov 2025 12:20:36 +0100 Subject: [PATCH 06/17] first changes for sync of instances --- docker-compose-dev.yml | 72 ++++++++++++++++++++++++++++++++++ web/www/sunders/sync-state.php | 27 +++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 docker-compose-dev.yml create mode 100644 web/www/sunders/sync-state.php diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000..58c2af2 --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,72 @@ +services: + db: + image: mariadb:12.0.2 + restart: unless-stopped + command: --max_allowed_packet=3250585600 + environment: + MYSQL_ROOT_PASSWORD: rootpassword # ${{secrets.MYSQL_ROOT_PASSWORD}} + MYSQL_DATABASE: camera # ${{secrets.MYSQL_DATABASE}} + MYSQL_USER: camera # ${{secrets.MYSQL_USER}} + MYSQL_PASSWORD: camerapassword # ${{secrets.MYSQL_PASSWORD}} + volumes: + - ./mariadb:/var/lib/mysql:Z + healthcheck: + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpassword"] + interval: 10s + timeout: 5s + start_period: 30s + retries: 5 + + web: + image: git.hamburg.ccc.de/ccchh/sunders/web:latest + restart: unless-stopped + environment: + MYSQL_HOST: db + MYSQL_DB: camera # ${{secrets.MYSQL_DATABASE}} + CAMERA_SELECT_USER: camera_select # ${{secrets.CAMERA_SELECT_USER}} + CAMERA_SELECT_USER_PASSWORD: camera_selectpassword # ${{secrets.CAMERA_SELECT_USER_PASSWORD}} + DEFAULT_ZOOM: 12 + DEFAULT_LAT: 0 + DEFAULT_LON: 0 + DEFAULT_LANGUAGE: en + IMPRESSUM_URL: https://hamburg.ccc.de/imprint/ + ports: + - "8081:80" + volumes: + - ./web/www/sunders:/var/www/html:Z + depends_on: + db: + condition: service_started + # all the way zoomed out, with hamburg at the center, at least one camera should be returned + healthcheck: + test: > + ["CMD", "curl -s 'http://localhost/camera.php?bbox=-92.52991540527346,30.683278176916133,131.7689595947266,72.87186315234298&zoom=4&width=2552&height=867' | grep '^\[.+\]$'"] + interval: 10s + timeout: 5s + retries: 5 + + data_handler: + image: git.hamburg.ccc.de/ccchh/sunders/data_handler:latest + restart: unless-stopped + environment: + MYSQL_HOST: db + MYSQL_DB: camera # ${{secrets.MYSQL_DATABASE}} + MYSQL_USER: root # ${{secrets.MYSQL_USER}} + MYSQL_PASSWORD: rootpassword # ${{secrets.MYSQL_ROOT_PASSWORD}} + CAMERA_USER: camera # ${{secrets.CAMERA_USER}} + CAMERA_USER_PASSWORD: camerapassword # ${{secrets.CAMERA_USER_PASSWORD}} + CAMERA_SELECT_USER: camera_select # ${{secrets.CAMERA_SELECT_USER}} + CAMERA_SELECT_USER_PASSWORD: camera_selectpassword # ${{secrets.CAMERA_SELECT_USER_PASSWORD}} + depends_on: + db: + condition: service_healthy + restart: true + # if the latest `update_camera_*.log` contains "error", fail the healthcheck + healthcheck: + test: ["CMD", "sh", "-c", "ls /var/log | grep '^update_camera_' | xargs -I {} sh -c 'grep -q error /var/log/{} || exit 0; exit 1'"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + mariadb: \ No newline at end of file diff --git a/web/www/sunders/sync-state.php b/web/www/sunders/sync-state.php new file mode 100644 index 0000000..095e92c --- /dev/null +++ b/web/www/sunders/sync-state.php @@ -0,0 +1,27 @@ +connect_errno) { + header('Content-type: application/json'); + $result = '{"error":"error while connecting to db : ' . $mysqli->error . '"}'; + echo $result; + exit; + } + + $syncstate_querry = $mysqli->query("SELECT * FROM sync_state WHERE k = 'sequenceNumber'"); + + while($row = $syncstate_querry->fetch_assoc()) { + $syncstate = array('sequenceNumber' => $row["v"]); + } + + $result = json_encode($syncstate); + + $mysqli->close(); + + header('Content-type: application/json; Charset : utf-8'); + echo $result; +?> From c186886df71dd70ce0e835915709b96f35b326d1 Mon Sep 17 00:00:00 2001 From: aso Date: Sat, 1 Nov 2025 15:34:50 +0100 Subject: [PATCH 07/17] modified health check for web --- docker-compose-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 58c2af2..28c7c46 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -39,11 +39,11 @@ services: condition: service_started # all the way zoomed out, with hamburg at the center, at least one camera should be returned healthcheck: - test: > - ["CMD", "curl -s 'http://localhost/camera.php?bbox=-92.52991540527346,30.683278176916133,131.7689595947266,72.87186315234298&zoom=4&width=2552&height=867' | grep '^\[.+\]$'"] + test: ["CMD", "curl", "-f", "http://localhost/sync-state.php"] interval: 10s timeout: 5s retries: 5 + start_period: 10s data_handler: image: git.hamburg.ccc.de/ccchh/sunders/data_handler:latest From 7727c56351bae73b7de6843526cc2597d991a0f1 Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 1 Nov 2025 20:55:49 +0100 Subject: [PATCH 08/17] feat: `web` healthcheck returns 503 status code if database is unavailable --- docker-compose.yml | 5 ++--- web/www/sunders/sync-state.php | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c957f4c..e97db01 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,12 +33,11 @@ services: ports: - "8081:80" depends_on: - data_handler: + db: condition: service_started # all the way zoomed out, with hamburg at the center, at least one camera should be returned healthcheck: - test: > - ["CMD", "curl -s 'http://localhost/camera.php?bbox=-92.52991540527346,30.683278176916133,131.7689595947266,72.87186315234298&zoom=4&width=2552&height=867' | grep '^\[.+\]$'"] + test: ["CMD", "curl", "-f", "http://localhost/sync-state.php"] interval: 10s timeout: 5s start_period: 30s diff --git a/web/www/sunders/sync-state.php b/web/www/sunders/sync-state.php index 095e92c..11ecef5 100644 --- a/web/www/sunders/sync-state.php +++ b/web/www/sunders/sync-state.php @@ -6,8 +6,9 @@ /* Connect to database */ $mysqli = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB); if($mysqli->connect_errno) { + http_response_code(503); header('Content-type: application/json'); - $result = '{"error":"error while connecting to db : ' . $mysqli->error . '"}'; + $result = '{"error":"Database unavailable"}'; echo $result; exit; } From 54e78f3f4ef6831c8d101dd7957f0d3bf46c221f Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 1 Nov 2025 21:23:38 +0100 Subject: [PATCH 09/17] docs: Adds instructions about `dev` override chore: Applies docker naming convention to files --- README.md | 6 ++-- docker-compose-dev.yml | 72 ------------------------------------------ docker-compose.dev.yml | 13 ++++++++ 3 files changed, 15 insertions(+), 76 deletions(-) delete mode 100644 docker-compose-dev.yml create mode 100644 docker-compose.dev.yml diff --git a/README.md b/README.md index b2e535c..e613464 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,10 @@ To run Surveillance using docker, decide between development/testing or producti 1. Clone this repository -2. Run `docker compose up` and wait for services to start up +2. Run `docker compose -f docker-compose.yml -f docker-compose.dev.yml up` and wait for services to start up 3. Visit `http://localhost:8081/` in a browser; you should see an interactive OpenStreetMap -_tbd.: Populate camera data_ - ### Production 1. Close this repository @@ -51,7 +49,7 @@ _tbd.: Populate camera data_ 3. Visit `http://localhost:8081/` in a browser to open the web interface -_tbd.: Populate camera data_ +4. ## Surveillance nodes diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml deleted file mode 100644 index 28c7c46..0000000 --- a/docker-compose-dev.yml +++ /dev/null @@ -1,72 +0,0 @@ -services: - db: - image: mariadb:12.0.2 - restart: unless-stopped - command: --max_allowed_packet=3250585600 - environment: - MYSQL_ROOT_PASSWORD: rootpassword # ${{secrets.MYSQL_ROOT_PASSWORD}} - MYSQL_DATABASE: camera # ${{secrets.MYSQL_DATABASE}} - MYSQL_USER: camera # ${{secrets.MYSQL_USER}} - MYSQL_PASSWORD: camerapassword # ${{secrets.MYSQL_PASSWORD}} - volumes: - - ./mariadb:/var/lib/mysql:Z - healthcheck: - test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpassword"] - interval: 10s - timeout: 5s - start_period: 30s - retries: 5 - - web: - image: git.hamburg.ccc.de/ccchh/sunders/web:latest - restart: unless-stopped - environment: - MYSQL_HOST: db - MYSQL_DB: camera # ${{secrets.MYSQL_DATABASE}} - CAMERA_SELECT_USER: camera_select # ${{secrets.CAMERA_SELECT_USER}} - CAMERA_SELECT_USER_PASSWORD: camera_selectpassword # ${{secrets.CAMERA_SELECT_USER_PASSWORD}} - DEFAULT_ZOOM: 12 - DEFAULT_LAT: 0 - DEFAULT_LON: 0 - DEFAULT_LANGUAGE: en - IMPRESSUM_URL: https://hamburg.ccc.de/imprint/ - ports: - - "8081:80" - volumes: - - ./web/www/sunders:/var/www/html:Z - depends_on: - db: - condition: service_started - # all the way zoomed out, with hamburg at the center, at least one camera should be returned - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/sync-state.php"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 10s - - data_handler: - image: git.hamburg.ccc.de/ccchh/sunders/data_handler:latest - restart: unless-stopped - environment: - MYSQL_HOST: db - MYSQL_DB: camera # ${{secrets.MYSQL_DATABASE}} - MYSQL_USER: root # ${{secrets.MYSQL_USER}} - MYSQL_PASSWORD: rootpassword # ${{secrets.MYSQL_ROOT_PASSWORD}} - CAMERA_USER: camera # ${{secrets.CAMERA_USER}} - CAMERA_USER_PASSWORD: camerapassword # ${{secrets.CAMERA_USER_PASSWORD}} - CAMERA_SELECT_USER: camera_select # ${{secrets.CAMERA_SELECT_USER}} - CAMERA_SELECT_USER_PASSWORD: camera_selectpassword # ${{secrets.CAMERA_SELECT_USER_PASSWORD}} - depends_on: - db: - condition: service_healthy - restart: true - # if the latest `update_camera_*.log` contains "error", fail the healthcheck - healthcheck: - test: ["CMD", "sh", "-c", "ls /var/log | grep '^update_camera_' | xargs -I {} sh -c 'grep -q error /var/log/{} || exit 0; exit 1'"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - mariadb: \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..15542fa --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,13 @@ +services: + db: + volumes: + - ./mariadb:/var/lib/mysql:Z + + web: + volumes: + - ./web/www/sunders:/var/www/html:Z + + data_handler: + volumes: + - ./data_handler/utils:/opt:Z + - ./data_handler/data_init:/opt/init/init.sql:Z \ No newline at end of file From d9529cf6c088105d5534b1438ef7aeef5052bc5d Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 1 Nov 2025 21:27:47 +0100 Subject: [PATCH 10/17] fix: Enables PHP log output when running in `development` --- .gitignore | 5 ++++- docker-compose.dev.yml | 2 ++ web/www/sunders/add-lists.php | 1 - web/www/sunders/camera.php | 1 - web/www/sunders/config.php | 11 +++++++++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 09f94a6..1febf73 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ lastState.txt lastStatisticsUpdate.txt log.* state.txt -migrations \ No newline at end of file +migrations + +# created when running development environment +mariadb/** \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 15542fa..61d0016 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -6,6 +6,8 @@ services: web: volumes: - ./web/www/sunders:/var/www/html:Z + environment: + APP_ENV: development data_handler: volumes: diff --git a/web/www/sunders/add-lists.php b/web/www/sunders/add-lists.php index da9f396..12fc0c0 100644 --- a/web/www/sunders/add-lists.php +++ b/web/www/sunders/add-lists.php @@ -1,5 +1,4 @@ \ No newline at end of file From ea5e30530476b8d91f3c4dca7739c4d459e565fb Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 1 Nov 2025 21:28:30 +0100 Subject: [PATCH 11/17] fix: Handles issue where error handler was skipped, if database DNS request fails --- web/www/sunders/sync-state.php | 40 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/web/www/sunders/sync-state.php b/web/www/sunders/sync-state.php index 11ecef5..3cb8ef0 100644 --- a/web/www/sunders/sync-state.php +++ b/web/www/sunders/sync-state.php @@ -2,27 +2,29 @@ error_reporting(0); include $pathToWebFolder.'config.php'; - - /* Connect to database */ - $mysqli = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB); - if($mysqli->connect_errno) { - http_response_code(503); - header('Content-type: application/json'); - $result = '{"error":"Database unavailable"}'; - echo $result; - exit; - } - - $syncstate_querry = $mysqli->query("SELECT * FROM sync_state WHERE k = 'sequenceNumber'"); - - while($row = $syncstate_querry->fetch_assoc()) { - $syncstate = array('sequenceNumber' => $row["v"]); + try { + $mysqli = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB); + if($mysqli->connect_errno) { + throw new Exception("Could not connect to database"); } - $result = json_encode($syncstate); + $syncstate_querry = $mysqli->query("SELECT * FROM sync_state WHERE k = 'sequenceNumber'"); - $mysqli->close(); + while($row = $syncstate_querry->fetch_assoc()) { + $syncstate = array('sequenceNumber' => $row["v"]); + } - header('Content-type: application/json; Charset : utf-8'); - echo $result; + $result = json_encode($syncstate); + + $mysqli->close(); + + header('Content-type: application/json; Charset : utf-8'); + echo $result; + mysqli_report(MYSQLI_REPORT_OFF); + } catch (Exception $e) { + http_response_code(503); + header('Content-type: application/json'); + $result = '{"error":"Database unavailable"}'; + echo $result; + } ?> From b6c05e526507b162890354509867aeb68dd0a05f Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 1 Nov 2025 21:28:59 +0100 Subject: [PATCH 12/17] docs: Removes incorrect comment --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index e97db01..3fae64e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,7 +35,6 @@ services: depends_on: db: condition: service_started - # all the way zoomed out, with hamburg at the center, at least one camera should be returned healthcheck: test: ["CMD", "curl", "-f", "http://localhost/sync-state.php"] interval: 10s From f5ef9adc4db4534cde804892eac9347030b78ceb Mon Sep 17 00:00:00 2001 From: Vincent Mahnke Date: Sat, 1 Nov 2025 21:29:18 +0100 Subject: [PATCH 13/17] docs: Adds information about changes when running in a development environment --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e613464..a46ecb0 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,17 @@ To run Surveillance using docker, decide between development/testing or producti 3. Visit `http://localhost:8081/` in a browser; you should see an interactive OpenStreetMap +4. You can see most cameras on the map immediately; the `data_handler` background process continuously applies updates from OpenStreetMap which become visible after refrshing the page + +5. Appending `-f docker-compose.dev.yml` applies these changes: + + - PHP won't supress any errors; to disable this, remove `return;` in `./web/www/sunders/config.php` + + - Making changes in the `web` will immediately apply them to the running containers; try modifying `web/www/sunders/index.php` + + - Making changes in the `data_handler` will immediately apply them to the running containers (try modifying `data_handler/utils/update_camera.sh`) + + - The host has access to database files at `./mariadb` ### Production 1. Close this repository @@ -49,7 +60,7 @@ To run Surveillance using docker, decide between development/testing or producti 3. Visit `http://localhost:8081/` in a browser to open the web interface -4. +4. You can see most cameras on the map immediately; the `data_handler` background process continuously applies updates from OpenStreetMap which become visible after refrshing the page ## Surveillance nodes From 3013bf42b1c086439ad000a7f997a80034e53c56 Mon Sep 17 00:00:00 2001 From: ViMaSter Date: Sat, 1 Nov 2025 21:49:46 +0100 Subject: [PATCH 14/17] fix: Adds missing documentation hint for secret replacement --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3fae64e..99ed328 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ services: volumes: - mariadb:/var/lib/mysql healthcheck: - test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpassword"] + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpassword"] # ${{secrets.MYSQL_ROOT_PASSWORD}} interval: 10s timeout: 5s start_period: 30s From 13f02116248d5f0ea9e9fa57bb0d4cee477cf1e9 Mon Sep 17 00:00:00 2001 From: ViMaSter Date: Sun, 2 Nov 2025 12:47:33 +0100 Subject: [PATCH 15/17] revert: Uses previous port mapping --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 99ed328..290227d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,7 +31,7 @@ services: DEFAULT_LANGUAGE: en IMPRESSUM_URL: https://hamburg.ccc.de/imprint/ ports: - - "8081:80" + - "8080:80" depends_on: db: condition: service_started From aa6ef7f3626cb78fb8f3fab710b7ae06a10b500c Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Sun, 15 Nov 2026 14:24:47 +0100 Subject: [PATCH 16/17] fix: Pin PHP to php2shell-patched release Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- web/Containerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/Containerfile b/web/Containerfile index c84f8a7..984e64c 100644 --- a/web/Containerfile +++ b/web/Containerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/php:apache +FROM docker.io/library/php:8.5.12-apache RUN docker-php-ext-install mysqli bcmath From 5ce403cec251926d6887a827eaa7861b460707e0 Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Sun, 15 Nov 2026 14:28:07 +0100 Subject: [PATCH 17/17] fix: Send data handler output to container logs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- data_handler/Containerfile | 2 +- data_handler/utils/entrypoint.sh | 5 +++-- data_handler/utils/run_update_camera.sh | 12 ++++++++++++ docker-compose.yml | 4 ++-- 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 data_handler/utils/run_update_camera.sh diff --git a/data_handler/Containerfile b/data_handler/Containerfile index 4c08fa6..0da9985 100644 --- a/data_handler/Containerfile +++ b/data_handler/Containerfile @@ -5,4 +5,4 @@ COPY ./data_init/*.sql /opt/init/init.sql ENTRYPOINT ["/opt/entrypoint.sh"] -CMD ["/bin/sh", "-c", "/usr/sbin/dcrond -f -d 5 > /var/log/dcrond.log 2>&1"] \ No newline at end of file +CMD ["/usr/sbin/dcrond", "-f", "-d", "5"] \ No newline at end of file diff --git a/data_handler/utils/entrypoint.sh b/data_handler/utils/entrypoint.sh index 9e726e8..1933ef1 100755 --- a/data_handler/utils/entrypoint.sh +++ b/data_handler/utils/entrypoint.sh @@ -1,6 +1,7 @@ #!/bin/sh set -e +printf 'ok\n' > /run/update_camera.status #################################################################################################### ### Crontab settings @@ -8,7 +9,7 @@ set -e cat<> /var/log/update_camera_$(date +\%Y\%m\%d\%H\%M\%S).log 2>&1 +*/15 * * * * sh /opt/run_update_camera.sh EOF #################################################################################################### @@ -24,7 +25,7 @@ echo "Prescripts done" #################################################################################################### echo "Running update once initially..." -sh /opt/update_camera.sh >> /var/log/update_camera_$(date +\%Y\%m\%d\%H\%M\%S).log 2>&1 +sh /opt/run_update_camera.sh echo "Initial update done" #################################################################################################### diff --git a/data_handler/utils/run_update_camera.sh b/data_handler/utils/run_update_camera.sh new file mode 100644 index 0000000..431d3e1 --- /dev/null +++ b/data_handler/utils/run_update_camera.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +status_file=/run/update_camera.status +status_file_tmp="${status_file}.$$" + +if sh /opt/update_camera.sh 2>&1 | tee /proc/1/fd/1 | grep -i error >/dev/null; then + printf 'error\n' > "$status_file_tmp" +else + printf 'ok\n' > "$status_file_tmp" +fi + +mv "$status_file_tmp" "$status_file" diff --git a/docker-compose.yml b/docker-compose.yml index 290227d..ff2f3f3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -58,9 +58,9 @@ services: db: condition: service_healthy restart: true - # if the latest `update_camera_*.log` contains "error", fail the healthcheck + # if the latest update output contains "error", fail the healthcheck healthcheck: - test: ["CMD", "sh", "-c", "ls /var/log | grep '^update_camera_' | xargs -I {} sh -c 'grep -q error /var/log/{} || exit 0; exit 1'"] + test: ["CMD", "sh", "-c", "test \"$(cat /run/update_camera.status)\" = ok"] interval: 10s timeout: 5s start_period: 30s