diff --git a/.env b/.env index a9734f2..ecf56ac 100644 --- a/.env +++ b/.env @@ -1,3 +1,6 @@ +# Base +APP_DIR=/srv/app + # Container names NGINX_CONTAINER_NAME=nginx REDIS_CONTAINER_NAME=redis @@ -5,11 +8,47 @@ POSTGRESQL_CONTAINER_NAME=db SOLR_CONTAINER_NAME=solr CKAN_CONTAINER_NAME=ckan WORKER_CONTAINER_NAME=ckan-worker +APACHE_CONTAINER_NAME=apache +PYCSW_CONTAINER_NAME=pycsw # Host Ports CKAN_PORT_HOST=5000 -NGINX_PORT_HOST=81 +NGINX_PORT_HOST=80 NGINX_SSLPORT_HOST=8443 +APACHE_PORT_HOST=80 +PYCSW_PORT_HOST=8000 + +# Solr +SOLR_IMAGE_VERSION=2.9-solr8-spatial +SOLR_PORT=8983 +CKAN_SOLR_URL=http://solr:${SOLR_PORT}/solr/ckan +TEST_CKAN_SOLR_URL=http://solr:${SOLR_PORT}/solr/ckan + +# Redis +REDIS_VERSION=7-alpine +CKAN_REDIS_URL=redis://redis:6379/1 +TEST_CKAN_REDIS_URL=redis://redis:6379/1 + +# NGINX +NGINX_PORT=80 +NGINX_SSLPORT=443 + +# Apache HTTP Server +APACHE_VERSION=2.4 +APACHE_PORT=80 +APACHE_LOG_DIR=/var/log/apache +APACHE_SERVER_NAME=localhost:5000 +# Check CKAN__ROOT_PATH and CKANEXT__DCAT__BASE_URI. If you don't need to use domain locations, it is better to use the nginx configuration. Leave blank or use the root `/`. +APACHE_CKAN_LOCATION=/catalog +APACHE_PYCSW_LOCATION=/csw + +# pycsw +PYCSW_PORT=8000 +CKAN_URL=http://localhost:5000/catalog +PYCSW_URL=http://localhost:5000/csw +# SCHEMAS: ckan2pycsw/model/dataset.py - Dataset type +PYCSW_CKAN_SCHEMA=iso19139_geodcatap +PYCSW_OUPUT_SCHEMA=iso19139_inspire # CKAN databases POSTGRES_USER=ckan @@ -29,9 +68,9 @@ TEST_CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:datastore@db/datastore_te # CKAN core CKAN_VERSION=2.9.8 CKAN_SITE_ID=default -CKAN_SITE_URL=https://localhost:8443 +CKAN_SITE_URL=http://localhost:5000 +CKAN__ROOT_PATH=/catalog/{{LANG}} CKAN_PORT=5000 -CKAN_PORT_HOST=5000 CKAN___BEAKER__SESSION__SECRET=CHANGE_ME # See https://docs.ckan.org/en/latest/maintaining/configuration.html#api-token-settings CKAN___API_TOKEN__JWT__ENCODE__SECRET=string:CHANGE_ME @@ -49,8 +88,10 @@ TZ=UTC ## Customize which text formats the text_view plugin will show CKAN__PREVIEW__JSON_FORMATS="json jsonld" # html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json -CKAN__PREVIEW__XML_FORMATS="html htm xml rdf rdf+xml owl+xml atom rss turtle ttl n3 n-triples" +CKAN__PREVIEW__XML_FORMATS="xml rdf rdf+xml owl+xml atom rss turtle ttl n3 n-triples" CKAN__PREVIEW__TEXT_FORMATS="text plain text/plain text/turtle csv tsv rss txt json" +CKAN__PREVIEW__LOADABLE="html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json arcgis_rest" + ## Resource Proxy settings ### Preview size limit, default: 1MB CKAN__RESOURCE_PROXY__MAX_FILE_SIZE=50048576 @@ -58,25 +99,16 @@ CKAN__RESOURCE_PROXY__MAX_FILE_SIZE=50048576 CKAN__RESOURCE_PROXY__CHUNK_SIZE=4096 ## Default timeout for fetching proxied items CKAN__RESOURCE_PROXY__TIMEOUT=10 -CKAN__VIEWS__DEFAULT_VIEWS="image_view text_view recline_view wmts_view geojson_view geo_view shp_view pdf_view" +CKAN__VIEWS__DEFAULT_VIEWS="image_view webpage_view text_view recline_view wmts_view geojson_view geo_view shp_view pdf_view" -# Solr -SOLR_IMAGE_VERSION=2.9-solr8-spatial -CKAN_SOLR_URL=http://solr:8983/solr/ckan -TEST_CKAN_SOLR_URL=http://solr:8983/solr/ckan - -# Redis -REDIS_VERSION=6 -CKAN_REDIS_URL=redis://redis:6379/1 -TEST_CKAN_REDIS_URL=redis://redis:6379/1 - -# NGINX -NGINX_PORT=80 -NGINX_SSLPORT=443 +# Localization +CKAN__LOCALE_DEFAULT="en" +CKAN__LOCALE_ORDER="en es pt_BR ja it cs_CZ ca fr el sv sr sr@latin no sk fi ru de pl nl bg ko_KR hu sa sl lv" # Extensions -CKAN__PLUGINS="envvars stats text_view image_view recline_view resourcedictionary datastore xloader harvest ckan_harvester spatial_metadata spatial_query spatial_harvest_metadata_api csw_harvester waf_harvester doc_harvester resource_proxy geo_view geojson_view wmts_view shp_view dcat dcat_rdf_harvester dcat_json_harvester dcat_json_interface scheming_datasets scheming_groups scheming_organizations pdf_view pages" +CKAN__PLUGINS="envvars stats text_view image_view webpage_view recline_view resourcedictionary datastore xloader harvest ckan_harvester spatial_metadata spatial_query spatial_harvest_metadata_api csw_harvester waf_harvester doc_harvester resource_proxy geo_view geojson_view wmts_view shp_view dcat dcat_rdf_harvester dcat_json_harvester dcat_json_interface scheming_datasets scheming_groups scheming_organizations pdf_view pages" +# ckanext-harvest CKAN__HARVEST__MQ__TYPE=redis CKAN__HARVEST__MQ__HOSTNAME=redis CKAN__HARVEST__MQ__PORT=6379 @@ -87,7 +119,7 @@ CKANEXT__XLOADER__API_TOKEN=api_token CKANEXT__XLOADER__JOBS__DB_URI=postgresql://ckan:ckan@db/ckan # ckanext-dcat -CKANEXT__DCAT__BASE_URI=https://localhost:5000 +CKANEXT__DCAT__BASE_URI=http://localhost:5000/catalog CKANEXT__DCAT__RDF_PROFILES="euro_dcat_ap_2 euro_dcat_ap" # ckanext-scheming: setup_scheming.sh diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index 1722a68..2d7ba92 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ _service-provider/* _solr/schema.xml _src/* local/* -.vscode \ No newline at end of file +.vscode +__pycache__ +log +metadata \ No newline at end of file diff --git a/README.md b/README.md index 02ce475..cad4d69 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
@@ -23,24 +23,35 @@ Contains Docker images for the different components of CKAN Cloud and a Docker c
>**Warning**:
>This is a **custom installation of Docker Compose** with specific extensions for spatial data and [GeoDCAT-AP](https://github.com/SEMICeu/GeoDCAT-AP)/[INSPIRE](https://github.com/INSPIRE-MIF/technical-guidelines) metadata [profiles](https://en.wikipedia.org/wiki/Geospatial_metadata). For official installations, please have a look: [CKAN documentation: Installation](https://docs.ckan.org/en/latest/maintaining/installing/index.html).
+![CKAN Docker Platform](/doc/img/ckan-docker-services.png)
+
+
Available components:
* CKAN custom image based on the official CKAN repo [ckan-docker-spatial](https://github.com/mjanez/ckan-docker-spatial)[^1]
The non-CKAN images are as follows:
-* PostgreSQL: Official PostgreSQL image. Database files are stored in a named volume.
+* PostgreSQL: [Custom image](/postgresql/Dockerfile) based on official PostgreSQL image. Database files are stored in a named volume.
* Solr: CKAN's [pre-configured Solr image](https://github.com/ckan/ckan-solr). The index data is stored in a named volume and has a spatial schema. [^2]
* Redis: standard Redis image
-* NGINX: latest stable nginx image that includes SSL and Non-SSL endpoints
+* Apache HTTP Server: [Custom image](/apache/Dockerfile) based on official latest stable httpd image. Configured to serve multiple routes for the [ckan-pycsw](#ckan-pycsw) CSW endpoint (`{CKAN_SITE_URL}/csw`) and CKAN (`{CKAN_SITE_URL}/catalog`).
+* ckan-pycsw: [Custom image](/ckan-pycsw/Dockerfile) based on [pycsw CKAN harvester ISO19139](https://github.com/mjanez/ckan-pycsw) for INSPIRE Metadata CSW Endpoint.
-| Repository | Type | Docker tag | Size | Notes |
-| --- | --- | --- | --- | --- |
-| PostgreSQL 15.2 | base image | [`postgres/postgres:15-alpine`](https://hub.docker.com/layers/library/postgres/15-alpine/images/sha256-53a02ecbe9d18ff6476e6651c34811da39f054424c725fc15d2b480fc3fab877?context=explore) | 89.74 MB | Custom Dockerfile: [`postgresql/Dockerfile`](/postgresql/Dockerfile) |
-| Solr 8.11.1 | base image | [`ckan/ckan-solr:2.9-solr8-spatial`](https://registry.hub.docker.com/layers/ckan/ckan-solr/2.9-solr8-spatial/images/sha256-b5ee4979891c7dd1f10d2ac2cbdd4d80ff656879edb0f0493616be7b4cf8bc3a?context=explore) | 331.1 MB | - |
-| Redis 6.2.11 | base image | [`redis/redis:6`](https://hub.docker.com/layers/library/redis/6/images/sha256-e10c69dc5f9b27c47874060962fdaa26ec0df592205d6d21402945267081b434?context=explore) | 39.32 MB | - |
-| NGINX 1.22.1 | base image | [`nginx:stable-alpine`](https://hub.docker.com/layers/library/nginx/stable-alpine/images/sha256-ff2a5d557ca22fa93669f5e70cfbeefda32b98f8fd3d33b38028c582d700f93a?context=explore) | 9.74 MB | Custom Dockerfile: [`nginx/Dockerfile`](/nginx/Dockerfile) |
+Optional HTTP Endpoint ([`docker-compose.nginx.yml`](/docker-compose.nginx.yml)):
+* `docker-compose.nginx.yml`:
+ * NGINX: latest stable nginx image that includes SSL and Non-SSL endpoints instead of Apache HTTP Server. No locations, no ckan-pycsw, only CKAN.
-The site is configured using environment variables that you can set in the `.env` file.
+| Compose files | Repository | Type | Docker tag | Size | Notes |
+| --- | --- | --- | --- | --- | --- |
+| [`docker-compose.yml`](/docker-compose.yml) / [`docker-compose.nginx.yml`](/docker-compose.nginx.yml) | PostgreSQL 15.2 | base image | [`postgres/postgres:15-alpine`](https://hub.docker.com/layers/library/postgres/15-alpine/images/sha256-53a02ecbe9d18ff6476e6651c34811da39f054424c725fc15d2b480fc3fab877?context=explore) | 89.74 MB | Custom Dockerfile: [`postgresql/Dockerfile`](/postgresql/Dockerfile) |
+| [`docker-compose.yml`](/docker-compose.yml) / [`docker-compose.nginx.yml`](/docker-compose.nginx.yml) | Solr 8.11.1 | custom image | [`ckan/ckan-solr:2.9-solr8-spatial`](https://registry.hub.docker.com/layers/ckan/ckan-solr/2.9-solr8-spatial/images/sha256-b5ee4979891c7dd1f10d2ac2cbdd4d80ff656879edb0f0493616be7b4cf8bc3a?context=explore) | 331.1 MB | CKAN's [pre-configured spatial Solr image](https://github.com/ckan/ckan-solr). |
+| [`docker-compose.yml`](/docker-compose.yml) / [`docker-compose.nginx.yml`](/docker-compose.nginx.yml) | Redis 7.0.10 | base image | [`redis/redis:7-alpine`](https://hub.docker.com/layers/library/redis/7-alpine/images/sha256-98f4ea44e912d0941d29015a4e2448151b94411109c896b5627d94d79306eea7?context=explore) | 11.82 MB | - |
+| [`docker-compose.yml`](/docker-compose.yml) | Apache HTTP Server 2.4 | custom image | [`httpd/httpd:2.4`](https://hub.docker.com/layers/library/httpd/2.4/images/sha256-f34e8e25ee18da020633ef0b2bf7516d8cfdad5c5c4b0595d36e5cd78a098101?context=explore) | 54.47 MB | Custom Dockerfile: [`apache/Dockerfile`](/apache/Dockerfile) |
+| [`docker-compose.yml`](/docker-compose.yml)| pycsw CKAN harvester ISO19139 | custom image | [`mjanez/ckan-pycsw:main`](https://github.com/mjanez/ckan-pycsw/pkgs/container/ckan-pycsw) | 44 MB | Custom Dockerfile: [`ckan-pycsw/Dockerfile`](/ckan-pycsw/Dockerfile) |
+| [`docker-compose.nginx.yml`](/docker-compose.nginx.yml) | NGINX 1.22.1 | base image | [`nginx:stable-alpine`](https://hub.docker.com/layers/library/nginx/stable-alpine/images/sha256-ff2a5d557ca22fa93669f5e70cfbeefda32b98f8fd3d33b38028c582d700f93a?context=explore) | 9.74 MB | No routing, only CKAN. Custom Dockerfile: [`nginx/Dockerfile`](/nginx/Dockerfile) |
+
+
+The site is configured using environment variables that you can set in the `.env` file for an Apache HTTP Server and ckan-pycsw deployment, or replace it with the [`.env.nginx.example`](/samples/.env.nginx.example) for a NGINX and CKAN-only deployment using the Docker Compose file: [`docker-compose.nginx.yml`](/docker-compose.nginx.yml).
### ckan-docker roadmap
@@ -64,7 +75,7 @@ Information about extensions installed in the `main` image. More info described
| Extension | [ckanext-resourcedictionary](https://github.com/OpenDataGIS/ckanext-resourcedictionary) | main | Completed | ✔️ | ✔️ | Stable installation. This extension extends the default CKAN Data Dictionary functionality by adding possibility to create data dictionary before actual data is uploaded to datastore. |
| Extension | [ckanext-pages](https://github.com/ckan/ckanext-pages) | 0.5.1 | Completed | ✔️ | ✔️ | Stable installation. This extension gives you an easy way to add simple pages to CKAN. |
| Extension | [ckanext-pdfview](https://github.com/ckan/ckanext-pdfview) | 0.0.8 | Completed | ✔️ | ✔️ | Stable installation. This extension provides a view plugin for PDF files using an html object tag. |
-| Software | [docker-pycsw](https://github.com/mjanez/ckan-pycsw) | main | Ready to use standalone version | ✔️ | ❌ | Stable installation. PyCSW Endpoint of Open Data Portal with docker compose config. Harvest the CKAN catalogue in a CSW endpoint based on existing spatial datasets in the open data portal. |
+| Software | [ckan-pycsw](https://github.com/mjanez/ckan-pycsw) | main | Completed | ✔️ | ✔️ | Stable installation. PyCSW Endpoint of Open Data Portal with docker compose config. Harvest the CKAN catalogue in a CSW endpoint based on existing spatial datasets in the open data portal. |
## Environment: docker
@@ -151,29 +162,47 @@ docker compose [-p
-> Please note that when accessing CKAN directly (via a browser) ie: not going through NGINX you will need to make sure you have "ckan" set up to be an alias to localhost in the local hosts file. Either that or you will need to change the `.env` entry for `CKAN_SITE_URL`
+> Please note that when accessing CKAN directly (via a browser) ie: not going through Apache/NGINX you will need to make sure you have "ckan" set up to be an alias to localhost in the local hosts file. Either that or you will need to change the `.env` entry for `CKAN_SITE_URL`
>**Warning**:
> Using the default values on the `.env.example` file will get you a working CKAN instance. There is a sysadmin user created by default with the values defined in `CKAN_SYSADMIN_NAME` and `CKAN_SYSADMIN_PASSWORD`(`ckan_admin` and `test1234` by default). This should be obviously changed before running this setup as a public CKAN instance.
-Clone project
-```shell
-cd /path/to/my/project
-git clone https://github.com/mjanez/ckan-docker.git
-```
-
To build the images:
-
- docker compose build
+ ```bash
+ docker compose build
+ ```
+ >**Note**
+ > NGINX CKAN without ckan-pycsw and Apache:
+ >```bash
+ >docker compose -f docker-compose.nginx.yml build
+ >```
+
To start the containers:
+ ```bash
+ docker compose up
+ ```
- docker compose up
+ >**Note**
+ > NGINX CKAN without ckan-pycsw and Apache:
+ >```bash
+ >docker compose -f docker-compose.nginx.yml up
+ >```
This will start up the containers in the current window. By default the containers will log direct to this window with each container
using a different colour. You could also use the -d "detach mode" option ie: `docker compose up -d` if you wished to use the current
@@ -182,13 +211,74 @@ window for something else.
>**Note**
> Or `docker compose up --build` to build & up the containers.
-At the end of the container start sequence there should be 6 containers running
+At the end of the container start sequence there should be 6 containers running (or 5 if use NGINX Docker Compose file)
-![Screenshot 2022-12-12 at 10 36 21 am](https://user-images.githubusercontent.com/54408245/207012236-f9571baa-4d99-4ffe-bd93-30b11c4829e0.png)
+After this step, CKAN should be running at {`APACHE_SERVER_NAME`}{`APACHE_CKAN_LOCATION`} and ckan-pycsw at {`APACHE_SERVER_NAME`}{`APACHE_PYCSW_LOCATION`}, i.e: http://localhost/catalog or http://localhost/csw
-After this step, CKAN should be running at `CKAN_SITE_URL`.
+|CONTAINER ID |IMAGE |COMMAND|CREATED|STATUS|PORTS|NAMES|
+|------------|----------------------------------|--------------------|-------|-------|------|-----|
+|0217537f717e|ckan-docker-apache |/docker-entrypoint.…|6 minutes ago |Up 4 minutes|80/tcp,0.0.0.0:80->80/tcp | apache |
+|7b06ab2e060a|ckan-docker-ckan|/srv/app/start_ckan…|6 minutes ago |Up 5 minutes (healthy)|0.0.0.0:5000->5000/tcp|ckan | |
+|1b8d9789c29a|redis:7-alpine |docker-entrypoint.s…|6 minutes ago |Up 4 minutes (healthy)|6379/tcp |redis | |
+|7f162741254d|ckan/ckan-solr:2.9-solr8-spatial |docker-entrypoint.s…|6 minutes ago |Up 4 minutes (healthy)|8983/tcp |solr | |
+|2cdd25cea0de|ckan-docker-db |docker-entrypoint.s…|6 minutes ago |Up 4 minutes (healthy)|5432/tcp |db | |
+|9cdj25dae6gr|ckan-docker-pycsw |docker-entrypoint.s…|6 minutes ago |Up 4 minutes (healthy)|8000/tcp |db | |
+#### Configure a docker compose service to start on boot
+>**Note**
+> Test on Debian.
+
+To have Docker Compose run automatically when you reboot a machine, you can follow the steps below:
+1. Create a systemd service file for Docker Compose. You can create a file named `ckan-docker-compose.service` in the `/etc/systemd/system/` folder with the following content:
+
+ ```bash
+ [Unit]
+ Description=CKAN Docker Compose Application Service
+ Requires=docker.service
+ After=docker.service
+
+ [Service]
+ Type=oneshot
+ RemainAfterExit=yes
+ WorkingDirectory=/path/to/project/ckan-docker/
+ ExecStart=/bin/docker compose up -d
+ ExecStop=/bin/docker compose down
+ TimeoutStartSec=0
+
+ [Install]
+ WantedBy=multi-user.target
+ ```
+
+2. Replace `/path/to/project/ckan-docker/` with the path where your project's `docker-compose.yml` file is located and and check the path to the docker compose binary on execution and stop: `/bin/docker`.
+3. Load the systemd service file with the following command:
+
+ ```bash
+ sudo systemctl daemon-reload
+ ```
+
+4. Enables the service to start automatically when the machine boots up:
+
+ ```bash
+ sudo systemctl enable ckan-docker-compose
+ ```
+
+5. You can now start the service with the following command:
+
+ ```bash
+ sudo systemctl start ckan-docker-compose
+ ```
+
+6. If you want to stop or check the status of the service, use the following commands:
+
+ ```bash
+ # Stop the service
+ sudo systemctl stop ckan-docker-compose
+
+ # Check the status
+ sudo systemctl status ckan-docker-compose
+ ```
+
### Development mode
Use this mode if you are making code changes to CKAN and either creating new extensions or making code changes to existing extensions. This mode also uses the `.env` file for config options.
@@ -210,13 +300,7 @@ You can use the ckan [extension](https://docs.ckan.org/en/latest/extensions/tuto
docker compose -f docker compose.dev.yml exec ckan-dev /bin/sh -c "ckan generate extension --output-dir /srv/app/src_extensions"
-|CONTAINER ID |IMAGE |COMMAND|CREATED|STATUS|PORTS|NAMES|
-|------------|----------------------------------|--------------------|-------|-------|------|-----|
-|0217537f717e|ckan-docker-nginx |/docker-entrypoint.…|6 minutes ago |Up 4 minutes|81/tcp,0.0.0.0:81->80/tcp, 0.0.0.0:8443->443/tcp|nginx |
-|7b06ab2e060a|ghcr.io/mjanez/ckan-spatial:master|/srv/app/start_ckan…|6 minutes ago |Up 5 minutes (healthy)|0.0.0.0:5000->5000/tcp|ckan | |
-|1b8d9789c29a|redis:6 |docker-entrypoint.s…|6 minutes ago |Up 5 minutes (healthy)|6379/tcp |redis | |
-|7f162741254d|ckan/ckan-solr:2.9-solr8-spatial |docker-entrypoint.s…|6 minutes ago |Up 5 minutes (healthy)|8983/tcp |solr | |
-|2cdd25cea0de|ckan-docker-db |docker-entrypoint.s…|6 minutes ago |Up 5 minutes (healthy)|5432/tcp |db | |
+![extension](https://user-images.githubusercontent.com/54408245/220623568-b4e074c7-6d07-4d27-ae29-35ce70961463.png)
The new extension files and directories are created in the `/srv/app/src_extensions/` folder in the running container. They will also exist in the local src/ directory as local `/src` directory is mounted as `/srv/app/src_extensions/` on the ckan container. You might need to change the owner of its folder to have the appropiate permissions.
@@ -340,8 +424,30 @@ command: `python -m pdb /usr/lib/ckan/venv/bin/ckan --config /srv/app/ckan.ini r
The Datastore database and user is created as part of the entrypoint scripts for the db container. There is also a Datapusher container running the latest version of Datapusher.
+### Apache HTTP Server
+The default Docker Compose configuration ([`docker-compose.yml`](/docker-compose.yml)) uses an httpd image as the front-end. It has two routes for the ckan (default location: `/catalog`) and ckan-pycsw (default location: `/csw`) services.
+
+Both web locations can be modified in the `.env` file:
+```ini
+...
+
+# Apache HTTP Server
+APACHE_VERSION=2.4
+APACHE_PORT=80
+APACHE_LOG_DIR=/var/log/apache
+APACHE_SERVER_NAME=mjanez-cautious-lamp-4pjq9vpg967hq447-80.preview.app.github.dev
+# Check CKAN__ROOT_PATH and CKANEXT__DCAT__BASE_URI. If you don't need to use domain locations, it is better to use the nginx configuration. Leave blank or use the root `/`.
+APACHE_CKAN_LOCATION=/catalog
+APACHE_PYCSW_LOCATION=/csw
+
+...
+```
+
### NGINX
-The base Docker Compose configuration uses an NGINX image as the front-end (ie: reverse proxy). It includes HTTPS running on port number 8443 and an HTTP port (81). A "self-signed" SSL certificate is generated beforehand and the server certificate and key files are included. The NGINX `server_name` directive and the `CN` field in the SSL certificate have been both set to 'localhost'. This should obviously not be used for production.
+>**Warning**
+> The [nginx docker compose file](/docker-compose.nginx.yml) only deploys the CKAN service, not ckan-pycsw.
+
+The nginx Docker Compose configuration ([`docker-compose.nginx.yml`](/docker-compose.nginx.yml)) uses an NGINX image as the front-end (ie: reverse proxy). It includes HTTPS running on port number 8443 and an HTTP port (81). A "self-signed" SSL certificate is generated beforehand and the server certificate and key files are included. The NGINX `server_name` directive and the `CN` field in the SSL certificate have been both set to 'localhost'. This should obviously not be used for production.
Creating the SSL cert and key files as follows:
`openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=DE/ST=Berlin/L=Berlin/O=None/CN=localhost" -keyout ckan-local.key -out ckan-local.crt`
diff --git a/apache/Dockerfile b/apache/Dockerfile
new file mode 100644
index 0000000..721cd5a
--- /dev/null
+++ b/apache/Dockerfile
@@ -0,0 +1,23 @@
+FROM httpd:2.4-alpine
+
+ENV CKAN_PORT_HOST=5000
+ENV PYCSW_PORT_HOST=8000
+ENV PYCSW_CONTAINER_NAME=pycsw
+ENV CKAN_CONTAINER_NAME=ckan
+ENV APACHE_PORT=80
+ENV APACHE_LOG_DIR=/var/log/apache
+ENV APACHE_ROOT=/usr/local/apache2
+ENV APACHE_DOCUMENT_ROOT=${APACHE_ROOT}/htdocs
+ENV APACHE_SERVER_NAME=localhost
+
+ENV APACHE_CKAN_LOCATION=/
+ENV APACHE_PYCSW_LOCATION=/csw
+ENV APACHE_PYCSW_PROXY_PASS=http://${PYCSW_CONTAINER_NAME}:${PYCSW_PORT_HOST}
+ENV APACHE_PROXY_PASS=http://${CKAN_CONTAINER_NAME}:${CKAN_PORT_HOST}
+
+RUN mkdir -p ${APACHE_LOG_DIR}
+
+COPY setup/httpd.conf ${APACHE_ROOT}/conf/httpd.conf
+COPY setup/index.html ${APACHE_DOCUMENT_ROOT}/index.html
+
+EXPOSE ${APACHE_PORT}
\ No newline at end of file
diff --git a/apache/setup/httpd.conf b/apache/setup/httpd.conf
new file mode 100644
index 0000000..1c527f5
--- /dev/null
+++ b/apache/setup/httpd.conf
@@ -0,0 +1,570 @@
+#
+# This is the main Apache HTTP server configuration file. It contains the
+# configuration directives that give the server its instructions.
+# See
+ CKAN Docker Apache landing page
+
+
+
+
\ No newline at end of file
diff --git a/ckan-pycsw/Dockerfile b/ckan-pycsw/Dockerfile
new file mode 100644
index 0000000..7adc83c
--- /dev/null
+++ b/ckan-pycsw/Dockerfile
@@ -0,0 +1,20 @@
+FROM ghcr.io/mjanez/ckan-pycsw:main
+
+# Set up environment variables
+ENV APP_DIR=/app
+ENV TZ=UTC
+RUN echo ${TZ} > /etc/timezone
+ENV PYCSW_CKAN_SCHEMA=iso19139_inspire
+ENV PYCSW_CONFIG=${APP_DIR}/pycsw.conf
+ENV CKAN_URL=http://localhost:5000/
+ENV PYCSW_PORT=8000
+ENV PYCSW_URL=http://localhost:${PYCSW_PORT}/
+ENV DEV_MODE: False
+ENV TIMEOUT=300
+WORKDIR ${APP_DIR}
+
+COPY pycsw/conf/pycsw.conf.template pycsw/entrypoint.sh .
+
+EXPOSE 8080/TCP
+ENTRYPOINT ["/bin/bash", "./entrypoint.sh"]
+CMD ["pdm", "run", "python3", "-m", "gunicorn", "pycsw.wsgi:application", "-b", "0.0.0.0:${PYCSW_PORT}"]
\ No newline at end of file
diff --git a/ckan-pycsw/pycsw/conf/pycsw.conf.template b/ckan-pycsw/pycsw/conf/pycsw.conf.template
new file mode 100644
index 0000000..607c3f3
--- /dev/null
+++ b/ckan-pycsw/pycsw/conf/pycsw.conf.template
@@ -0,0 +1,69 @@
+[server]
+home=${PWD}
+url=${PYCSW_URL}
+mimetype=application/xml; charset=UTF-8
+encoding=UTF-8
+language=en-US
+maxrecords=10
+#loglevel=DEBUG
+#logfile=/tmp/pycsw.log
+#ogc_schemas_base=http://foo
+#federatedcatalogues=http://catalog.data.gov/csw
+#pretty_print=true
+# Disable gzip_compresslevel when use httpd
+#gzip_compresslevel=9
+#domainquerytype=range
+#domaincounts=true
+#spatial_ranking=true
+profiles=apiso
+
+[manager]
+transactions=false
+allowed_ips=127.0.0.1
+#csw_harvest_pagesize=10
+
+[metadata:main]
+identification_title=Sample Geospatial Catalogue
+identification_abstract=OGC CSW server powered by pycsw
+identification_keywords=catalogue,discovery,metadata
+#identification_keywords_type=theme
+identification_fees=None
+identification_accessconstraints=None
+provider_name=Sample
+provider_url=https://example.org/
+#contact_name=admin
+#contact_position=Position Title
+#contact_address=Mailing Address
+#contact_city=Madrid
+#contact_stateorprovince=Administrative Area
+#contact_postalcode=Zip or Postal Code
+contact_country=Spain
+#contact_phone=+xx-xxx-xxx-xxxx
+#contact_fax=+xx-xxx-xxx-xxxx
+contact_email=admin@example.org
+#contact_url=https://example.org/members/admin
+#contact_hours=Hours of Service
+#contact_instructions=During hours of service. Off on weekends.
+contact_role=pointOfContact
+
+[repository]
+# sqlite
+database=sqlite:///${PWD}/cite.db
+# postgres
+#database=postgresql://ckan:ckan@db/pycsw
+# mysql
+#database=mysql://username:password@localhost/pycsw?charset=utf8
+#mappings=path/to/mappings.py
+table=records
+#filter=type='http://purl.org/dc/dcmitype/Dataset'
+
+#[metadata:inspire]
+enabled=true
+languages_supported=eng,spa
+default_language=eng
+date=YYYY-MM-DD
+gemet_keywords=Utility and governmental services
+conformity_service=notEvaluated
+contact_name=Organization Name
+contact_email=Email Address
+temp_extent=YYYY-MM-DD/YYYY-MM-DD
\ No newline at end of file
diff --git a/ckan-pycsw/pycsw/entrypoint.sh b/ckan-pycsw/pycsw/entrypoint.sh
new file mode 100644
index 0000000..3edfc21
--- /dev/null
+++ b/ckan-pycsw/pycsw/entrypoint.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -xeuo pipefail
+
+envsubst < pycsw.conf.template > pycsw.conf
+/wait-for --timeout "$TIMEOUT" "$CKAN_URL" -- pdm run python3 ckan2pycsw/ckan2pycsw.py
+
+exec "$@"
diff --git a/ckan/Dockerfile b/ckan/Dockerfile
index 1b3552e..bbafefd 100644
--- a/ckan/Dockerfile
+++ b/ckan/Dockerfile
@@ -7,53 +7,49 @@ RUN echo ${TZ} > /etc/timezone
# Make sure both files are not exactly the same
RUN if ! [ /usr/share/zoneinfo/${TZ} -ef /etc/localtime ]; then \
- cp /usr/share/zoneinfo/${TZ} /etc/localtime ;\
+ cp /usr/share/zoneinfo/${TZ} /etc/localtime ;\
fi ;
# Extensions
### XLoader - v0.12.2 ###
-RUN pip3 install -e 'git+https://github.com/ckan/ckanext-xloader.git@0.12.2#egg=ckanext-xloader' && \
- pip3 install -r ${APP_DIR}/src/ckanext-xloader/requirements.txt && \
- pip3 install -U requests[security]
-
### Harvester - v1.5.1 ###
-RUN echo "ckan/ckanext-harvest" && \
- pip3 install -e 'git+https://github.com/ckan/ckanext-harvest.git@v1.5.1#egg=ckanext-harvest' && \
- pip3 install -r ${APP_DIR}/src/ckanext-harvest/pip-requirements.txt
-
### Geoview - v0.0.20 ###
-RUN echo "ckan/ckanext-geoview" && \
- pip3 install -e 'git+https://github.com/ckan/ckanext-geoview.git@v0.0.20#egg=ckanext-geoview'
-
-### Spatial - v2.0.0 ###
-RUN echo "ckan/ckanext-spatial" && \
- pip3 install -e 'git+https://github.com/ckan/ckanext-spatial.git@v2.0.0#egg=ckanext-spatial' && \
- pip3 install -r https://raw.githubusercontent.com/ckan/ckanext-spatial/bae9290395b252ee8e40056256fa694569d1d78b/requirements.txt
-
+### Spatial - v2.0.0 ###
### DCAT - master (GeoDCAT-AP extended version) ###
-RUN echo "mjanez/ckanext-dcat (GeoDCAT-AP extended version)" && \
- pip3 install -e git+https://github.com/mjanez/ckanext-dcat.git#egg=ckanext-dcat && \
- pip3 install -r https://raw.githubusercontent.com/mjanez/ckanext-dcat/master/requirements.txt
-
### Scheming - master (GeoDCAT-AP extended version) ###
-RUN echo "mjanez/ckanext-scheming (GeoDCAT-AP extended version)" && \
- pip3 install -e git+https://github.com/mjanez/ckanext-scheming.git#egg=ckanext-scheming
-
### Resource dictionary (Fix version) - main ###
-RUN echo "mjanez/ckanext-resourcedictionary" && \
- pip3 install -e 'git+https://github.com/mjanez/ckanext-resourcedictionary.git#egg=ckanext-resourcedictionary'
-
### Pages - v0.5.1 ###
-RUN echo "ckan/ckanext-pages" && \
- pip3 install -e git+https://github.com/ckan/ckanext-pages.git@v0.5.1#egg=ckanext-pages
-
### PDFView - v0.0.8 ###
-RUN echo "ckan/ckanext-pdfview" && \
+RUN echo "ckan/ckanext-xloader" && \
+ pip3 install -e 'git+https://github.com/ckan/ckanext-xloader.git@0.12.2#egg=ckanext-xloader' && \
+ pip3 install -r ${APP_DIR}/src/ckanext-xloader/requirements.txt && \
+ pip3 install -U requests[security] && \
+ echo "ckan/ckanext-harvest" && \
+ pip3 install -e 'git+https://github.com/ckan/ckanext-harvest.git@v1.5.1#egg=ckanext-harvest' && \
+ pip3 install -r ${APP_DIR}/src/ckanext-harvest/pip-requirements.txt && \
+ echo "ckan/ckanext-geoview" && \
+ pip3 install -e 'git+https://github.com/ckan/ckanext-geoview.git@v0.0.20#egg=ckanext-geoview' && \
+ echo "ckan/ckanext-spatial" && \
+ pip3 install -e 'git+https://github.com/ckan/ckanext-spatial.git@v2.0.0#egg=ckanext-spatial' && \
+ pip3 install -r https://raw.githubusercontent.com/ckan/ckanext-spatial/bae9290395b252ee8e40056256fa694569d1d78b/requirements.txt && \
+ echo "mjanez/ckanext-dcat (GeoDCAT-AP extended version)" && \
+ pip3 install -e git+https://github.com/mjanez/ckanext-dcat.git#egg=ckanext-dcat && \
+ pip3 install -r https://raw.githubusercontent.com/mjanez/ckanext-dcat/master/requirements.txt && \
+ echo "mjanez/ckanext-scheming (GeoDCAT-AP extended version)" && \
+ pip3 install -e git+https://github.com/mjanez/ckanext-scheming.git#egg=ckanext-scheming && \
+ echo "mjanez/ckanext-resourcedictionary" && \
+ pip3 install -e 'git+https://github.com/mjanez/ckanext-resourcedictionary.git#egg=ckanext-resourcedictionary' && \
+ echo "ckan/ckanext-pages" && \
+ pip3 install -e git+https://github.com/ckan/ckanext-pages.git@v0.5.1#egg=ckanext-pages && \
+ echo "ckan/ckanext-pdfview" && \
pip3 install -e git+https://github.com/ckan/ckanext-pdfview.git@0.0.8#egg=ckanext-pdfview
# Used to configure the container environment by setting environment variables, creating users, running initialization scripts, .etc
COPY docker-entrypoint.d/* /docker-entrypoint.d/
+# Update who.ini with APACHE_CKAN_LOCATION
+COPY setup/who.ini ${APP_DIR}/
+
# Apply any patches needed to CKAN core
COPY patches ${APP_DIR}/patches
@@ -65,4 +61,4 @@ RUN for d in $APP_DIR/patches/*; do \
fi ; \
done
-CMD ["/srv/app/start_ckan.sh"]
+CMD $APP_DIR/start_ckan.sh
diff --git a/ckan/Dockerfile.dev b/ckan/Dockerfile.dev
index 6f2d24b..fb810ce 100644
--- a/ckan/Dockerfile.dev
+++ b/ckan/Dockerfile.dev
@@ -7,7 +7,7 @@ RUN echo ${TZ} > /etc/timezone
# Make sure both files are not exactly the same
RUN if ! [ /usr/share/zoneinfo/${TZ} -ef /etc/localtime ]; then \
- cp /usr/share/zoneinfo/${TZ} /etc/localtime ;\
+ cp /usr/share/zoneinfo/${TZ} /etc/localtime ;\
fi ;
# Install any extensions needed by your CKAN instance
@@ -49,6 +49,9 @@ RUN if ! [ /usr/share/zoneinfo/${TZ} -ef /etc/localtime ]; then \
# Used to configure the container environment by setting environment variables, creating users, running initialization scripts, .etc
COPY docker-entrypoint.d/* /docker-entrypoint.d/
+# Update who.ini with APACHE_CKAN_LOCATION
+COPY setup/who.ini ${APP_DIR}/
+
# Apply any patches needed to CKAN core or any of the built extensions (not the
# runtime mounted ones)
COPY patches ${APP_DIR}/patches
diff --git a/ckan/docker-entrypoint.d/00_update_who.sh b/ckan/docker-entrypoint.d/00_update_who.sh
new file mode 100644
index 0000000..11559ef
--- /dev/null
+++ b/ckan/docker-entrypoint.d/00_update_who.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# Update who.ini when exists APACHE_CKAN_LOCATION
+echo "Update who.ini"
+if [ -n "$APACHE_CKAN_LOCATION" ] && [ "$APACHE_CKAN_LOCATION" != "/" ]; then \
+ sed -i "s|\${WHO_LOCATION}|$APACHE_CKAN_LOCATION|g" ${APP_DIR}/who.ini; \
+ else \
+ sed -i "s|\${WHO_LOCATION}|/|g" ${APP_DIR}/who.ini; \
+ fi
\ No newline at end of file
diff --git a/ckan/docker-entrypoint.d/setup_xloader.sh b/ckan/docker-entrypoint.d/01_setup_xloader.sh
similarity index 100%
rename from ckan/docker-entrypoint.d/setup_xloader.sh
rename to ckan/docker-entrypoint.d/01_setup_xloader.sh
diff --git a/ckan/docker-entrypoint.d/setup_scheming.sh b/ckan/docker-entrypoint.d/02_setup_scheming.sh
similarity index 100%
rename from ckan/docker-entrypoint.d/setup_scheming.sh
rename to ckan/docker-entrypoint.d/02_setup_scheming.sh
diff --git a/ckan/docker-entrypoint.d/setup_dcat.sh b/ckan/docker-entrypoint.d/03_setup_dcat.sh
similarity index 100%
rename from ckan/docker-entrypoint.d/setup_dcat.sh
rename to ckan/docker-entrypoint.d/03_setup_dcat.sh
diff --git a/ckan/docker-entrypoint.d/setup_preview.sh b/ckan/docker-entrypoint.d/04_setup_preview.sh
similarity index 100%
rename from ckan/docker-entrypoint.d/setup_preview.sh
rename to ckan/docker-entrypoint.d/04_setup_preview.sh
diff --git a/ckan/setup/who.ini b/ckan/setup/who.ini
new file mode 100644
index 0000000..34a753f
--- /dev/null
+++ b/ckan/setup/who.ini
@@ -0,0 +1,32 @@
+[plugin:auth_tkt]
+use=ckan.lib.repoze_plugins.auth_tkt:make_plugin
+# If no secret key is defined here, beaker.session.secret will be used
+#secret = somesecret
+
+[plugin:friendlyform]
+use=ckan.lib.repoze_plugins.friendly_form:FriendlyFormPlugin
+login_form_url=${WHO_LOCATION}/user/login
+login_handler_path=/login_generic
+logout_handler_path=/user/logout
+rememberer_name=auth_tkt
+post_login_url=${WHO_LOCATION}/user/logged_in
+post_logout_url=${WHO_LOCATION}/user/logged_out
+charset=utf-8
+
+[general]
+request_classifier=repoze.who.classifiers:default_request_classifier
+challenge_decider=repoze.who.classifiers:default_challenge_decider
+
+[identifiers]
+plugins =
+ friendlyform;browser
+ auth_tkt
+
+[authenticators]
+plugins =
+ auth_tkt
+ ckan.lib.authenticator:UsernamePasswordAuthenticator
+
+[challengers]
+plugins =
+ friendlyform;browser
\ No newline at end of file
diff --git a/doc/img/ckan-docker-services.png b/doc/img/ckan-docker-services.png
new file mode 100644
index 0000000..d3e9c7b
Binary files /dev/null and b/doc/img/ckan-docker-services.png differ
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
old mode 100755
new mode 100644
index 5fc9ea4..ba37362
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -56,7 +56,7 @@ services:
- solr_data:/var/solr
restart: unless-stopped
healthcheck:
- test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:8983/solr/"]
+ test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:${SOLR_PORT}/solr/"]
redis:
container_name: ${REDIS_CONTAINER_NAME}
diff --git a/docker-compose.nginx.yml b/docker-compose.nginx.yml
new file mode 100644
index 0000000..7fb2f8c
--- /dev/null
+++ b/docker-compose.nginx.yml
@@ -0,0 +1,86 @@
+# With NGINX and without ckan-pycsw
+version: "3"
+
+volumes:
+ ckan_storage:
+ pg_data:
+ solr_data:
+
+services:
+
+ nginx:
+ container_name: ${NGINX_CONTAINER_NAME}
+ build:
+ context: nginx/
+ dockerfile: Dockerfile
+ env_file:
+ - .env
+ depends_on:
+ ckan:
+ condition: service_healthy
+ ports:
+ - "0.0.0.0:${NGINX_PORT_HOST}:${NGINX_PORT}"
+ - "0.0.0.0:${NGINX_SSLPORT_HOST}:${NGINX_SSLPORT}"
+
+ ckan:
+ container_name: ${CKAN_CONTAINER_NAME}
+ build:
+ context: ckan/
+ dockerfile: Dockerfile
+ args:
+ - TZ=${TZ}
+ image: ghcr.io/mjanez/ckan-spatial:master
+ env_file:
+ - .env
+ depends_on:
+ db:
+ condition: service_healthy
+ solr:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ ports:
+ - "0.0.0.0:${CKAN_PORT_HOST}:${CKAN_PORT}"
+ volumes:
+ - ckan_storage:/var/lib/ckan
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:5000"]
+
+ db:
+ container_name: ${POSTGRESQL_CONTAINER_NAME}
+ build:
+ context: postgresql/
+ args:
+ - DATASTORE_READONLY_PASSWORD=${DATASTORE_READONLY_PASSWORD}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ environment:
+ - DATASTORE_READONLY_PASSWORD=${DATASTORE_READONLY_PASSWORD}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ - PGDATA=/var/lib/postgresql/data/db
+ volumes:
+ - pg_data:/var/lib/postgresql/data
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "pg_isready", "-U", "ckan"]
+
+ solr:
+ container_name: ${SOLR_CONTAINER_NAME}
+ build:
+ context: solr/
+ dockerfile: Dockerfile.spatial
+ image: ckan/ckan-solr:${SOLR_IMAGE_VERSION}
+ env_file:
+ - .env
+ volumes:
+ - solr_data:/var/solr
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:${SOLR_PORT}/solr/"]
+
+ redis:
+ container_name: ${REDIS_CONTAINER_NAME}
+ image: redis:${REDIS_VERSION}
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "redis-cli", "-e", "QUIT"]
diff --git a/docker-compose.yml b/docker-compose.yml
old mode 100755
new mode 100644
index e51be94..59b568c
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,19 +6,22 @@ volumes:
solr_data:
services:
-
- nginx:
- container_name: ${NGINX_CONTAINER_NAME}
+
+ apache:
+ container_name: ${APACHE_CONTAINER_NAME}
build:
- context: nginx/
+ context: apache/
dockerfile: Dockerfile
+ #image: httpd:${APACHE_VERSION}
+ env_file:
+ - .env
depends_on:
ckan:
condition: service_healthy
ports:
- - "0.0.0.0:${NGINX_PORT_HOST}:${NGINX_PORT}"
- - "0.0.0.0:${NGINX_SSLPORT_HOST}:${NGINX_SSLPORT}"
-
+ - "0.0.0.0:${APACHE_PORT_HOST}:${APACHE_PORT}"
+ restart: on-failure:3
+
ckan:
container_name: ${CKAN_CONTAINER_NAME}
build:
@@ -42,8 +45,27 @@ services:
- ckan_storage:/var/lib/ckan
restart: unless-stopped
healthcheck:
- test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:5000"]
-
+ test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:${CKAN_PORT}"]
+
+ pycsw:
+ container_name: ${PYCSW_CONTAINER_NAME}
+ build:
+ context: ckan-pycsw/
+ dockerfile: Dockerfile
+ env_file:
+ - .env
+ depends_on:
+ ckan:
+ condition: service_healthy
+ ports:
+ - "0.0.0.0:${PYCSW_PORT_HOST}:${PYCSW_PORT}"
+ volumes:
+ - ./log:${APP_DIR}/log
+ - ./metadata:${APP_DIR}/metadata
+ restart: on-failure:3
+ healthcheck:
+ test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:${PYCSW_PORT}"]
+
db:
container_name: ${POSTGRESQL_CONTAINER_NAME}
build:
@@ -63,12 +85,17 @@ services:
solr:
container_name: ${SOLR_CONTAINER_NAME}
+ build:
+ context: solr/
+ dockerfile: Dockerfile.spatial
image: ckan/ckan-solr:${SOLR_IMAGE_VERSION}
+ env_file:
+ - .env
volumes:
- solr_data:/var/solr
restart: unless-stopped
healthcheck:
- test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:8983/solr/"]
+ test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:${SOLR_PORT}/solr/"]
redis:
container_name: ${REDIS_CONTAINER_NAME}
diff --git a/nginx/Dockerfile b/nginx/Dockerfile
index 8abad79..b7b6abc 100644
--- a/nginx/Dockerfile
+++ b/nginx/Dockerfile
@@ -1,6 +1,7 @@
FROM nginx:stable-alpine
ENV NGINX_DIR=/etc/nginx
+ENV NGINX_PORT=80
COPY setup/nginx.conf ${NGINX_DIR}/nginx.conf
COPY setup/index.html /usr/share/nginx/html/index.html
@@ -9,4 +10,4 @@ COPY setup/default.conf ${NGINX_DIR}/conf.d/
RUN mkdir -p ${NGINX_DIR}/certs
COPY setup/ckan-local.* ${NGINX_DIR}/certs/
-EXPOSE 81
\ No newline at end of file
+EXPOSE ${NGINX_PORT}
\ No newline at end of file
diff --git a/samples/.env.example b/samples/.env.example
index 5437e53..c364641 100644
--- a/samples/.env.example
+++ b/samples/.env.example
@@ -1,3 +1,6 @@
+# Base
+APP_DIR=/srv/app
+
# Container names
NGINX_CONTAINER_NAME=nginx
REDIS_CONTAINER_NAME=redis
@@ -5,11 +8,47 @@ POSTGRESQL_CONTAINER_NAME=db
SOLR_CONTAINER_NAME=solr
CKAN_CONTAINER_NAME=ckan
WORKER_CONTAINER_NAME=ckan-worker
+APACHE_CONTAINER_NAME=apache
+PYCSW_CONTAINER_NAME=pycsw
# Host Ports
CKAN_PORT_HOST=5000
-NGINX_PORT_HOST=81
+NGINX_PORT_HOST=80
NGINX_SSLPORT_HOST=8443
+APACHE_PORT_HOST=80
+PYCSW_PORT_HOST=8000
+
+# Solr
+SOLR_IMAGE_VERSION=2.9-solr8-spatial
+SOLR_PORT=8983
+CKAN_SOLR_URL=http://solr:${SOLR_PORT}/solr/ckan
+TEST_CKAN_SOLR_URL=http://solr:${SOLR_PORT}/solr/ckan
+
+# Redis
+REDIS_VERSION=7-alpine
+CKAN_REDIS_URL=redis://redis:6379/1
+TEST_CKAN_REDIS_URL=redis://redis:6379/1
+
+# NGINX
+NGINX_PORT=80
+NGINX_SSLPORT=443
+
+# Apache HTTP Server
+APACHE_VERSION=2.4-alpine
+APACHE_PORT=80
+APACHE_LOG_DIR=/var/log/apache
+APACHE_SERVER_NAME=localhost
+# Check CKAN__ROOT_PATH and CKANEXT__DCAT__BASE_URI. If you don't need to use domain locations, it is better to use the nginx configuration.
+APACHE_CKAN_LOCATION=/catalog
+APACHE_PYCSW_LOCATION=/csw
+
+# pycsw
+PYCSW_PORT=8000
+CKAN_URL=https://localhost:5000/catalog
+PYCSW_URL=https://localhost:5000/csw
+# SCHEMAS: ckan2pycsw/model/dataset.py - Dataset type
+PYCSW_CKAN_SCHEMA=iso19139_geodcatap
+PYCSW_OUPUT_SCHEMA=iso19139_inspire
# CKAN databases
POSTGRES_USER=ckan
@@ -29,9 +68,9 @@ TEST_CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:datastore@db/datastore_te
# CKAN core
CKAN_VERSION=2.9.8
CKAN_SITE_ID=default
-CKAN_SITE_URL=http://localhost:5000
+CKAN_SITE_URL=https://localhost:5000
+CKAN__ROOT_PATH=/catalog/{{LANG}}
CKAN_PORT=5000
-CKAN_PORT_HOST=5000
CKAN___BEAKER__SESSION__SECRET=CHANGE_ME
# See https://docs.ckan.org/en/latest/maintaining/configuration.html#api-token-settings
CKAN___API_TOKEN__JWT__ENCODE__SECRET=string:CHANGE_ME
@@ -49,8 +88,10 @@ TZ=UTC
## Customize which text formats the text_view plugin will show
CKAN__PREVIEW__JSON_FORMATS="json jsonld"
# html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json
-CKAN__PREVIEW__XML_FORMATS="html htm xml rdf rdf+xml owl+xml atom rss turtle ttl n3 n-triples"
+CKAN__PREVIEW__XML_FORMATS="xml rdf rdf+xml owl+xml atom rss turtle ttl n3 n-triples"
CKAN__PREVIEW__TEXT_FORMATS="text plain text/plain text/turtle csv tsv rss txt json"
+CKAN__PREVIEW__LOADABLE="html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json arcgis_rest"
+
## Resource Proxy settings
### Preview size limit, default: 1MB
CKAN__RESOURCE_PROXY__MAX_FILE_SIZE=50048576
@@ -58,25 +99,16 @@ CKAN__RESOURCE_PROXY__MAX_FILE_SIZE=50048576
CKAN__RESOURCE_PROXY__CHUNK_SIZE=4096
## Default timeout for fetching proxied items
CKAN__RESOURCE_PROXY__TIMEOUT=10
-CKAN__VIEWS__DEFAULT_VIEWS="image_view text_view recline_view wmts_view geojson_view geo_view shp_view pdf_view"
+CKAN__VIEWS__DEFAULT_VIEWS="image_view webpage_view text_view recline_view wmts_view geojson_view geo_view shp_view pdf_view"
-# Solr
-SOLR_IMAGE_VERSION=2.9-solr8-spatial
-CKAN_SOLR_URL=http://solr:8983/solr/ckan
-TEST_CKAN_SOLR_URL=http://solr:8983/solr/ckan
-
-# Redis
-REDIS_VERSION=6
-CKAN_REDIS_URL=redis://redis:6379/1
-TEST_CKAN_REDIS_URL=redis://redis:6379/1
-
-# NGINX
-NGINX_PORT=80
-NGINX_SSLPORT=443
+# Localization
+CKAN__LOCALE_DEFAULT="en"
+CKAN__LOCALE_ORDER="en es pt_BR ja it cs_CZ ca fr el sv sr sr@latin no sk fi ru de pl nl bg ko_KR hu sa sl lv"
# Extensions
-CKAN__PLUGINS="envvars stats text_view image_view recline_view resourcedictionary datastore xloader harvest ckan_harvester spatial_metadata spatial_query spatial_harvest_metadata_api csw_harvester waf_harvester doc_harvester resource_proxy geo_view geojson_view wmts_view shp_view dcat dcat_rdf_harvester dcat_json_harvester dcat_json_interface scheming_datasets scheming_groups scheming_organizations pdf_view pages"
+CKAN__PLUGINS="envvars stats text_view image_view webpage_view recline_view resourcedictionary datastore xloader harvest ckan_harvester spatial_metadata spatial_query spatial_harvest_metadata_api csw_harvester waf_harvester doc_harvester resource_proxy geo_view geojson_view wmts_view shp_view dcat dcat_rdf_harvester dcat_json_harvester dcat_json_interface scheming_datasets scheming_groups scheming_organizations pdf_view pages"
+# ckanext-harvest
CKAN__HARVEST__MQ__TYPE=redis
CKAN__HARVEST__MQ__HOSTNAME=redis
CKAN__HARVEST__MQ__PORT=6379
@@ -87,7 +119,7 @@ CKANEXT__XLOADER__API_TOKEN=api_token
CKANEXT__XLOADER__JOBS__DB_URI=postgresql://ckan:ckan@db/ckan
# ckanext-dcat
-CKANEXT__DCAT__BASE_URI=https://localhost:5000
+CKANEXT__DCAT__BASE_URI=https://localhost:5000/catalog
CKANEXT__DCAT__RDF_PROFILES="euro_dcat_ap_2 euro_dcat_ap"
# ckanext-scheming: setup_scheming.sh
diff --git a/samples/.env.nginx.example b/samples/.env.nginx.example
new file mode 100644
index 0000000..6704e87
--- /dev/null
+++ b/samples/.env.nginx.example
@@ -0,0 +1,124 @@
+# Base
+APP_DIR=/srv/app
+
+# Container names
+NGINX_CONTAINER_NAME=nginx
+REDIS_CONTAINER_NAME=redis
+POSTGRESQL_CONTAINER_NAME=db
+SOLR_CONTAINER_NAME=solr
+CKAN_CONTAINER_NAME=ckan
+WORKER_CONTAINER_NAME=ckan-worker
+
+# Host Ports
+CKAN_PORT_HOST=5000
+NGINX_PORT_HOST=80
+NGINX_SSLPORT_HOST=8443
+
+# Solr
+SOLR_IMAGE_VERSION=2.9-solr8-spatial
+SOLR_PORT=8983
+CKAN_SOLR_URL=http://solr:${SOLR_PORT}/solr/ckan
+TEST_CKAN_SOLR_URL=http://solr:${SOLR_PORT}/solr/ckan
+
+# Redis
+REDIS_VERSION=7-alpine
+CKAN_REDIS_URL=redis://redis:6379/1
+TEST_CKAN_REDIS_URL=redis://redis:6379/1
+
+# NGINX
+NGINX_PORT=80
+NGINX_SSLPORT=443
+
+# CKAN databases
+POSTGRES_USER=ckan
+POSTGRES_PASSWORD=ckan
+DATASTORE_READONLY_USER=datastore_ro
+DATASTORE_READONLY_PASSWORD=datastore
+POSTGRES_HOST=db
+CKAN_SQLALCHEMY_URL=postgresql://ckan:ckan@db/ckan
+CKAN_DATASTORE_WRITE_URL=postgresql://ckan:ckan@db/datastore
+CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:datastore@db/datastore
+
+# Test database connections
+TEST_CKAN_SQLALCHEMY_URL=postgres://ckan:ckan@db/ckan_test
+TEST_CKAN_DATASTORE_WRITE_URL=postgresql://ckan:ckan@db/datastore_test
+TEST_CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:datastore@db/datastore_test
+
+# CKAN core
+CKAN_VERSION=2.9.8
+CKAN_SITE_ID=default
+CKAN_SITE_URL=http://localhost:5000
+CKAN_PORT=5000
+CKAN___BEAKER__SESSION__SECRET=CHANGE_ME
+# See https://docs.ckan.org/en/latest/maintaining/configuration.html#api-token-settings
+CKAN___API_TOKEN__JWT__ENCODE__SECRET=string:CHANGE_ME
+CKAN___API_TOKEN__JWT__DECODE__SECRET=string:CHANGE_ME
+CKAN_SYSADMIN_NAME=ckan_admin
+CKAN_SYSADMIN_PASSWORD=test1234
+CKAN_SYSADMIN_EMAIL=your_email@example.com
+CKAN_STORAGE_PATH=/var/lib/ckan
+CKAN_SMTP_SERVER=smtp.corporateict.domain:25
+CKAN_SMTP_STARTTLS=True
+CKAN_SMTP_USER=user
+CKAN_SMTP_PASSWORD=pass
+CKAN_SMTP_MAIL_FROM=ckan@localhost
+TZ=UTC
+## Customize which text formats the text_view plugin will show
+CKAN__PREVIEW__JSON_FORMATS="json jsonld"
+# html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json
+CKAN__PREVIEW__XML_FORMATS="xml rdf rdf+xml owl+xml atom rss turtle ttl n3 n-triples"
+CKAN__PREVIEW__TEXT_FORMATS="text plain text/plain text/turtle csv tsv rss txt json"
+CKAN__PREVIEW__LOADABLE="html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json arcgis_rest"
+
+## Resource Proxy settings
+### Preview size limit, default: 1MB
+CKAN__RESOURCE_PROXY__MAX_FILE_SIZE=50048576
+## Size of chunks to read/write__
+CKAN__RESOURCE_PROXY__CHUNK_SIZE=4096
+## Default timeout for fetching proxied items
+CKAN__RESOURCE_PROXY__TIMEOUT=10
+CKAN__VIEWS__DEFAULT_VIEWS="image_view webpage_view text_view recline_view wmts_view geojson_view geo_view shp_view pdf_view"
+
+# Localization
+CKAN__LOCALE_DEFAULT="en"
+CKAN__LOCALE_ORDER="en es pt_BR ja it cs_CZ ca fr el sv sr sr@latin no sk fi ru de pl nl bg ko_KR hu sa sl lv"
+
+# Extensions
+CKAN__PLUGINS="envvars stats text_view image_view webpage_view recline_view resourcedictionary datastore xloader harvest ckan_harvester spatial_metadata spatial_query spatial_harvest_metadata_api csw_harvester waf_harvester doc_harvester resource_proxy geo_view geojson_view wmts_view shp_view dcat dcat_rdf_harvester dcat_json_harvester dcat_json_interface scheming_datasets scheming_groups scheming_organizations pdf_view pages"
+
+# ckanext-harvest
+CKAN__HARVEST__MQ__TYPE=redis
+CKAN__HARVEST__MQ__HOSTNAME=redis
+CKAN__HARVEST__MQ__PORT=6379
+CKAN__HARVEST__MQ__REDIS_DB=1
+
+# ckanext-xloader
+CKANEXT__XLOADER__API_TOKEN=api_token
+CKANEXT__XLOADER__JOBS__DB_URI=postgresql://ckan:ckan@db/ckan
+
+# ckanext-dcat
+CKANEXT__DCAT__BASE_URI=https://localhost:5000/
+CKANEXT__DCAT__RDF_PROFILES="euro_dcat_ap_2 euro_dcat_ap"
+
+# ckanext-scheming: setup_scheming.sh
+SCHEMA_CKANEXT_SCHEMING_DATASET_SCHEMA="ckanext.scheming:ckan_geodcatap.yaml"
+SCHEMA_CKANEXT_SCHEMING_GROUP_SCHEMAS="ckanext.scheming:ckan_group_geodcatap.json"
+SCHEMA_CKANEXT_SCHEMING_ORGANIZATION_SCHEMAS="ckanext.scheming:ckan_org_geodcatap.json"
+SCHEMA_CKANEXT_SCHEMING_PRESETS="ckanext.scheming:presets.json"
+
+# ckanext-spatial (Solr Backend - solr8-spatial)
+CKANEXT__SPATIAL__SEARCH_BACKEND=solr-bbox
+CKAN__SPATIAL__SRID=3857
+CKANEXT__SPATIAL__COMMON_MAP__TYPE=custom
+CKANEXT__SPATIAL__COMMON_MAP__CUSTOM__URL=https://rts.larioja.org/mapa-base/rioja/{z}/{x}/{y}.png
+CKANEXT__SPATIAL__COMMON_MAP__ATTRIBUTION='Servicios de Teselas. IDEE, bajo CC BY 3.0.'
+
+# ckanext-geoview
+CKANEXT__GEOVIEW__GEOJSON__MAX_FILE_SIZE=100000000
+CKANEXT__GEOVIEW__OL_VIEWER__FORMATS="wms wfs geojson gml kml"
+CKANEXT__GEOVIEW__SHP_VIEWER__SRID=3857
+CKANEXT__GEOVIEW__SHP_VIEWER__ENCODING=UTF-8
+
+#TODO: ckanext-sparql - Not implemented yet
+CKANEXT__SPARQL__ENDPOINT_URL=http://dbpedia.org/sparql
+CKANEXT__SPARQL__HIDE_ENDPOINT_URL=False
\ No newline at end of file
diff --git a/solr/Dockerfile b/solr/Dockerfile
old mode 100755
new mode 100644
index cbd1432..cb9c480
--- a/solr/Dockerfile
+++ b/solr/Dockerfile
@@ -1,6 +1,8 @@
FROM solr:8
-EXPOSE 8983
+ENV SOLR_PORT=8983
+
+EXPOSE ${SOLR_PORT}
ARG CKAN_BRANCH="dev-v2.10"
diff --git a/solr/Dockerfile.spatial b/solr/Dockerfile.spatial
index c3171f7..d789828 100644
--- a/solr/Dockerfile.spatial
+++ b/solr/Dockerfile.spatial
@@ -1,6 +1,8 @@
FROM solr:8
-EXPOSE 8983
+ENV SOLR_PORT=8983
+
+EXPOSE ${SOLR_PORT}
ARG CKAN_BRANCH="dev-v2.10"