diff --git a/.ddev/config.yaml b/.ddev/config.yaml deleted file mode 100644 index 6ea79ab..0000000 --- a/.ddev/config.yaml +++ /dev/null @@ -1,296 +0,0 @@ -name: enter -type: symfony -docroot: public -php_version: "8.5" -webserver_type: nginx-fpm -xdebug_enabled: false -additional_hostnames: [] -additional_fqdns: [] -database: - type: mariadb - version: "11.8" -use_dns_when_possible: true -composer_version: "2" -web_environment: [] -nodejs_version: "24" -corepack_enable: false -disable_upload_dirs_warning: true - -# Key features of DDEV's config.yaml: - -# name: # Name of the project, automatically provides -# http://projectname.ddev.site and https://projectname.ddev.site -# If the name is omitted, the project will take the name of the enclosing directory, -# which is useful if you want to have a copy of the project side by side with this one. - -# type: # asterios, backdrop, cakephp, codeigniter, craftcms, drupal, drupal6, drupal7, drupal8, drupal9, drupal10, drupal11, drupal12, generic, joomla, laravel, magento, magento2, php, shopware6, silverstripe, symfony, typo3, wordpress, wp-bedrock -# See https://docs.ddev.com/en/stable/users/quickstart/ for more -# information on the different project types - -# docroot: # Relative path to the directory containing index.php. - -# php_version: "8.4" # PHP version to use, "5.6" through "8.5" - -# You can explicitly specify the webimage but this -# is not recommended, as the images are often closely tied to DDEV's behavior, -# so this can break upgrades. - -# webimage: -# It’s unusual to change this option, and we don’t recommend it without Docker experience and a good reason. -# Typically, this means additions to the existing web image using a .ddev/web-build/Dockerfile.* - -# database: -# type: # mysql, mariadb, postgres -# version: # database version, like "10.11" or "8.0" -# MariaDB versions can be 5.5-10.8, 10.11, 11.4, 11.8, 12.3 -# MySQL versions can be 5.5-8.0, 8.4 -# PostgreSQL versions can be 9-18 - -# router_http_port: # Port to be used for http (defaults to global configuration, usually 80) -# router_https_port: # Port for https (defaults to global configuration, usually 443) - -# xdebug_enabled: false # Set to true to enable Xdebug and "ddev start" or "ddev restart" -# Note that for most people the commands -# "ddev xdebug" to enable Xdebug and "ddev xdebug off" to disable it work better, -# as leaving Xdebug enabled all the time is a big performance hit. - -# xhgui_http_port: "8143" -# xhgui_https_port: "8142" -# The XHGui ports can be changed from the default 8143 and 8142 -# Very rarely used - -# host_xhgui_port: "8142" -# Can be used to change the host binding port of the XHGui -# application. Rarely used; only when port conflict and -# bind_all_ports is used (normally with router disabled) - -# xhprof_mode: [prepend|xhgui|global] -# Default is "xhgui" - -# webserver_type: nginx-fpm, apache-fpm, generic - -# timezone: Europe/Berlin -# If timezone is unset, DDEV will attempt to derive it from the host system timezone -# using the $TZ environment variable or the /etc/localtime symlink. -# This is the timezone used in the containers and by PHP; -# it can be set to any valid timezone, -# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones -# For example Europe/Dublin or MST7MDT - -# composer_root: -# Relative path to the Composer root directory from the project root. This is -# the directory which contains the composer.json and where all Composer related -# commands are executed. - -# composer_version: "2" -# You can set it to "" or "2" (default) for Composer v2 -# to use the latest major version available at the time your container is built. -# It is also possible to use any other Composer version channel. This includes: -# - 2.2 (latest Composer LTS version) -# - stable -# - preview -# - snapshot -# Alternatively, an explicit Composer version may be specified, for example "2.2.18". -# To reinstall Composer after the image was built, run "ddev utility rebuild". - -# nodejs_version: "24" -# change from the default system Node.js version to any other version. -# See https://docs.ddev.com/en/stable/users/configuration/config/#nodejs_version for more information -# and https://www.npmjs.com/package/n#specifying-nodejs-versions for the full documentation. - -# corepack_enable: false -# Change to 'true' to 'corepack enable' and gain access to latest versions of yarn/pnpm - -# additional_hostnames: -# - somename -# - someothername -# would provide http and https URLs for "somename.ddev.site" -# and "someothername.ddev.site". - -# additional_fqdns: -# - example.com -# - sub1.example.com -# would provide http and https URLs for "example.com" and "sub1.example.com" -# Please take care with this because it can cause great confusion. - -# upload_dirs: "custom/upload/dir" -# -# upload_dirs: -# - custom/upload/dir -# - ../private -# -# would set the destination paths for ddev import-files to /custom/upload/dir -# When Mutagen is enabled this path is bind-mounted so that all the files -# in the upload_dirs don't have to be synced into Mutagen. - -# disable_upload_dirs_warning: false -# If true, turns off the normal warning that says -# "You have Mutagen enabled and your 'php' project type doesn't have upload_dirs set" - -# ddev_version_constraint: "" -# Example: -# ddev_version_constraint: ">= 1.24.8" -# This will enforce that the running ddev version is within this constraint. -# See https://github.com/Masterminds/semver#checking-version-constraints for -# supported constraint formats - -# working_dir: -# web: /var/www/html -# db: /home -# would set the default working directory for the web and db services. -# These values specify the destination directory for ddev ssh and the -# directory in which commands passed into ddev exec are run. - -# omit_containers: [db, ddev-ssh-agent] -# Currently only these containers are supported. Some containers can also be -# omitted globally in the ~/.ddev/global_config.yaml. Note that if you omit -# the "db" container, several standard features of DDEV that access the -# database container will be unusable. In the global configuration it is also -# possible to omit ddev-router, but not here. - -# performance_mode: "global" -# DDEV offers performance optimization strategies to improve the filesystem -# performance depending on your host system. Should be configured globally. -# -# If set, will override the global config. Possible values are: -# - "global": uses the value from the global config. -# - "none": disables performance optimization for this project. -# - "mutagen": enables Mutagen for this project. -# -# See https://docs.ddev.com/en/stable/users/install/performance/#mutagen - -# fail_on_hook_fail: False -# Decide whether 'ddev start' should be interrupted by a failing hook - -# host_https_port: "59002" -# The host port binding for https can be explicitly specified. It is -# dynamic unless otherwise specified. -# This is not used by most people, most people use the *router* instead -# of the localhost port. - -# host_webserver_port: "59001" -# The host port binding for the ddev-webserver can be explicitly specified. It is -# dynamic unless otherwise specified. -# This is not used by most people, most people use the *router* instead -# of the localhost port. - -# host_db_port: "59002" -# The host port binding for the ddev-dbserver can be explicitly specified. It is dynamic -# unless explicitly specified. - -# mailpit_http_port: "8025" -# mailpit_https_port: "8026" -# The Mailpit ports can be changed from the default 8025 and 8026 - -# host_mailpit_port: "8025" -# The mailpit port is not normally bound on the host at all, instead being routed -# through ddev-router, but it can be bound directly to localhost if specified here. - -# webimage_extra_packages: ['php${DDEV_PHP_VERSION}-tidy', 'php${DDEV_PHP_VERSION}-yac'] -# Extra Debian packages that are needed in the webimage can be added here - -# dbimage_extra_packages: [netcat, telnet, sudo] -# Extra Debian packages that are needed in the dbimage can be added here - -# use_dns_when_possible: true -# If the host has internet access and the domain configured can -# successfully be looked up, DNS will be used for hostname resolution -# instead of editing /etc/hosts -# Defaults to true - -# project_tld: ddev.site -# The top-level domain used for project URLs -# The default "ddev.site" allows DNS lookup via a wildcard - -# share_default_provider: ngrok -# The default share provider to use for "ddev share" -# Defaults to global configuration, usually "ngrok" -# Can be "ngrok" or "cloudflared" or the name of a custom provider from .ddev/share-providers/ - -# share_provider_args: --basic-auth username:pass1234 -# Provide extra flags to the share provider script -# See https://docs.ddev.com/en/stable/users/configuration/config/#share_provider_args - -# disable_settings_management: false -# If true, DDEV will not create CMS-specific settings files like -# Drupal's settings.php/settings.ddev.php or TYPO3's additional.php -# In this case the user must provide all such settings. - -# You can inject environment variables into the web container with: -# web_environment: -# - SOMEENV=somevalue -# - SOMEOTHERENV=someothervalue - -# no_project_mount: false -# (Experimental) If true, DDEV will not mount the project into the web container; -# the user is responsible for mounting it manually or via a script. -# This is to enable experimentation with alternate file mounting strategies. -# For advanced users only! - -# bind_all_interfaces: false -# If true, host ports will be bound on all network interfaces, -# not the localhost interface only. This means that ports -# will be available on the local network if the host firewall -# allows it. - -# default_container_timeout: 120 -# The default time that DDEV waits for all containers to become ready can be increased from -# the default 120. This helps in importing huge databases, for example. - -#web_extra_exposed_ports: -#- name: nodejs -# container_port: 3000 -# http_port: 2999 -# https_port: 3000 -#- name: something -# container_port: 4000 -# https_port: 4000 -# http_port: 3999 -# Allows a set of extra ports to be exposed via ddev-router -# Fill in all three fields even if you don’t intend to use the https_port! -# If you don’t add https_port, then it defaults to 0 and ddev-router will fail to start. -# -# The port behavior on the ddev-webserver must be arranged separately, for example -# using web_extra_daemons. -# For example, with a web app on port 3000 inside the container, this config would -# expose that web app on https://.ddev.site:9999 and http://.ddev.site:9998 -# web_extra_exposed_ports: -# - name: myapp -# container_port: 3000 -# http_port: 9998 -# https_port: 9999 - -#web_extra_daemons: -#- name: "http-1" -# command: "/var/www/html/node_modules/.bin/http-server -p 3000" -# directory: /var/www/html -#- name: "http-2" -# command: "/var/www/html/node_modules/.bin/http-server /var/www/html/sub -p 3000" -# directory: /var/www/html - -# override_config: false -# By default, config.*.yaml files are *merged* into the configuration -# But this means that some things can't be overridden -# For example, if you have 'use_dns_when_possible: true' you can't override it with a merge -# and you can't erase existing hooks or all environment variables. -# However, with "override_config: true" in a particular config.*.yaml file, -# 'use_dns_when_possible: false' can override the existing values, and -# hooks: -# post-start: [] -# or -# web_environment: [] -# or -# additional_hostnames: [] -# can have their intended effect. 'override_config' affects only behavior of the -# config.*.yaml file it exists in. - -# Many DDEV commands can be extended to run tasks before or after the -# DDEV command is executed, for example "post-start", "post-import-db", -# "pre-composer", "post-composer" -# See https://docs.ddev.com/en/stable/users/extend/custom-commands/ for more -# information on the commands that can be extended and the tasks you can define -# for them. Example: -#hooks: -## Un-comment to consume async message. -# post-start: -# - exec: symfony run --daemon --watch=config,src,templates,vendor bin/console messenger:consume async -vv diff --git a/.ddev/docker-compose.scorpio.yaml b/.ddev/docker-compose.scorpio.yaml deleted file mode 100644 index a8a12ec..0000000 --- a/.ddev/docker-compose.scorpio.yaml +++ /dev/null @@ -1,37 +0,0 @@ -networks: - scorpio: - -# https://docs.ddev.com/en/stable/users/extend/custom-docker-services/ -services: - scorpio: - container_name: "ddev-${DDEV_SITENAME}-scorpio" - hostname: scorpio.local - image: scorpiobroker/all-in-one-runner:java-latest - restart: "no" - ports: - - "9090" - environment: - - VIRTUAL_HOST=${DDEV_HOSTNAME} - - HTTP_EXPOSE=9090:9999 - - DBHOST=scorpio-db - depends_on: - - "scorpio-db" - networks: - - default - - scorpio - platform: "linux/amd64" - - scorpio-db: - container_name: "ddev-${DDEV_SITENAME}-scorpio-db" - image: postgis/postgis - environment: - - POSTGRES_USER=ngb - - POSTGRES_PASSWORD=ngb - - POSTGRES_DB=ngb - networks: - - scorpio - volumes: - - ./data/scorpio-db:/var/lib/postgresql/data - platform: "linux/amd64" - # https://stackoverflow.com/a/58806511 - command: ["postgres", "-c", "log_statement=all"] diff --git a/.env b/.env index 5e53eba..316a414 100644 --- a/.env +++ b/.env @@ -31,7 +31,7 @@ DEFAULT_URI=http://localhost ###< symfony/routing ### ###> app ### -APP_BROKER_BASE_URI=http://scorpio.local:9090/ +APP_BROKER_BASE_URI=http://scorpio:9090/ # JSON-LD contexts attached to every entity, outermost last so the ETSI core # context resolves the NGSI-LD terms and the domain context resolves the diff --git a/.gitignore b/.gitignore index c7fb02c..33146c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.ddev/data .idea *.local.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e140da..867894f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,5 +21,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `task broker:entities` for reading entities back out of the broker. - Architecture Decision Records under `docs/adr`. - Added test suite +- Scorpio broker as a Compose service in `docker-compose.override.yml`, with a + `docker-compose.server.override.yml` counterpart. + +### Changed + +- Replaced DDEV with the itk-dev Docker setup (`symfony-8` template): removed + `.ddev/`, rewrote `Taskfile.yml` to run through `itkdev-docker-compose`, and + updated the README accordingly. +- `APP_BROKER_BASE_URI` now points at the `scorpio` Compose service rather than + the DDEV-only `scorpio.local` hostname. +- `task test` runs the whole suite; it previously ran only `tests/Unit`. + +### Removed + +- The `mariadb` service, which no part of the project uses. [Unreleased]: https://github.com/itk-dev/enter diff --git a/README.md b/README.md index b6a8d5f..747483d 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,27 @@ # Enter -We use [DDEV](https://ddev.com/) and [Task](https://taskfile.dev/) for development: +We use the [itk-dev Docker +setup](https://github.com/itk-dev/devops_itkdev-docker) and +[Task](https://taskfile.dev/) for development. The project is built from the +`symfony-8` template, with two deliberate deviations: `docker-compose.yml` has +no `mariadb` service (nothing here uses a database), and +`docker-compose.override.yml` adds the Scorpio broker. + +Install from scratch — this also resets the broker database: ``` shell task site:install ``` +Or bring an existing checkout up to date: + ``` shell task site:update -ddev launch +task site:open ``` -Run `task` to see what cool task are available. Running `ddev` can help with other stuff. +Run `task` to see what cool task are available. Running `itkdev-docker-compose` +can help with other stuff. ## Adapter @@ -53,30 +63,41 @@ Design decisions are recorded in [docs/adr](docs/adr/README.md). ## Broker -A [Scorpio Broker](https://scorpio.readthedocs.io/) is part of the development setup. +A [Scorpio Broker](https://scorpio.readthedocs.io/) is part of the development +setup. It is declared in `docker-compose.override.yml`, so it comes up with the +rest of the stack and needs no separate start. It is not exposed through +Traefik: reach it from inside the network as `http://scorpio:9090`, the value +of `APP_BROKER_BASE_URI`. + +``` shell +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent http://scorpio:9090/ngsi-ld/v1/types | jq" +``` + +The app also proxies the broker at `/data`, which is the easier way to read it +from the host: ``` shell -ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/types | jq" +curl --silent https://enter.local.itkdev.dk/data/ngsi-ld/v1/types | jq ``` Load some example data: ``` shell name=import-toilet -ddev console app:broker:entity:delete toilet -ddev console app:broker:import:geojson toilet 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=andre_toiletter' -ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/entities --get --data-urlencode type=toilet" | jq '.[]|with_entries(select([.key] | inside(["id", "type", "location"])))' +task console -- app:broker:entity:delete toilet +task console -- app:broker:import:geojson toilet 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=andre_toiletter' +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent http://scorpio:9090/ngsi-ld/v1/entities --get --data-urlencode type=toilet" | jq '.[]|with_entries(select([.key] | inside(["id", "type", "location"])))' ``` ``` shell name=import-handicapparkering -ddev console app:broker:entity:delete handicapparkering -ddev console app:broker:import:geojson handicapparkering 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=invap' -ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/entities --get --data-urlencode type=handicapparkering" | jq '.[]|with_entries(select([.key] | inside(["id", "type", "location"])))' +task console -- app:broker:entity:delete handicapparkering +task console -- app:broker:import:geojson handicapparkering 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=invap' +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent http://scorpio:9090/ngsi-ld/v1/entities --get --data-urlencode type=handicapparkering" | jq '.[]|with_entries(select([.key] | inside(["id", "type", "location"])))' ``` ``` shell name=import-hundeskov -ddev console app:broker:entity:delete hundeskov -ddev console app:broker:import:geojson hundeskov 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=hundeskove_friluftsliv_aarhus' -ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/entities --get --data-urlencode type=hundeskov" | jq '.[]|with_entries(select([.key] | inside(["id", "type", "location", "geometry"])))' +task console -- app:broker:entity:delete hundeskov +task console -- app:broker:import:geojson hundeskov 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=hundeskove_friluftsliv_aarhus' +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent http://scorpio:9090/ngsi-ld/v1/entities --get --data-urlencode type=hundeskov" | jq '.[]|with_entries(select([.key] | inside(["id", "type", "location", "geometry"])))' ``` ### Broker API request examples @@ -84,7 +105,7 @@ ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/entities --get --d ``` shell name=scorpio-entity-create substitutions="{«entity-type»: Room, «entity-id»: 'house2:smartrooms:room1'}" -ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/entities --header 'content-type: application/json' --data @-" <<'JSON' +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent http://scorpio:9090/ngsi-ld/v1/entities --header 'content-type: application/json' --data @-" <<'JSON' { "type": "«entity-type»", "id": "«entity-id»" @@ -93,7 +114,7 @@ JSON # EPSG:4326?! -ddev exec "curl --silent http://scorpio.local:9090/ngsi-ld/v1/entities/«entity-id»/attrs --header 'content-type: application/json' --data @-" <<'JSON' +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent http://scorpio:9090/ngsi-ld/v1/entities/«entity-id»/attrs --header 'content-type: application/json' --data @-" <<'JSON' { "location": { "type": "geo:json", @@ -109,19 +130,19 @@ JSON # Get the entities -ddev exec "curl --silent --header 'accept: application/ld+json' http://scorpio.local:9090/ngsi-ld/v1/entities?type=«entity-type» | jq" +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent --header 'accept: application/ld+json' http://scorpio:9090/ngsi-ld/v1/entities?type=«entity-type» | jq" # Get the entities as GeoJSON -ddev exec "curl --silent --header 'accept: application/geo+json' http://scorpio.local:9090/ngsi-ld/v1/entities?type=«entity-type» | jq" +itkdev-docker-compose exec -T phpfpm sh -c "curl --silent --header 'accept: application/geo+json' http://scorpio:9090/ngsi-ld/v1/entities?type=«entity-type» | jq" ``` > [!CAUTION] > Excuse me what?! > > ``` shell -> ddev exec "curl --silent --header 'accept: application/geo+json' 'http://scorpio.local:9090/ngsi-ld/v1/entities?georel=near;maxDistance%3D%3D2000&geometry=Point&coordinates=%5B8,40%5D'" -> ddev exec "curl --silent --header 'accept: application/geo+json' 'http://scorpio.local:9090/ngsi-ld/v1/entities?georel=near;maxDistance==2000&geometry=Point&coordinates=%5B8,40%5D'" -> ddev exec "curl --silent --header 'accept: application/geo+json' 'http://scorpio.local:9090/ngsi-ld/v1/entities?georel=near;maxDistance==2000&geometry=Point&coordinates=[10,56]'" +> itkdev-docker-compose exec -T phpfpm sh -c "curl --silent --header 'accept: application/geo+json' 'http://scorpio:9090/ngsi-ld/v1/entities?georel=near;maxDistance%3D%3D2000&geometry=Point&coordinates=%5B8,40%5D'" +> itkdev-docker-compose exec -T phpfpm sh -c "curl --silent --header 'accept: application/geo+json' 'http://scorpio:9090/ngsi-ld/v1/entities?georel=near;maxDistance==2000&geometry=Point&coordinates=%5B8,40%5D'" +> itkdev-docker-compose exec -T phpfpm sh -c "curl --silent --header 'accept: application/geo+json' 'http://scorpio:9090/ngsi-ld/v1/entities?georel=near;maxDistance==2000&geometry=Point&coordinates=[10,56]'" > > ``` ## GeoJSON @@ -167,7 +188,7 @@ ddev exec "curl --silent --header 'accept: application/geo+json' http://scorpio. Must `location` be a `Point` in ngsi-ld? ``` shell -ddev exec --service scorpio-db "psql ngb ngb" +itkdev-docker-compose exec scorpio-db psql ngb ngb ``` ``` sql @@ -177,13 +198,13 @@ ddev exec --service scorpio-db "psql ngb ngb" ``` shell -ddev exec --service scorpio-db "psql ngb ngb" <<< "SELECT id , e_types, location FROM entity;" +itkdev-docker-compose exec -T scorpio-db psql ngb ngb <<< "SELECT id , e_types, location FROM entity;" ``` ``` shell name=hmm -ddev console app:import:geojson toilet 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=andre_toiletter' \ - && ddev exec --service scorpio-db "psql ngb ngb" <<< "SELECT id , e_types, ST_AsText(location) AS location FROM entity WHERE id = 'toilet:0000';" \ - && ddev exec --service scorpio-db "psql ngb ngb" <<< "SELECT temporalentity_id, ST_AsText(location) AS location, ST_asText(geovalue) AS geovalue, createdat FROM temporalentityattrinstance WHERE temporalentity_id = 'toilet:0000' ORDER BY createdat DESC LIMIT 10;" +task console -- app:import:geojson toilet 'https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=andre_toiletter' \ + && itkdev-docker-compose exec -T scorpio-db psql ngb ngb <<< "SELECT id , e_types, ST_AsText(location) AS location FROM entity WHERE id = 'toilet:0000';" \ + && itkdev-docker-compose exec -T scorpio-db psql ngb ngb <<< "SELECT temporalentity_id, ST_AsText(location) AS location, ST_asText(geovalue) AS geovalue, createdat FROM temporalentityattrinstance WHERE temporalentity_id = 'toilet:0000' ORDER BY createdat DESC LIMIT 10;" ``` @@ -197,4 +218,4 @@ ddev console app:import:geojson toilet 'https://webkort.aarhuskommune.dk/spatial * [Handicapparkering](https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=invap): -* +* diff --git a/Taskfile.yml b/Taskfile.yml index 6ac1694..49bc13d 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,57 +1,107 @@ +# https://taskfile.dev — install with `brew install go-task`. +# Run `task` (or `task --list-all`) to see all available commands. + version: '3' # https://taskfile.dev/usage/#env-files dotenv: ['.env.local', '.env'] +vars: + # Set TASK_DOCKER_COMPOSE=docker compose to bypass the itk-dev wrapper. + DOCKER_COMPOSE: '{{.TASK_DOCKER_COMPOSE | default "itkdev-docker-compose"}}' + tasks: + # ---------------------------------------------------------------- Site --- + site:install: desc: Install site from scratch - prompt: Really (re)install site? + prompt: Really (re)install site? This deletes the broker database. cmds: - - ddev delete --omit-snapshot --yes - - rm -fr .ddev/data/scorpio-db/ + - task: compose + vars: + TASK_ARGS: down --volumes --remove-orphans + - rm -fr .docker/data/scorpio-db/ - task: site:update site:update: desc: Update site cmds: - - ddev restart - - ddev composer install - # - ddev console doctrine:migrations:migrate --no-interaction - - ddev console cache:clear + - task: traefik:start + - task: compose + vars: + TASK_ARGS: pull + - task: compose + vars: + TASK_ARGS: up --detach --remove-orphans + - task: composer + vars: + TASK_ARGS: install + - task: console + vars: + TASK_ARGS: cache:clear - test: - desc: Run all tests - cmds: - - task: test:unit - # - task: test:application - # - task: test:integration + site:open: + desc: Open the site in a browser + cmd: '{{.DOCKER_COMPOSE}} open' + + traefik:start: + desc: Start the shared Traefik reverse proxy + # Traefik is a stack of its own. Without unsetting COMPOSE_PROJECT_NAME — + # which the dotenv block above exports — it would be brought up under this + # project's name and get its own proxy network instead of joining the + # shared one. + cmd: env -u COMPOSE_PROJECT_NAME itkdev-docker-compose traefik:start + + # ----------------------------------------------------------- Wrappers --- + + compose: + desc: 'Run a docker compose command, e.g. task compose -- logs --follow' + cmd: '{{.DOCKER_COMPOSE}} {{.TASK_ARGS}} {{.CLI_ARGS}}' + + composer: + desc: 'Run composer, e.g. task composer -- require symfony/uid' + cmd: '{{.DOCKER_COMPOSE}} run --rm --no-deps phpfpm composer {{.TASK_ARGS}} {{.CLI_ARGS}}' + + php: + desc: 'Run a command in a one-off phpfpm container, e.g. task php -- vendor/bin/phpstan' + cmd: '{{.DOCKER_COMPOSE}} run --rm --no-deps phpfpm {{.TASK_ARGS}} {{.CLI_ARGS}}' + + console: + desc: 'Run a Symfony console command, e.g. task console -- debug:router' + cmd: '{{.DOCKER_COMPOSE}} exec phpfpm bin/console {{.TASK_ARGS}} {{.CLI_ARGS}}' - test:unit: &test_task + shell: + desc: Open a shell in the running phpfpm container + cmd: '{{.DOCKER_COMPOSE}} exec phpfpm bash' + + # -------------------------------------------------------------- Tests --- + + test: + desc: 'Run the test suite, e.g. task test -- --filter=FeedReader' env: APP_ENV: test - desc: 'Run all {{.TASK | replace "test:" "" }} tests' - cmd: ddev php bin/phpunit tests/{{.TASK | replace "test:" "" | title }} + cmd: '{{.DOCKER_COMPOSE}} run --rm --no-deps phpfpm bin/phpunit {{.CLI_ARGS}}' - test:integration: *test_task - test:application: *test_task + # ------------------------------------------------------------- Broker --- + # Scorpio comes up with the rest of the stack (docker-compose.override.yml), + # so there is no separate start task. Read requests need the domain context + # in a Link header, which the script supplies; the env values come from the + # dotenv block above and are passed into the container explicitly because it + # does not read .env itself. import: desc: 'Import a source into the broker, e.g. task import -- mtm_spatialmaps-handicap-parking' - cmd: ddev console app:import {{.CLI_ARGS}} + cmd: '{{.DOCKER_COMPOSE}} exec phpfpm bin/console app:import {{.CLI_ARGS}}' - # The broker itself needs no start task: Scorpio is a DDEV custom service - # (.ddev/docker-compose.scorpio.yaml), so it comes up with the rest of the - # site. Read requests need the domain context in a Link header, which the - # script supplies; the env values come from the dotenv block above, and are - # passed in explicitly because the container shell does not read .env. broker:entities: desc: 'List broker entities of a type, e.g. task broker:entities -- OnStreetParking 10' cmd: >- - ddev exec sh -c - "APP_BROKER_BASE_URI='$APP_BROKER_BASE_URI' - ENTER_NGSI_DOMAIN_CONTEXT='$ENTER_NGSI_DOMAIN_CONTEXT' - sh task/scripts/broker-entities {{.CLI_ARGS}}" + {{.DOCKER_COMPOSE}} exec + --env APP_BROKER_BASE_URI="$APP_BROKER_BASE_URI" + --env ENTER_NGSI_DOMAIN_CONTEXT="$ENTER_NGSI_DOMAIN_CONTEXT" + phpfpm sh task/scripts/broker-entities {{.CLI_ARGS}} + + # ---------------------------------------------------- Coding standards --- coding-standards:apply: desc: 'Apply coding standards' @@ -64,7 +114,7 @@ tasks: - task: coding-standards:yaml:apply coding-standards:check: - desc: 'Apply coding standards' + desc: 'Apply and check coding standards' cmds: - task: coding-standards:assets:check - task: coding-standards:composer:check @@ -127,26 +177,38 @@ tasks: coding-standards:php:apply: desc: 'Apply coding standards for PHP' cmds: - - ddev php vendor/bin/rector - - ddev php vendor/bin/php-cs-fixer fix + - task: php + vars: + TASK_ARGS: vendor/bin/rector + - task: php + vars: + TASK_ARGS: vendor/bin/php-cs-fixer fix coding-standards:php:check: desc: 'Apply and check coding standards for PHP' cmds: - task: coding-standards:php:apply - - ddev php vendor/bin/rector --dry-run - - ddev php vendor/bin/php-cs-fixer check + - task: php + vars: + TASK_ARGS: vendor/bin/rector --dry-run + - task: php + vars: + TASK_ARGS: vendor/bin/php-cs-fixer check coding-standards:twig:apply: desc: 'Apply coding standards for Twig' - cmds: - - ddev php vendor/bin/twig-cs-fixer fix + cmd: + task: php + vars: + TASK_ARGS: vendor/bin/twig-cs-fixer fix coding-standards:twig:check: desc: 'Apply and check coding standards for Twig' cmds: - task: coding-standards:twig:apply - - ddev php vendor/bin/twig-cs-fixer check + - task: php + vars: + TASK_ARGS: vendor/bin/twig-cs-fixer check coding-standards:yaml:apply: desc: 'Apply coding standards for YAML' @@ -163,31 +225,22 @@ tasks: vars: TASK_ARGS: run --rm prettier --parser yaml phpstan*.neon '**/*.{yml,yaml}' --check + # ------------------------------------------------------ Code analysis --- + code-analysis: desc: 'Run code analysis' cmds: - task: code-analysis:phpstan - - task: code-analysis:mago code-analysis:phpstan: desc: 'Run PHPStan' cmds: - - task: compose + - task: composer vars: - TASK_ARGS: run --rm --no-deps phpfpm composer install --no-scripts - - task: compose + TASK_ARGS: install --no-scripts + - task: php vars: - TASK_ARGS: run --rm --no-deps phpfpm vendor/bin/phpstan - - compose: - internal: true - cmd: 'docker compose {{.TASK_ARGS}} {{.CLI_ARGS}}' - - composer: - internal: true - task: compose - vars: - TASK_ARGS: run --rm --no-deps phpfpm composer + TASK_ARGS: vendor/bin/phpstan default: cmds: diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..390f4f1 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,44 @@ +# The Scorpio broker is part of the development setup: the app proxies it at +# /data and `task import` writes to it. It lives here rather than in +# docker-compose.yml so the template file stays comparable with symfony-8. +networks: + scorpio: + +services: + scorpio: + image: scorpiobroker/all-in-one-runner:java-latest + restart: "no" + # Scorpio publishes no arm64 image. + platform: "linux/amd64" + ports: + - "9090" + environment: + - DBHOST=scorpio-db + depends_on: + scorpio-db: + condition: service_healthy + networks: + # On `app` so phpfpm can reach it as APP_BROKER_BASE_URI; on + # `scorpio` so it can reach its own database. + - app + - scorpio + + scorpio-db: + image: postgis/postgis + platform: "linux/amd64" + environment: + - POSTGRES_USER=ngb + - POSTGRES_PASSWORD=ngb + - POSTGRES_DB=ngb + healthcheck: + test: ["CMD-SHELL", "pg_isready --username=ngb --dbname=ngb"] + start_period: 10s + interval: 5s + timeout: 5s + retries: 10 + networks: + - scorpio + volumes: + - ./.docker/data/scorpio-db:/var/lib/postgresql/data + # https://stackoverflow.com/a/58806511 + command: ["postgres", "-c", "log_statement=all"] diff --git a/docker-compose.server.override.yml b/docker-compose.server.override.yml index 9a3a124..c88a405 100644 --- a/docker-compose.server.override.yml +++ b/docker-compose.server.override.yml @@ -1,36 +1,37 @@ +# Server counterpart to docker-compose.override.yml: the same broker, without +# the local-only bits. Applied on top of docker-compose.server.yml. networks: scorpio: -# https://docs.ddev.com/en/stable/users/extend/custom-docker-services/ services: - phpfpm: - image: itkdev/php8.5-fpm:alpine - scorpio: - hostname: scorpio.local image: scorpiobroker/all-in-one-runner:java-latest - restart: "no" + restart: unless-stopped ports: - "9090" environment: - DBHOST=scorpio-db depends_on: - - "scorpio-db" + scorpio-db: + condition: service_healthy networks: - app - scorpio - platform: "linux/amd64" scorpio-db: image: postgis/postgis + restart: unless-stopped environment: - POSTGRES_USER=ngb - POSTGRES_PASSWORD=ngb - POSTGRES_DB=ngb + healthcheck: + test: ["CMD-SHELL", "pg_isready --username=ngb --dbname=ngb"] + start_period: 10s + interval: 5s + timeout: 5s + retries: 10 networks: - scorpio volumes: - ./.docker/data/scorpio-db:/var/lib/postgresql/data - platform: "linux/amd64" - # https://stackoverflow.com/a/58806511 - command: ["postgres", "-c", "log_statement=all"] diff --git a/docker-compose.yml b/docker-compose.yml index 4c8f69a..ae669f1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,25 +7,6 @@ networks: internal: false services: - mariadb: - image: itkdev/mariadb:latest - networks: - - app - ports: - - "3306" - healthcheck: - test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] - start_period: 10s - interval: 10s - timeout: 5s - retries: 3 - environment: - - MYSQL_ROOT_PASSWORD=password - - MYSQL_USER=db - - MYSQL_PASSWORD=db - - MYSQL_DATABASE=db - #- ENCRYPT=1 # Uncomment to enable database encryption. - phpfpm: image: itkdev/php8.4-fpm:latest user: ${COMPOSE_USER:-deploy} @@ -41,9 +22,6 @@ services: - PHP_SENDMAIL_PATH=/usr/bin/msmtp --host=mail --port=1025 --read-recipients --read-envelope-from - DOCKER_HOST_DOMAIN=${COMPOSE_DOMAIN:?} - PHP_IDE_CONFIG=serverName=localhost - depends_on: - mariadb: - condition: service_healthy volumes: - .:/app