deleted unused files
This commit is contained in:
parent
a9989167f9
commit
d7ee7d66f3
|
@ -1,36 +0,0 @@
|
|||
# Runtime configuration of CKAN enabled through ckanext-envvars
|
||||
# Information about how it works: https://github.com/okfn/ckanext-envvars
|
||||
# Note that variables here take presedence over build/up time variables in .env
|
||||
|
||||
# Set to true to disable CKAN from starting and serve a maintenance page
|
||||
MAINTENANCE_MODE=false
|
||||
|
||||
# General Settings
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
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 Plugins
|
||||
CKAN__PLUGINS=envvars image_view text_view recline_view datastore datapusher
|
||||
# CKAN requires storage path to be set in order for filestore to be enabled
|
||||
CKAN__STORAGE_PATH=/srv/app/data
|
||||
CKAN__WEBASSETS__PATH=/srv/app/data/webassets
|
||||
# SYSADMIN settings, a sysadmin user is created automatically with the below credentials
|
||||
CKAN_SYSADMIN_NAME=sysadmin
|
||||
CKAN_SYSADMIN_PASSWORD=password
|
||||
CKAN_SYSADMIN_EMAIL=sysadmin@ckantest.com
|
||||
|
||||
# Email settings
|
||||
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
|
||||
|
||||
# Datapusher configuration
|
||||
CKAN__DATAPUSHER__URL=http://datapusher:8000
|
||||
CKAN__DATAPUSHER__CALLBACK_URL_BASE=http://ckan:5000/
|
|
@ -1,32 +0,0 @@
|
|||
# Variables in this file will be used as build arguments when running
|
||||
# docker-compose build and docker-compose up
|
||||
# Verify correct substitution with "docker-compose config"
|
||||
# If variables are newly added or enabled, please delete and rebuild the images to pull in changes:
|
||||
# docker-compose down -v
|
||||
# docker-compose build
|
||||
# docker-compose up -d
|
||||
|
||||
# Database
|
||||
POSTGRES_PASSWORD=ckan
|
||||
POSTGRES_PORT=5432
|
||||
DATASTORE_READONLY_PASSWORD=datastore
|
||||
|
||||
# CKAN
|
||||
CKAN_VERSION=2.8.12
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
|
||||
# Datapusher
|
||||
DATAPUSHER_VERSION=0.0.17
|
||||
DATAPUSHER_MAX_CONTENT_LENGTH=10485760
|
||||
DATAPUSHER_CHUNK_SIZE=16384
|
||||
DATAPUSHER_CHUNK_INSERT_ROWS=250
|
||||
DATAPUSHER_DOWNLOAD_TIMEOUT=30
|
||||
DATAPUSHER_SSL_VERIFY=False
|
||||
DATAPUSHER_REWRITE_RESOURCES=True
|
||||
DATAPUSHER_REWRITE_URL=http://ckan:5000
|
||||
|
||||
# Redis
|
||||
REDIS_VERSION=6.0.7
|
|
@ -1,93 +0,0 @@
|
|||
# docker-compose build && docker-compose up -d
|
||||
version: "3"
|
||||
|
||||
volumes:
|
||||
ckan_data:
|
||||
pg_data:
|
||||
solr_data:
|
||||
|
||||
services:
|
||||
ckan:
|
||||
container_name: ckan
|
||||
image: ghcr.io/keitaroinc/ckan:${CKAN_VERSION}
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- solr
|
||||
ports:
|
||||
- "0.0.0.0:${CKAN_PORT}:5000"
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
volumes:
|
||||
- ckan_data:/srv/app/data
|
||||
|
||||
datapusher:
|
||||
container_name: datapusher
|
||||
image: ghcr.io/keitaroinc/datapusher:${DATAPUSHER_VERSION}
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- DATAPUSHER_MAX_CONTENT_LENGTH=${DATAPUSHER_MAX_CONTENT_LENGTH}
|
||||
- DATAPUSHER_CHUNK_SIZE=${DATAPUSHER_CHUNK_SIZE}
|
||||
- DATAPUSHER_CHUNK_INSERT_ROWS=${DATAPUSHER_CHUNK_INSERT_ROWS}
|
||||
- DATAPUSHER_DOWNLOAD_TIMEOUT=${DATAPUSHER_DOWNLOAD_TIMEOUT}
|
||||
- DATAPUSHER_SSL_VERIFY=${DATA_PUSHER_SSL_VERIFY}
|
||||
- DATAPUSHER_REWRITE_RESOURCES=${DATAPUSHER_REWRITE_RESOURCES}
|
||||
- DATAPUSHER_REWRITE_URL=${DATAPUSHER_REWRITE_URL}
|
||||
|
||||
|
||||
db:
|
||||
container_name: db
|
||||
build:
|
||||
context: .
|
||||
dockerfile: postgresql/Dockerfile
|
||||
args:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
networks:
|
||||
- backend
|
||||
environment:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- PGDATA=/var/lib/postgresql/data/db
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "ckan"]
|
||||
|
||||
solr:
|
||||
container_name: solr
|
||||
build:
|
||||
context: .
|
||||
dockerfile: solr/Dockerfile
|
||||
args:
|
||||
- CKAN_VERSION=${CKAN_VERSION}
|
||||
networks:
|
||||
- backend
|
||||
volumes:
|
||||
- solr_data:/opt/solr/server/solr/ckan/data
|
||||
|
||||
redis:
|
||||
container_name: redis
|
||||
image: redis:${REDIS_VERSION}
|
||||
networks:
|
||||
- backend
|
||||
|
||||
networks:
|
||||
frontend:
|
||||
backend:
|
|
@ -1,13 +0,0 @@
|
|||
FROM postgis/postgis:11-3.3-alpine
|
||||
|
||||
# Allow connections; we don't map out any ports so only linked docker containers can connect
|
||||
RUN echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf
|
||||
|
||||
# Customize default user/pass/db
|
||||
ENV POSTGRES_DB ckan
|
||||
ENV POSTGRES_USER ckan
|
||||
ARG POSTGRES_PASSWORD
|
||||
ARG DS_RO_PASS
|
||||
|
||||
# Include datastore setup scripts
|
||||
COPY ./postgresql/docker-entrypoint-initdb.d /docker-entrypoint-initdb.d
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||
CREATE ROLE datastore_ro NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN PASSWORD '$DS_RO_PASS';
|
||||
CREATE DATABASE datastore OWNER ckan ENCODING 'utf-8';
|
||||
GRANT ALL PRIVILEGES ON DATABASE datastore TO ckan;
|
||||
EOSQL
|
|
@ -1,2 +0,0 @@
|
|||
ALTER VIEW geometry_columns OWNER TO ckan;
|
||||
ALTER TABLE spatial_ref_sys OWNER TO ckan;
|
|
@ -1,35 +0,0 @@
|
|||
FROM solr:6.6.6
|
||||
|
||||
# Enviroment
|
||||
ENV SOLR_CORE ckan
|
||||
ENV SOLR_VERSION 6.6.6
|
||||
|
||||
# Build Arguments
|
||||
ARG CKAN_VERSION
|
||||
|
||||
# Create Directories
|
||||
RUN mkdir -p /opt/solr/server/solr/$SOLR_CORE/conf
|
||||
RUN mkdir -p /opt/solr/server/solr/$SOLR_CORE/data
|
||||
|
||||
# Adding Files
|
||||
COPY ./solr/solrconfig-$CKAN_VERSION.xml /opt/solr/server/solr/$SOLR_CORE/conf/
|
||||
ADD https://raw.githubusercontent.com/ckan/ckan/ckan-$CKAN_VERSION/ckan/config/solr/schema.xml \
|
||||
https://raw.githubusercontent.com/apache/lucene-solr/releases/lucene-solr/$SOLR_VERSION/solr/server/solr/configsets/basic_configs/conf/currency.xml \
|
||||
https://raw.githubusercontent.com/apache/lucene-solr/releases/lucene-solr/$SOLR_VERSION/solr/server/solr/configsets/basic_configs/conf/synonyms.txt \
|
||||
https://raw.githubusercontent.com/apache/lucene-solr/releases/lucene-solr/$SOLR_VERSION/solr/server/solr/configsets/basic_configs/conf/stopwords.txt \
|
||||
https://raw.githubusercontent.com/apache/lucene-solr/releases/lucene-solr/$SOLR_VERSION/solr/server/solr/configsets/basic_configs/conf/protwords.txt \
|
||||
https://raw.githubusercontent.com/apache/lucene-solr/releases/lucene-solr/$SOLR_VERSION/solr/server/solr/configsets/data_driven_schema_configs/conf/elevate.xml \
|
||||
/opt/solr/server/solr/$SOLR_CORE/conf/
|
||||
|
||||
# Create Core.properties
|
||||
RUN mv /opt/solr/server/solr/$SOLR_CORE/conf/solrconfig-$CKAN_VERSION.xml /opt/solr/server/solr/$SOLR_CORE/conf/solrconfig.xml && \
|
||||
echo name=$SOLR_CORE > /opt/solr/server/solr/$SOLR_CORE/core.properties
|
||||
|
||||
# Giving ownership to Solr
|
||||
|
||||
USER root
|
||||
|
||||
RUN chown -R "$SOLR_USER:$SOLR_USER" /opt/solr/server/solr/$SOLR_CORE
|
||||
|
||||
# User
|
||||
USER $SOLR_USER:$SOLR_USER
|
|
@ -1 +0,0 @@
|
|||
solrconfig-2.8.10.xml
|
|
@ -1,343 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--solrconfig.xml documentation [https://wiki.apache.org/solr/SolrConfigXml]-->
|
||||
<config>
|
||||
|
||||
<luceneMatchVersion>6.0.0</luceneMatchVersion>
|
||||
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/extraction/lib" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-cell-\d.*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/clustering/lib/" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-clustering-\d.*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-\d.*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
|
||||
|
||||
<dataDir>${solr.data.dir:}</dataDir>
|
||||
|
||||
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}" />
|
||||
|
||||
<codecFactory class="solr.SchemaCodecFactory" />
|
||||
|
||||
<indexConfig>
|
||||
<lockType>${solr.lock.type:native}</lockType>
|
||||
</indexConfig>
|
||||
|
||||
<jmx />
|
||||
|
||||
<updateHandler class="solr.DirectUpdateHandler2">
|
||||
|
||||
<updateLog>
|
||||
<str name="dir">${solr.ulog.dir:}</str>
|
||||
<int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
|
||||
</updateLog>
|
||||
|
||||
<autoCommit>
|
||||
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
|
||||
<openSearcher>false</openSearcher>
|
||||
</autoCommit>
|
||||
|
||||
<autoSoftCommit>
|
||||
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
|
||||
</autoSoftCommit>
|
||||
|
||||
</updateHandler>
|
||||
|
||||
<query>
|
||||
|
||||
<maxBooleanClauses>1024</maxBooleanClauses>
|
||||
<filterCache class="solr.FastLRUCache" size="512" initialSize="512" autowarmCount="0" />
|
||||
<queryResultCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0" />
|
||||
<documentCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0" />
|
||||
<cache name="perSegFilter" class="solr.search.LRUCache" size="10" initialSize="0" autowarmCount="10" regenerator="solr.NoOpRegenerator" />
|
||||
<enableLazyFieldLoading>true</enableLazyFieldLoading>
|
||||
<queryResultWindowSize>20</queryResultWindowSize>
|
||||
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
|
||||
|
||||
<listener event="newSearcher" class="solr.QuerySenderListener">
|
||||
<arr name="queries" />
|
||||
</listener>
|
||||
|
||||
<listener event="firstSearcher" class="solr.QuerySenderListener">
|
||||
<arr name="queries" />
|
||||
</listener>
|
||||
|
||||
<useColdSearcher>false</useColdSearcher>
|
||||
<maxWarmingSearchers>2</maxWarmingSearchers>
|
||||
|
||||
</query>
|
||||
|
||||
<requestDispatcher handleSelect="false">
|
||||
|
||||
<requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048000" formdataUploadLimitInKB="2048" addHttpRequestToContext="false" />
|
||||
<httpCaching never304="true" />
|
||||
|
||||
</requestDispatcher>
|
||||
|
||||
<requestHandler name="/select" class="solr.SearchHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<int name="rows">10</int>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<requestHandler name="/query" class="solr.SearchHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<str name="wt">json</str>
|
||||
<str name="indent">true</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell,/browse">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="df">_text_</str>
|
||||
</lst>
|
||||
|
||||
</initParams>
|
||||
|
||||
<initParams path="/update/**">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="update.chain">add-unknown-fields-to-the-schema</str>
|
||||
</lst>
|
||||
|
||||
</initParams>
|
||||
|
||||
<requestHandler name="/update/extract" startup="lazy" class="solr.extraction.ExtractingRequestHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="lowernames">true</str>
|
||||
<str name="fmap.meta">ignored_</str>
|
||||
<str name="fmap.content">_text_</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<requestHandler name="/analysis/field" startup="lazy" class="solr.FieldAnalysisRequestHandler" />
|
||||
<requestHandler name="/analysis/document" class="solr.DocumentAnalysisRequestHandler" startup="lazy" />
|
||||
|
||||
<requestHandler name="/debug/dump" class="solr.DumpRequestHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<str name="echoHandler">true</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
|
||||
|
||||
<str name="queryAnalyzerFieldType">text_general</str>
|
||||
|
||||
<lst name="spellchecker">
|
||||
<str name="name">default</str>
|
||||
<str name="field">_text_</str>
|
||||
<str name="classname">solr.DirectSolrSpellChecker</str>
|
||||
<str name="distanceMeasure">internal</str>
|
||||
<float name="accuracy">0.5</float>
|
||||
<int name="maxEdits">2</int>
|
||||
<int name="minPrefix">1</int>
|
||||
<int name="maxInspections">5</int>
|
||||
<int name="minQueryLength">4</int>
|
||||
<float name="maxQueryFrequency">0.01</float>
|
||||
</lst>
|
||||
|
||||
</searchComponent>
|
||||
|
||||
<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="spellcheck.dictionary">default</str>
|
||||
<str name="spellcheck">on</str>
|
||||
<str name="spellcheck.extendedResults">true</str>
|
||||
<str name="spellcheck.count">10</str>
|
||||
<str name="spellcheck.alternativeTermCount">5</str>
|
||||
<str name="spellcheck.maxResultsForSuggest">5</str>
|
||||
<str name="spellcheck.collate">true</str>
|
||||
<str name="spellcheck.collateExtendedResults">true</str>
|
||||
<str name="spellcheck.maxCollationTries">10</str>
|
||||
<str name="spellcheck.maxCollations">5</str>
|
||||
</lst>
|
||||
|
||||
<arr name="last-components">
|
||||
<str>spellcheck</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="tvComponent" class="solr.TermVectorComponent" />
|
||||
|
||||
<requestHandler name="/tvrh" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<bool name="tv">true</bool>
|
||||
</lst>
|
||||
<arr name="last-components">
|
||||
<str>tvComponent</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="terms" class="solr.TermsComponent" />
|
||||
|
||||
<requestHandler name="/terms" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<bool name="terms">true</bool>
|
||||
<bool name="distrib">false</bool>
|
||||
</lst>
|
||||
|
||||
<arr name="components">
|
||||
<str>terms</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="elevator" class="solr.QueryElevationComponent">
|
||||
|
||||
<str name="queryFieldType">string</str>
|
||||
<str name="config-file">elevate.xml</str>
|
||||
|
||||
</searchComponent>
|
||||
|
||||
<requestHandler name="/elevate" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
</lst>
|
||||
<arr name="last-components">
|
||||
<str>elevator</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent class="solr.HighlightComponent" name="highlight">
|
||||
|
||||
<highlighting>
|
||||
|
||||
<fragmenter name="gap" default="true" class="solr.highlight.GapFragmenter">
|
||||
<lst name="defaults">
|
||||
<int name="hl.fragsize">100</int>
|
||||
</lst>
|
||||
</fragmenter>
|
||||
|
||||
<fragmenter name="regex" class="solr.highlight.RegexFragmenter">
|
||||
<lst name="defaults">
|
||||
<int name="hl.fragsize">70</int>
|
||||
<float name="hl.regex.slop">0.5</float>
|
||||
<str name="hl.regex.pattern">[-\w ,/\n\"']{20,200}</str>
|
||||
</lst>
|
||||
</fragmenter>
|
||||
|
||||
<formatter name="html" default="true" class="solr.highlight.HtmlFormatter">
|
||||
<lst name="defaults">
|
||||
<str name="hl.simple.pre"><![CDATA[<em>]]></str>
|
||||
<str name="hl.simple.post"><![CDATA[</em>]]></str>
|
||||
</lst>
|
||||
</formatter>
|
||||
|
||||
<encoder name="html" class="solr.highlight.HtmlEncoder" />
|
||||
<fragListBuilder name="simple" class="solr.highlight.SimpleFragListBuilder" />
|
||||
<fragListBuilder name="single" class="solr.highlight.SingleFragListBuilder" />
|
||||
<fragListBuilder name="weighted" default="true" class="solr.highlight.WeightedFragListBuilder" />
|
||||
<fragmentsBuilder name="default" default="true" class="solr.highlight.ScoreOrderFragmentsBuilder" />
|
||||
<fragmentsBuilder name="colored" class="solr.highlight.ScoreOrderFragmentsBuilder">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="hl.tag.pre"><![CDATA[<b style="background:yellow">,<b style="background:lawgreen">,
|
||||
<b style="background:aquamarine">,<b style="background:magenta">,
|
||||
<b style="background:palegreen">,<b style="background:coral">,
|
||||
<b style="background:wheat">,<b style="background:khaki">,
|
||||
<b style="background:lime">,<b style="background:deepskyblue">]]></str>
|
||||
<str name="hl.tag.post"><![CDATA[</b>]]></str>
|
||||
</lst>
|
||||
|
||||
</fragmentsBuilder>
|
||||
|
||||
<boundaryScanner name="default" default="true" class="solr.highlight.SimpleBoundaryScanner">
|
||||
<lst name="defaults">
|
||||
<str name="hl.bs.maxScan">10</str>
|
||||
<str name="hl.bs.chars">.,!?</str>
|
||||
</lst>
|
||||
</boundaryScanner>
|
||||
|
||||
<boundaryScanner name="breakIterator" class="solr.highlight.BreakIteratorBoundaryScanner">
|
||||
<lst name="defaults">
|
||||
<str name="hl.bs.type">WORD</str>
|
||||
<str name="hl.bs.language">en</str>
|
||||
<str name="hl.bs.country">US</str>
|
||||
</lst>
|
||||
</boundaryScanner>
|
||||
|
||||
</highlighting>
|
||||
|
||||
</searchComponent>
|
||||
|
||||
<schemaFactory class="ClassicIndexSchemaFactory" />
|
||||
|
||||
<updateRequestProcessorChain name="add-unknown-fields-to-the-schema">
|
||||
<processor class="solr.UUIDUpdateProcessorFactory" />
|
||||
<processor class="solr.LogUpdateProcessorFactory" />
|
||||
<processor class="solr.DistributedUpdateProcessorFactory" />
|
||||
<processor class="solr.RemoveBlankFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.FieldNameMutatingUpdateProcessorFactory">
|
||||
<str name="pattern">[^\w-\.]</str>
|
||||
<str name="replacement">_</str>
|
||||
</processor>
|
||||
<processor class="solr.ParseBooleanFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.ParseLongFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.ParseDoubleFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.ParseDateFieldUpdateProcessorFactory">
|
||||
<arr name="format">
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss.SSSZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss,SSSZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss.SSS</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss,SSS</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ssZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss</str>
|
||||
<str>yyyy-MM-dd'T'HH:mmZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss.SSSZ</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss,SSSZ</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss.SSS</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss,SSS</str>
|
||||
<str>yyyy-MM-dd HH:mm:ssZ</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss</str>
|
||||
<str>yyyy-MM-dd HH:mmZ</str>
|
||||
<str>yyyy-MM-dd HH:mm</str>
|
||||
<str>yyyy-MM-dd</str>
|
||||
</arr>
|
||||
</processor>
|
||||
<processor class="solr.RunUpdateProcessorFactory" />
|
||||
</updateRequestProcessorChain>
|
||||
|
||||
<queryResponseWriter name="json" class="solr.JSONResponseWriter">
|
||||
<str name="content-type">text/plain; charset=UTF-8</str>
|
||||
</queryResponseWriter>
|
||||
|
||||
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
|
||||
<str name="template.base.dir">${velocity.template.base.dir:}</str>
|
||||
<str name="solr.resource.loader.enabled">${velocity.solr.resource.loader.enabled:true}</str>
|
||||
<str name="params.resource.loader.enabled">${velocity.params.resource.loader.enabled:false}</str>
|
||||
</queryResponseWriter>
|
||||
|
||||
<queryResponseWriter name="xslt" class="solr.XSLTResponseWriter">
|
||||
<int name="xsltCacheLifetimeSeconds">5</int>
|
||||
</queryResponseWriter>
|
||||
|
||||
</config>
|
|
@ -1,345 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--solrconfig.xml documentation [https://wiki.apache.org/solr/SolrConfigXml]-->
|
||||
<config>
|
||||
|
||||
<luceneMatchVersion>6.0.0</luceneMatchVersion>
|
||||
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/extraction/lib" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-cell-\d.*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/clustering/lib/" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-clustering-\d.*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-\d.*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib" regex=".*\.jar" />
|
||||
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
|
||||
|
||||
<dataDir>${solr.data.dir:}</dataDir>
|
||||
|
||||
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}" />
|
||||
|
||||
<codecFactory class="solr.SchemaCodecFactory" />
|
||||
|
||||
<indexConfig>
|
||||
<lockType>${solr.lock.type:native}</lockType>
|
||||
</indexConfig>
|
||||
|
||||
<jmx />
|
||||
|
||||
<updateHandler class="solr.DirectUpdateHandler2">
|
||||
|
||||
<updateLog>
|
||||
<str name="dir">${solr.ulog.dir:}</str>
|
||||
<int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
|
||||
</updateLog>
|
||||
|
||||
<autoCommit>
|
||||
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
|
||||
<openSearcher>false</openSearcher>
|
||||
</autoCommit>
|
||||
|
||||
<autoSoftCommit>
|
||||
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
|
||||
</autoSoftCommit>
|
||||
|
||||
</updateHandler>
|
||||
|
||||
<query>
|
||||
|
||||
<maxBooleanClauses>1024</maxBooleanClauses>
|
||||
<filterCache class="solr.FastLRUCache" size="512" initialSize="512" autowarmCount="0" />
|
||||
<queryResultCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0" />
|
||||
<documentCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0" />
|
||||
<cache name="perSegFilter" class="solr.search.LRUCache" size="10" initialSize="0" autowarmCount="10" regenerator="solr.NoOpRegenerator" />
|
||||
<enableLazyFieldLoading>true</enableLazyFieldLoading>
|
||||
<queryResultWindowSize>20</queryResultWindowSize>
|
||||
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
|
||||
|
||||
<listener event="newSearcher" class="solr.QuerySenderListener">
|
||||
<arr name="queries" />
|
||||
</listener>
|
||||
|
||||
<listener event="firstSearcher" class="solr.QuerySenderListener">
|
||||
<arr name="queries" />
|
||||
</listener>
|
||||
|
||||
<useColdSearcher>false</useColdSearcher>
|
||||
<maxWarmingSearchers>2</maxWarmingSearchers>
|
||||
|
||||
</query>
|
||||
|
||||
<requestDispatcher handleSelect="false">
|
||||
|
||||
<requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048000" formdataUploadLimitInKB="2048" addHttpRequestToContext="false" />
|
||||
<httpCaching never304="true" />
|
||||
|
||||
</requestDispatcher>
|
||||
|
||||
<requestHandler name="/select" class="solr.SearchHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<int name="rows">10</int>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<requestHandler name="/query" class="solr.SearchHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<str name="wt">json</str>
|
||||
<str name="indent">true</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell,/browse">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="df">_text_</str>
|
||||
</lst>
|
||||
|
||||
</initParams>
|
||||
|
||||
<initParams path="/update/**">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="update.chain">add-unknown-fields-to-the-schema</str>
|
||||
</lst>
|
||||
|
||||
</initParams>
|
||||
|
||||
<requestHandler name="/update/extract" startup="lazy" class="solr.extraction.ExtractingRequestHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="lowernames">true</str>
|
||||
<str name="fmap.meta">ignored_</str>
|
||||
<str name="fmap.content">_text_</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<requestHandler name="/analysis/field" startup="lazy" class="solr.FieldAnalysisRequestHandler" />
|
||||
<requestHandler name="/analysis/document" class="solr.DocumentAnalysisRequestHandler" startup="lazy" />
|
||||
|
||||
<requestHandler name="/debug/dump" class="solr.DumpRequestHandler">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<str name="echoHandler">true</str>
|
||||
</lst>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
|
||||
|
||||
<str name="queryAnalyzerFieldType">text_general</str>
|
||||
|
||||
<lst name="spellchecker">
|
||||
<str name="name">default</str>
|
||||
<str name="field">_text_</str>
|
||||
<str name="classname">solr.DirectSolrSpellChecker</str>
|
||||
<str name="distanceMeasure">internal</str>
|
||||
<float name="accuracy">0.5</float>
|
||||
<int name="maxEdits">2</int>
|
||||
<int name="minPrefix">1</int>
|
||||
<int name="maxInspections">5</int>
|
||||
<int name="minQueryLength">4</int>
|
||||
<float name="maxQueryFrequency">0.01</float>
|
||||
</lst>
|
||||
|
||||
</searchComponent>
|
||||
|
||||
<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="spellcheck.dictionary">default</str>
|
||||
<str name="spellcheck">on</str>
|
||||
<str name="spellcheck.extendedResults">true</str>
|
||||
<str name="spellcheck.count">10</str>
|
||||
<str name="spellcheck.alternativeTermCount">5</str>
|
||||
<str name="spellcheck.maxResultsForSuggest">5</str>
|
||||
<str name="spellcheck.collate">true</str>
|
||||
<str name="spellcheck.collateExtendedResults">true</str>
|
||||
<str name="spellcheck.maxCollationTries">10</str>
|
||||
<str name="spellcheck.maxCollations">5</str>
|
||||
</lst>
|
||||
|
||||
<arr name="last-components">
|
||||
<str>spellcheck</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="tvComponent" class="solr.TermVectorComponent" />
|
||||
|
||||
<requestHandler name="/tvrh" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<bool name="tv">true</bool>
|
||||
</lst>
|
||||
<arr name="last-components">
|
||||
<str>tvComponent</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="terms" class="solr.TermsComponent" />
|
||||
|
||||
<requestHandler name="/terms" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<bool name="terms">true</bool>
|
||||
<bool name="distrib">false</bool>
|
||||
</lst>
|
||||
|
||||
<arr name="components">
|
||||
<str>terms</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent name="elevator" class="solr.QueryElevationComponent">
|
||||
|
||||
<str name="queryFieldType">string</str>
|
||||
<str name="config-file">elevate.xml</str>
|
||||
|
||||
</searchComponent>
|
||||
|
||||
<requestHandler name="/elevate" class="solr.SearchHandler" startup="lazy">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
</lst>
|
||||
<arr name="last-components">
|
||||
<str>elevator</str>
|
||||
</arr>
|
||||
|
||||
</requestHandler>
|
||||
|
||||
<searchComponent class="solr.HighlightComponent" name="highlight">
|
||||
|
||||
<highlighting>
|
||||
|
||||
<fragmenter name="gap" default="true" class="solr.highlight.GapFragmenter">
|
||||
<lst name="defaults">
|
||||
<int name="hl.fragsize">100</int>
|
||||
</lst>
|
||||
</fragmenter>
|
||||
|
||||
<fragmenter name="regex" class="solr.highlight.RegexFragmenter">
|
||||
<lst name="defaults">
|
||||
<int name="hl.fragsize">70</int>
|
||||
<float name="hl.regex.slop">0.5</float>
|
||||
<str name="hl.regex.pattern">[-\w ,/\n\"']{20,200}</str>
|
||||
</lst>
|
||||
</fragmenter>
|
||||
|
||||
<formatter name="html" default="true" class="solr.highlight.HtmlFormatter">
|
||||
<lst name="defaults">
|
||||
<str name="hl.simple.pre"><![CDATA[<em>]]></str>
|
||||
<str name="hl.simple.post"><![CDATA[</em>]]></str>
|
||||
</lst>
|
||||
</formatter>
|
||||
|
||||
<encoder name="html" class="solr.highlight.HtmlEncoder" />
|
||||
<fragListBuilder name="simple" class="solr.highlight.SimpleFragListBuilder" />
|
||||
<fragListBuilder name="single" class="solr.highlight.SingleFragListBuilder" />
|
||||
<fragListBuilder name="weighted" default="true" class="solr.highlight.WeightedFragListBuilder" />
|
||||
<fragmentsBuilder name="default" default="true" class="solr.highlight.ScoreOrderFragmentsBuilder" />
|
||||
<fragmentsBuilder name="colored" class="solr.highlight.ScoreOrderFragmentsBuilder">
|
||||
|
||||
<lst name="defaults">
|
||||
<str name="hl.tag.pre"><![CDATA[<b style="background:yellow">,<b style="background:lawgreen">,
|
||||
<b style="background:aquamarine">,<b style="background:magenta">,
|
||||
<b style="background:palegreen">,<b style="background:coral">,
|
||||
<b style="background:wheat">,<b style="background:khaki">,
|
||||
<b style="background:lime">,<b style="background:deepskyblue">]]></str>
|
||||
<str name="hl.tag.post"><![CDATA[</b>]]></str>
|
||||
</lst>
|
||||
|
||||
</fragmentsBuilder>
|
||||
|
||||
<boundaryScanner name="default" default="true" class="solr.highlight.SimpleBoundaryScanner">
|
||||
<lst name="defaults">
|
||||
<str name="hl.bs.maxScan">10</str>
|
||||
<str name="hl.bs.chars">.,!?</str>
|
||||
</lst>
|
||||
</boundaryScanner>
|
||||
|
||||
<boundaryScanner name="breakIterator" class="solr.highlight.BreakIteratorBoundaryScanner">
|
||||
<lst name="defaults">
|
||||
<str name="hl.bs.type">WORD</str>
|
||||
<str name="hl.bs.language">en</str>
|
||||
<str name="hl.bs.country">US</str>
|
||||
</lst>
|
||||
</boundaryScanner>
|
||||
|
||||
</highlighting>
|
||||
|
||||
</searchComponent>
|
||||
|
||||
<schemaFactory class="ManagedIndexSchemaFactory">
|
||||
<bool name="mutable">true</bool>
|
||||
</schemaFactory>
|
||||
|
||||
<updateRequestProcessorChain name="add-unknown-fields-to-the-schema">
|
||||
<processor class="solr.UUIDUpdateProcessorFactory" />
|
||||
<processor class="solr.LogUpdateProcessorFactory" />
|
||||
<processor class="solr.DistributedUpdateProcessorFactory" />
|
||||
<processor class="solr.RemoveBlankFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.FieldNameMutatingUpdateProcessorFactory">
|
||||
<str name="pattern">[^\w-\.]</str>
|
||||
<str name="replacement">_</str>
|
||||
</processor>
|
||||
<processor class="solr.ParseBooleanFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.ParseLongFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.ParseDoubleFieldUpdateProcessorFactory" />
|
||||
<processor class="solr.ParseDateFieldUpdateProcessorFactory">
|
||||
<arr name="format">
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss.SSSZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss,SSSZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss.SSS</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss,SSS</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ssZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm:ss</str>
|
||||
<str>yyyy-MM-dd'T'HH:mmZ</str>
|
||||
<str>yyyy-MM-dd'T'HH:mm</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss.SSSZ</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss,SSSZ</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss.SSS</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss,SSS</str>
|
||||
<str>yyyy-MM-dd HH:mm:ssZ</str>
|
||||
<str>yyyy-MM-dd HH:mm:ss</str>
|
||||
<str>yyyy-MM-dd HH:mmZ</str>
|
||||
<str>yyyy-MM-dd HH:mm</str>
|
||||
<str>yyyy-MM-dd</str>
|
||||
</arr>
|
||||
</processor>
|
||||
<processor class="solr.RunUpdateProcessorFactory" />
|
||||
</updateRequestProcessorChain>
|
||||
|
||||
<queryResponseWriter name="json" class="solr.JSONResponseWriter">
|
||||
<str name="content-type">text/plain; charset=UTF-8</str>
|
||||
</queryResponseWriter>
|
||||
|
||||
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy">
|
||||
<str name="template.base.dir">${velocity.template.base.dir:}</str>
|
||||
<str name="solr.resource.loader.enabled">${velocity.solr.resource.loader.enabled:true}</str>
|
||||
<str name="params.resource.loader.enabled">${velocity.params.resource.loader.enabled:false}</str>
|
||||
</queryResponseWriter>
|
||||
|
||||
<queryResponseWriter name="xslt" class="solr.XSLTResponseWriter">
|
||||
<int name="xsltCacheLifetimeSeconds">5</int>
|
||||
</queryResponseWriter>
|
||||
|
||||
</config>
|
|
@ -1,203 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!--
|
||||
NB Please copy changes to this file into the multilingual schema:
|
||||
ckanext/multilingual/solr/schema.xml
|
||||
-->
|
||||
|
||||
<!-- We update the version when there is a backward-incompatible change to this
|
||||
schema. We used to use the `version` attribute for this but this is an internal
|
||||
attribute that should not be used so starting from CKAN 2.10 we use the `name`
|
||||
attribute with the form `ckan-X.Y` -->
|
||||
<schema name="ckan-2.10" version="1.6">
|
||||
|
||||
<types>
|
||||
<fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldtype name="binary" class="solr.BinaryField"/>
|
||||
<fieldType name="int" class="solr.IntPointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="float" class="solr.FloatPointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="long" class="solr.LongPointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="double" class="solr.DoublePointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="pint" class="solr.IntPointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="pfloat" class="solr.FloatPointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="plong" class="solr.LongPointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="pdouble" class="solr.DoublePointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="date" class="solr.DatePointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="pdate" class="solr.DatePointField" omitNorms="true" positionIncrementGap="0"/>
|
||||
|
||||
<fieldType name="pdates" class="solr.DatePointField" positionIncrementGap="0" multiValued="true"/>
|
||||
<fieldType name="booleans" class="solr.BoolField" sortMissingLast="true" multiValued="true"/>
|
||||
<fieldType name="pints" class="solr.IntPointField" positionIncrementGap="0" multiValued="true"/>
|
||||
<fieldType name="pfloats" class="solr.FloatPointField" positionIncrementGap="0" multiValued="true"/>
|
||||
<fieldType name="plongs" class="solr.LongPointField" positionIncrementGap="0" multiValued="true"/>
|
||||
<fieldType name="pdoubles" class="solr.DoublePointField" positionIncrementGap="0" multiValued="true"/>
|
||||
|
||||
<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
|
||||
<filter class="solr.ASCIIFoldingFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
|
||||
<filter class="solr.ASCIIFoldingFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
|
||||
<!-- A general unstemmed text field - good if one does not know the language of the field -->
|
||||
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
<fieldType name="text_ngram" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.NGramTokenizerFactory" minGramSize="2" maxGramSize="10"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
</types>
|
||||
|
||||
|
||||
<fields>
|
||||
<field name="index_id" type="string" indexed="true" stored="true" required="true" />
|
||||
<field name="id" type="string" indexed="true" stored="true" required="true" />
|
||||
<field name="site_id" type="string" indexed="true" stored="true" required="true" />
|
||||
<field name="title" type="text" indexed="true" stored="true" />
|
||||
<field name="title_ngram" type="text_ngram" indexed="true" stored="true" />
|
||||
<field name="entity_type" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="dataset_type" type="string" indexed="true" stored="true" />
|
||||
<field name="state" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="name" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="name_ngram" type="text_ngram" indexed="true" stored="true" />
|
||||
<field name="revision_id" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="version" type="string" indexed="true" stored="true" />
|
||||
<field name="url" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="ckan_url" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="download_url" type="string" indexed="true" stored="true" omitNorms="true" />
|
||||
<field name="notes" type="text" indexed="true" stored="true"/>
|
||||
<field name="author" type="text_general" indexed="true" stored="true" />
|
||||
<field name="author_email" type="text_general" indexed="true" stored="true" />
|
||||
<field name="maintainer" type="text_general" indexed="true" stored="true" />
|
||||
<field name="maintainer_email" type="text_general" indexed="true" stored="true" />
|
||||
<field name="license" type="string" indexed="true" stored="true" />
|
||||
<field name="license_id" type="string" indexed="true" stored="true" />
|
||||
<field name="tags" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="groups" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="organization" type="string" indexed="true" stored="true" multiValued="false"/>
|
||||
|
||||
<field name="capacity" type="string" indexed="true" stored="true" multiValued="false"/>
|
||||
<field name="permission_labels" type="string" indexed="true" stored="false" multiValued="true"/>
|
||||
|
||||
<field name="res_name" type="text_general" indexed="true" stored="true" multiValued="true" />
|
||||
<field name="res_description" type="text_general" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="res_format" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="res_url" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="res_type" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
|
||||
<!-- catchall field, containing all other searchable text fields (implemented
|
||||
via copyField further on in this schema -->
|
||||
<field name="text" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="urls" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
|
||||
<field name="depends_on" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="dependency_of" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="derives_from" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="has_derivation" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="links_to" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="linked_from" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="child_of" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="parent_of" type="text" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="views_total" type="int" indexed="true" stored="false"/>
|
||||
<field name="views_recent" type="int" indexed="true" stored="false"/>
|
||||
<field name="resources_accessed_total" type="int" indexed="true" stored="false"/>
|
||||
<field name="resources_accessed_recent" type="int" indexed="true" stored="false"/>
|
||||
|
||||
<field name="metadata_created" type="date" indexed="true" stored="true" multiValued="false"/>
|
||||
<field name="metadata_modified" type="date" indexed="true" stored="true" multiValued="false"/>
|
||||
|
||||
<field name="indexed_ts" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
|
||||
|
||||
<!-- Copy the title field into titleString, and treat as a string
|
||||
(rather than text type). This allows us to sort on the titleString -->
|
||||
<field name="title_string" type="string" indexed="true" stored="false" />
|
||||
|
||||
<field name="data_dict" type="string" indexed="false" stored="true" />
|
||||
<field name="validated_data_dict" type="string" indexed="false" stored="true" />
|
||||
|
||||
<field name="_version_" type="string" indexed="true" stored="true"/>
|
||||
|
||||
<dynamicField name="*_date" type="date" indexed="true" stored="true" multiValued="false"/>
|
||||
|
||||
<dynamicField name="extras_*" type="text" indexed="true" stored="true" multiValued="false"/>
|
||||
<dynamicField name="res_extras_*" type="text" indexed="true" stored="true" multiValued="true"/>
|
||||
<dynamicField name="vocab_*" type="string" indexed="true" stored="true" multiValued="true"/>
|
||||
<dynamicField name="*" type="string" indexed="true" stored="false"/>
|
||||
</fields>
|
||||
|
||||
<uniqueKey>index_id</uniqueKey>
|
||||
|
||||
<copyField source="url" dest="urls"/>
|
||||
<copyField source="title" dest="title_ngram"/>
|
||||
<copyField source="name" dest="name_ngram"/>
|
||||
<copyField source="ckan_url" dest="urls"/>
|
||||
<copyField source="download_url" dest="urls"/>
|
||||
<copyField source="res_url" dest="urls"/>
|
||||
<copyField source="extras_*" dest="text"/>
|
||||
<copyField source="res_extras_*" dest="text"/>
|
||||
<copyField source="vocab_*" dest="text"/>
|
||||
<copyField source="urls" dest="text"/>
|
||||
<copyField source="name" dest="text"/>
|
||||
<copyField source="title" dest="text"/>
|
||||
<copyField source="text" dest="text"/>
|
||||
<copyField source="license" dest="text"/>
|
||||
<copyField source="notes" dest="text"/>
|
||||
<copyField source="tags" dest="text"/>
|
||||
<copyField source="groups" dest="text"/>
|
||||
<copyField source="organization" dest="text"/>
|
||||
<copyField source="res_name" dest="text"/>
|
||||
<copyField source="res_description" dest="text"/>
|
||||
<copyField source="maintainer" dest="text"/>
|
||||
<copyField source="author" dest="text"/>
|
||||
|
||||
</schema>
|
|
@ -1,40 +0,0 @@
|
|||
# Runtime configuration of CKAN enabled through ckanext-envvars
|
||||
# Information about how it works: https://github.com/okfn/ckanext-envvars
|
||||
# Note that variables here take presedence over build/up time variables in .env
|
||||
|
||||
# Set to true to disable CKAN from starting and serve a maintenance page
|
||||
MAINTENANCE_MODE=false
|
||||
|
||||
# General Settings
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
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 Plugins
|
||||
CKAN__PLUGINS=envvars image_view text_view recline_view datastore datapusher
|
||||
# CKAN requires storage path to be set in order for filestore to be enabled
|
||||
CKAN__STORAGE_PATH=/srv/app/data
|
||||
CKAN__WEBASSETS__PATH=/srv/app/data/webassets
|
||||
# SYSADMIN settings, a sysadmin user is created automatically with the below credentials
|
||||
CKAN_SYSADMIN_NAME=sysadmin
|
||||
CKAN_SYSADMIN_PASSWORD=password
|
||||
CKAN_SYSADMIN_EMAIL=sysadmin@ckantest.com
|
||||
|
||||
# Email settings
|
||||
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
|
||||
|
||||
# Datapusher configuration
|
||||
CKAN__DATAPUSHER__URL=http://datapusher:8000
|
||||
CKAN__DATAPUSHER__CALLBACK_URL_BASE=http://ckan:5000/
|
||||
|
||||
# Solr configuration
|
||||
CKAN_VERSION=2.9.11
|
||||
CKAN_CORE_NAME=ckan
|
|
@ -1,35 +0,0 @@
|
|||
# Variables in this file will be used as build arguments when running
|
||||
# docker-compose build and docker-compose up
|
||||
# Verify correct substitution with "docker-compose config"
|
||||
# If variables are newly added or enabled, please delete and rebuild the images to pull in changes:
|
||||
# docker-compose down -v
|
||||
# docker-compose build
|
||||
# docker-compose up -d
|
||||
|
||||
# Database
|
||||
POSTGRES_PASSWORD=ckan
|
||||
POSTGRES_PORT=5432
|
||||
DATASTORE_READONLY_PASSWORD=datastore
|
||||
|
||||
# CKAN
|
||||
CKAN_VERSION=2.9.11
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
|
||||
# Datapusher
|
||||
DATAPUSHER_VERSION=0.0.17
|
||||
DATAPUSHER_MAX_CONTENT_LENGTH=10485760
|
||||
DATAPUSHER_CHUNK_SIZE=16384
|
||||
DATAPUSHER_CHUNK_INSERT_ROWS=250
|
||||
DATAPUSHER_DOWNLOAD_TIMEOUT=30
|
||||
DATAPUSHER_SSL_VERIFY=False
|
||||
DATAPUSHER_REWRITE_RESOURCES=True
|
||||
DATAPUSHER_REWRITE_URL=http://ckan:5000
|
||||
|
||||
# SOLR
|
||||
CKAN_CORE_NAME=ckan
|
||||
|
||||
# Redis
|
||||
REDIS_VERSION=6.0.7
|
|
@ -1,95 +0,0 @@
|
|||
# docker-compose build && docker-compose up -d
|
||||
version: "3"
|
||||
|
||||
volumes:
|
||||
ckan_data:
|
||||
pg_data:
|
||||
solr_data:
|
||||
|
||||
services:
|
||||
ckan:
|
||||
container_name: ckan
|
||||
image: ghcr.io/keitaroinc/ckan:${CKAN_VERSION}
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- solr
|
||||
ports:
|
||||
- "0.0.0.0:${CKAN_PORT}:5000"
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
volumes:
|
||||
- ckan_data:/srv/app/data
|
||||
|
||||
datapusher:
|
||||
container_name: datapusher
|
||||
image: ghcr.io/keitaroinc/datapusher:${DATAPUSHER_VERSION}
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- DATAPUSHER_MAX_CONTENT_LENGTH=${DATAPUSHER_MAX_CONTENT_LENGTH}
|
||||
- DATAPUSHER_CHUNK_SIZE=${DATAPUSHER_CHUNK_SIZE}
|
||||
- DATAPUSHER_CHUNK_INSERT_ROWS=${DATAPUSHER_CHUNK_INSERT_ROWS}
|
||||
- DATAPUSHER_DOWNLOAD_TIMEOUT=${DATAPUSHER_DOWNLOAD_TIMEOUT}
|
||||
- DATAPUSHER_SSL_VERIFY=${DATA_PUSHER_SSL_VERIFY}
|
||||
- DATAPUSHER_REWRITE_RESOURCES=${DATAPUSHER_REWRITE_RESOURCES}
|
||||
- DATAPUSHER_REWRITE_URL=${DATAPUSHER_REWRITE_URL}
|
||||
|
||||
|
||||
db:
|
||||
container_name: db
|
||||
build:
|
||||
context: .
|
||||
dockerfile: postgresql/Dockerfile
|
||||
args:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
networks:
|
||||
- backend
|
||||
environment:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- PGDATA=/var/lib/postgresql/data/db
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "ckan"]
|
||||
|
||||
solr:
|
||||
container_name: solr
|
||||
image: solr:8.11.1
|
||||
networks:
|
||||
- backend
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_CORE_NAME=${CKAN_CORE_NAME}
|
||||
- CKAN_VERSION=${CKAN_VERSION}
|
||||
volumes:
|
||||
- solr_data:/var/solr
|
||||
- ${PWD}/solr8/ckan_init_solr.sh:/docker-entrypoint-initdb.d/ckan_init_solr.sh
|
||||
|
||||
redis:
|
||||
container_name: redis
|
||||
image: redis:${REDIS_VERSION}
|
||||
networks:
|
||||
- backend
|
||||
|
||||
networks:
|
||||
frontend:
|
||||
backend:
|
|
@ -1,13 +0,0 @@
|
|||
FROM postgis/postgis:14-3.2-alpine
|
||||
|
||||
# Allow connections; we don't map out any ports so only linked docker containers can connect
|
||||
RUN echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf
|
||||
|
||||
# Customize default user/pass/db
|
||||
ENV POSTGRES_DB ckan
|
||||
ENV POSTGRES_USER ckan
|
||||
ARG POSTGRES_PASSWORD
|
||||
ARG DS_RO_PASS
|
||||
|
||||
# Include datastore setup scripts
|
||||
COPY ./postgresql/docker-entrypoint-initdb.d /docker-entrypoint-initdb.d
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||
CREATE ROLE datastore_ro NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN PASSWORD '$DS_RO_PASS';
|
||||
CREATE DATABASE datastore OWNER ckan ENCODING 'utf-8';
|
||||
GRANT ALL PRIVILEGES ON DATABASE datastore TO ckan;
|
||||
EOSQL
|
|
@ -1,2 +0,0 @@
|
|||
ALTER VIEW geometry_columns OWNER TO ckan;
|
||||
ALTER TABLE spatial_ref_sys OWNER TO ckan;
|
|
@ -1,38 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Initialize SOLR for CKAN by creating a ckan core
|
||||
# Arguments are supplied via environment variables: CKAN_CORE_NAME CKAN_VERSION
|
||||
# Example:
|
||||
# CKAN_CORE_NAME=ckan
|
||||
# CKAN_VERSION=2.9.11
|
||||
|
||||
set -e
|
||||
|
||||
CKAN_SOLR_SCHEMA_URL=https://raw.githubusercontent.com/ckan/ckan/ckan-$CKAN_VERSION/ckan/config/solr/schema.solr8.xml
|
||||
|
||||
echo "Check whether managed schema exists for CKAN $CKAN_VERSION"
|
||||
if ! curl --output /dev/null --silent --head --fail "$CKAN_SOLR_SCHEMA_URL"; then
|
||||
echo "Can't find CKAN SOLR schema at URL: $CKAN_SOLR_SCHEMA_URL. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Check whether SOLR is initialized for CKAN"
|
||||
CORESDIR=/var/solr/data
|
||||
|
||||
COREDIR="$CORESDIR/$CKAN_CORE_NAME"
|
||||
if [ -d "$COREDIR" ]; then
|
||||
echo "SOLR already initialized, skipping initialization"
|
||||
else
|
||||
echo "Initializing SOLR core $CKAN_CORE_NAME for CKAN $CKAN_VERSION"
|
||||
# init script for handling an empty /var/solr
|
||||
/opt/docker-solr/scripts/init-var-solr
|
||||
|
||||
# Precreate CKAN core
|
||||
/opt/docker-solr/scripts/precreate-core $CKAN_CORE_NAME
|
||||
|
||||
# Replace the managed schema with CKANs schema
|
||||
echo "Adding CKAN managed schema"
|
||||
curl $CKAN_SOLR_SCHEMA_URL -o /var/solr/data/$CKAN_CORE_NAME/conf/managed-schema -s
|
||||
|
||||
echo "SOLR initialized"
|
||||
fi
|
|
@ -1,37 +0,0 @@
|
|||
# Runtime configuration of CKAN enabled through ckanext-envvars
|
||||
# Information about how it works: https://github.com/okfn/ckanext-envvars
|
||||
# Note that variables here take presedence over build/up time variables in .env
|
||||
|
||||
# General Settings
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
# CKAN Plugins
|
||||
CKAN__PLUGINS=envvars image_view text_view recline_view datastore datapusher harvest ckan_harvester
|
||||
# CKAN requires storage path to be set in order for filestore to be enabled
|
||||
CKAN__STORAGE_PATH=/srv/app/data
|
||||
CKAN__WEBASSETS__PATH=/srv/app/data/webassets
|
||||
# SYSADMIN settings, a sysadmin user is created automatically with the below credentials
|
||||
CKAN_SYSADMIN_NAME=sysadmin
|
||||
CKAN_SYSADMIN_PASSWORD=password
|
||||
CKAN_SYSADMIN_EMAIL=sysadmin@ckantest.com
|
||||
|
||||
# Email settings
|
||||
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
|
||||
|
||||
# Datapusher configuration
|
||||
CKAN__DATAPUSHER__URL=http://datapusher:8000
|
||||
CKAN__DATAPUSHER__CALLBACK_URL_BASE=http://ckan:5000/
|
||||
|
||||
# Harvest settings
|
||||
CKAN__HARVEST__MQ__TYPE=redis
|
||||
CKAN__HARVEST__MQ__HOSTNAME=redis
|
||||
|
||||
# Solr configuration
|
||||
CKAN_VERSION=2.9.11
|
||||
CKAN_CORE_NAME=ckan
|
|
@ -1,35 +0,0 @@
|
|||
# Variables in this file will be used as build arguments when running
|
||||
# docker-compose build and docker-compose up
|
||||
# Verify correct substitution with "docker-compose config"
|
||||
# If variables are newly added or enabled, please delete and rebuild the images to pull in changes:
|
||||
# docker-compose down -v
|
||||
# docker-compose build
|
||||
# docker-compose up -d
|
||||
|
||||
# Database
|
||||
POSTGRES_PASSWORD=ckan
|
||||
POSTGRES_PORT=5432
|
||||
DATASTORE_READONLY_PASSWORD=datastore
|
||||
|
||||
# CKAN
|
||||
CKAN_VERSION=2.9.11
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
|
||||
# Datapusher
|
||||
DATAPUSHER_VERSION=0.0.17
|
||||
DATAPUSHER_MAX_CONTENT_LENGTH=10485760
|
||||
DATAPUSHER_CHUNK_SIZE=16384
|
||||
DATAPUSHER_CHUNK_INSERT_ROWS=250
|
||||
DATAPUSHER_DOWNLOAD_TIMEOUT=30
|
||||
DATAPUSHER_SSL_VERIFY=False
|
||||
DATAPUSHER_REWRITE_RESOURCES=True
|
||||
DATAPUSHER_REWRITE_URL=http://ckan:5000
|
||||
|
||||
# SOLR
|
||||
CKAN_CORE_NAME=ckan
|
||||
|
||||
# Redis
|
||||
REDIS_VERSION=6.0.7
|
|
@ -1,58 +0,0 @@
|
|||
###################
|
||||
### Extensions ####
|
||||
###################
|
||||
FROM ghcr.io/keitaroinc/ckan:2.9.11 as extbuild
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV HARVEST_GIT_URL=https://github.com/ckan/ckanext-harvest
|
||||
ENV HARVEST_GIT_BRANCH=v1.3.4
|
||||
|
||||
# Switch to the root user
|
||||
USER root
|
||||
|
||||
# Install necessary packages to build extensions
|
||||
RUN apk add --no-cache \
|
||||
python3-dev \
|
||||
gcc \
|
||||
g++ \
|
||||
libffi-dev \
|
||||
openssl-dev \
|
||||
rust \
|
||||
cargo
|
||||
|
||||
# Fetch and build the custom CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${HARVEST_GIT_URL}@${HARVEST_GIT_BRANCH}#egg=ckanext-harvest
|
||||
RUN pip wheel --wheel-dir=/wheels -r https://raw.githubusercontent.com/ckan/ckanext-harvest/${HARVEST_GIT_BRANCH}/pip-requirements.txt
|
||||
RUN curl -o /wheels/harvest.txt https://raw.githubusercontent.com/ckan/ckanext-harvest/${HARVEST_GIT_BRANCH}/pip-requirements.txt
|
||||
|
||||
USER ckan
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM ghcr.io/keitaroinc/ckan:2.9.11
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher harvest ckan_harvester
|
||||
|
||||
# Switch to the root user
|
||||
USER root
|
||||
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
|
||||
# Install and enable the custom extensions
|
||||
RUN pip install --no-index --find-links=/srv/app/ext_wheels ckanext-harvest && \
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels -r /srv/app/ext_wheels/harvest.txt && \
|
||||
# Configure plugins
|
||||
ckan config-tool "${APP_DIR}/production.ini" "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/ext_wheels
|
||||
|
||||
# Add harvest afterinit script
|
||||
COPY ./afterinit.d/00_harvest.sh ${APP_DIR}/docker-afterinit.d/00_harvest.sh
|
||||
|
||||
# Switch to the ckan user
|
||||
USER ckan
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/sh
|
||||
ckan -c /srv/app/production.ini harvester initdb
|
|
@ -1,192 +0,0 @@
|
|||
# docker-compose build && docker-compose up -d
|
||||
version: "3"
|
||||
|
||||
volumes:
|
||||
ckan_data:
|
||||
pg_data:
|
||||
solr_data:
|
||||
|
||||
services:
|
||||
ckan:
|
||||
container_name: ckan
|
||||
build:
|
||||
context: .
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
ports:
|
||||
- "0.0.0.0:${CKAN_PORT}:5000"
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
volumes:
|
||||
- ckan_data:/srv/app/data
|
||||
|
||||
ckan-harvest-gather:
|
||||
container_name: ckan-harvest-gather
|
||||
build:
|
||||
context: .
|
||||
command: ckan -c /srv/app/production.ini harvester gather-consumer
|
||||
restart: on-failure
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- ckan
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
|
||||
ckan-harvest-fetch:
|
||||
container_name: ckan-harvest-fetch
|
||||
build:
|
||||
context: .
|
||||
command: ckan -c /srv/app/production.ini harvester fetch-consumer
|
||||
restart: on-failure
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- ckan
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
|
||||
ckan-harvest-run:
|
||||
container_name: ckan-harvest-run
|
||||
build:
|
||||
context: .
|
||||
command: /bin/sh -c "while true; do sleep 900; ckan -c /srv/app/production.ini harvester run; done"
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- ckan
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
|
||||
ckan-harvest-cleanlog:
|
||||
container_name: ckan-harvest-cleanlog
|
||||
build:
|
||||
context: .
|
||||
command: /bin/sh -c "while true; do sleep 86400; ckan -c /srv/app/production.ini harvester clean_harvest_log; done"
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- ckan
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
|
||||
datapusher:
|
||||
container_name: datapusher
|
||||
image: ghcr.io/keitaroinc/datapusher:${DATAPUSHER_VERSION}
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- DATAPUSHER_MAX_CONTENT_LENGTH=${DATAPUSHER_MAX_CONTENT_LENGTH}
|
||||
- DATAPUSHER_CHUNK_SIZE=${DATAPUSHER_CHUNK_SIZE}
|
||||
- DATAPUSHER_CHUNK_INSERT_ROWS=${DATAPUSHER_CHUNK_INSERT_ROWS}
|
||||
- DATAPUSHER_DOWNLOAD_TIMEOUT=${DATAPUSHER_DOWNLOAD_TIMEOUT}
|
||||
- DATAPUSHER_SSL_VERIFY=${DATAPUSHER_SSL_VERIFY}
|
||||
- DATAPUSHER_REWRITE_RESOURCES=${DATAPUSHER_REWRITE_RESOURCES}
|
||||
- DATAPUSHER_REWRITE_URL=${DATAPUSHER_REWRITE_URL}
|
||||
|
||||
db:
|
||||
container_name: db
|
||||
build:
|
||||
context: ../../compose/2.9
|
||||
dockerfile: postgresql/Dockerfile
|
||||
args:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
networks:
|
||||
- backend
|
||||
environment:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- PGDATA=/var/lib/postgresql/data/db
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "ckan"]
|
||||
|
||||
solr:
|
||||
container_name: solr
|
||||
image: solr:8.11.1
|
||||
networks:
|
||||
- backend
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_CORE_NAME=${CKAN_CORE_NAME}
|
||||
- CKAN_VERSION=${CKAN_VERSION}
|
||||
volumes:
|
||||
- solr_data:/var/solr
|
||||
- ${PWD}/../../compose/2.9/solr8/ckan_init_solr.sh:/docker-entrypoint-initdb.d/ckan_init_solr.sh
|
||||
|
||||
redis:
|
||||
container_name: redis
|
||||
image: redis:${REDIS_VERSION}
|
||||
networks:
|
||||
- backend
|
||||
|
||||
networks:
|
||||
frontend:
|
||||
backend:
|
|
@ -1,42 +0,0 @@
|
|||
# Runtime configuration of CKAN enabled through ckanext-envvars
|
||||
# Information about how it works: https://github.com/okfn/ckanext-envvars
|
||||
# Note that variables here take presedence over build/up time variables in .env
|
||||
|
||||
# General Settings
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
# CKAN Plugins
|
||||
CKAN__PLUGINS=envvars s3filestore image_view webpage_view text_view recline_view datastore datapusher
|
||||
# CKAN requires storage path to be set in order for filestore to be enabled
|
||||
CKAN__STORAGE_PATH=/srv/app/data
|
||||
CKAN__WEBASSETS__PATH=/srv/app/data/webassets
|
||||
# SYSADMIN settings, a sysadmin user is created automatically with the below credentials
|
||||
CKAN_SYSADMIN_NAME=sysadmin
|
||||
CKAN_SYSADMIN_PASSWORD=password
|
||||
CKAN_SYSADMIN_EMAIL=sysadmin@ckantest.com
|
||||
CKAN__VIEWS__DEFAULT_VIEWS=image_view webpage_view text_view recline_view
|
||||
|
||||
# Email settings
|
||||
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
|
||||
|
||||
# Datapusher configuration
|
||||
CKAN__DATAPUSHER__URL=http://datapusher:8000
|
||||
CKAN__DATAPUSHER__CALLBACK_URL_BASE=http://ckan:5000/
|
||||
|
||||
# S3/MINIO settings
|
||||
CKANEXT__S3FILESTORE__AWS_ACCESS_KEY_ID=MINIOACCESSKEY
|
||||
CKANEXT__S3FILESTORE__AWS_SECRET_ACCESS_KEY=MINIOSECRETKEY
|
||||
CKANEXT__S3FILESTORE__AWS_BUCKET_NAME=ckan
|
||||
CKANEXT__S3FILESTORE__HOST_NAME=http://minio:9000
|
||||
CKANEXT__S3FILESTORE__REGION_NAME=us-east-1
|
||||
CKANEXT__S3FILESTORE__SIGNATURE_VERSION=s3v4
|
||||
|
||||
# Solr configuration
|
||||
CKAN_VERSION=2.9.11
|
||||
CKAN_CORE_NAME=ckan
|
|
@ -1,35 +0,0 @@
|
|||
# Variables in this file will be used as build arguments when running
|
||||
# docker-compose build and docker-compose up
|
||||
# Verify correct substitution with "docker-compose config"
|
||||
# If variables are newly added or enabled, please delete and rebuild the images to pull in changes:
|
||||
# docker-compose down -v
|
||||
# docker-compose build
|
||||
# docker-compose up -d
|
||||
|
||||
# Database
|
||||
POSTGRES_PASSWORD=ckan
|
||||
POSTGRES_PORT=5432
|
||||
DATASTORE_READONLY_PASSWORD=datastore
|
||||
|
||||
# CKAN
|
||||
CKAN_VERSION=2.9.11
|
||||
CKAN_SITE_ID=default
|
||||
CKAN_SITE_URL=http://localhost:5000
|
||||
CKAN_PORT=5000
|
||||
CKAN_MAX_UPLOAD_SIZE_MB=10
|
||||
|
||||
# Datapusher
|
||||
DATAPUSHER_VERSION=0.0.17
|
||||
DATAPUSHER_MAX_CONTENT_LENGTH=10485760
|
||||
DATAPUSHER_CHUNK_SIZE=16384
|
||||
DATAPUSHER_CHUNK_INSERT_ROWS=250
|
||||
DATAPUSHER_DOWNLOAD_TIMEOUT=30
|
||||
DATAPUSHER_SSL_VERIFY=False
|
||||
DATAPUSHER_REWRITE_RESOURCES=True
|
||||
DATAPUSHER_REWRITE_URL=http://ckan:5000
|
||||
|
||||
# SOLR
|
||||
CKAN_CORE_NAME=ckan
|
||||
|
||||
# Redis
|
||||
REDIS_VERSION=6.0.7
|
|
@ -1,43 +0,0 @@
|
|||
###################
|
||||
### Extensions ####
|
||||
###################
|
||||
FROM ghcr.io/keitaroinc/ckan:2.9.11 as extbuild
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV S3FILESTORE_GIT_URL=https://github.com/keitaroinc/ckanext-s3filestore
|
||||
ENV S3FILESTORE_GIT_BRANCH=v1.0.0
|
||||
|
||||
# Switch to the root user
|
||||
USER root
|
||||
|
||||
# Fetch and build the custom CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${S3FILESTORE_GIT_URL}@${S3FILESTORE_GIT_BRANCH}#egg=ckanext-s3filestore
|
||||
RUN pip wheel --wheel-dir=/wheels -r https://raw.githubusercontent.com/keitaroinc/ckanext-s3filestore/${S3FILESTORE_GIT_BRANCH}/requirements.txt
|
||||
RUN curl -o /wheels/s3filestore.txt https://raw.githubusercontent.com/keitaroinc/ckanext-s3filestore/${S3FILESTORE_GIT_BRANCH}/requirements.txt
|
||||
|
||||
USER ckan
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM ghcr.io/keitaroinc/ckan:2.9.11
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
|
||||
ENV CKAN__PLUGINS envvars s3filestore image_view webpage_view text_view recline_view datastore datapusher
|
||||
|
||||
# Switch to the root user
|
||||
USER root
|
||||
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
|
||||
# Install and enable the custom extensions
|
||||
RUN pip install --no-index --find-links=/srv/app/ext_wheels ckanext-s3filestore && \
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels -r /srv/app/ext_wheels/s3filestore.txt && \
|
||||
ckan config-tool "${APP_DIR}/production.ini" "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/ext_wheels
|
||||
|
||||
USER ckan
|
|
@ -1,122 +0,0 @@
|
|||
# docker-compose build && docker-compose up -d
|
||||
version: "3"
|
||||
|
||||
volumes:
|
||||
minio_data:
|
||||
pg_data:
|
||||
solr_data:
|
||||
|
||||
services:
|
||||
ckan:
|
||||
container_name: ckan
|
||||
build:
|
||||
context: .
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
ports:
|
||||
- "0.0.0.0:${CKAN_PORT}:5000"
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_SQLALCHEMY_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/ckan
|
||||
- CKAN_DATASTORE_WRITE_URL=postgresql://ckan:${POSTGRES_PASSWORD}@db/datastore
|
||||
- CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:${DATASTORE_READONLY_PASSWORD}@db/datastore
|
||||
- CKAN_SOLR_URL=http://solr:8983/solr/ckan
|
||||
- CKAN_REDIS_URL=redis://redis:6379/1
|
||||
- CKAN_SITE_URL=${CKAN_SITE_URL}
|
||||
- CKAN_MAX_UPLOAD_SIZE_MB=${CKAN_MAX_UPLOAD_SIZE_MB}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
|
||||
datapusher:
|
||||
container_name: datapusher
|
||||
image: ghcr.io/keitaroinc/datapusher:${DATAPUSHER_VERSION}
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- DATAPUSHER_MAX_CONTENT_LENGTH=${DATAPUSHER_MAX_CONTENT_LENGTH}
|
||||
- DATAPUSHER_CHUNK_SIZE=${DATAPUSHER_CHUNK_SIZE}
|
||||
- DATAPUSHER_CHUNK_INSERT_ROWS=${DATAPUSHER_CHUNK_INSERT_ROWS}
|
||||
- DATAPUSHER_DOWNLOAD_TIMEOUT=${DATAPUSHER_DOWNLOAD_TIMEOUT}
|
||||
- DATAPUSHER_SSL_VERIFY=${DATAPUSHER_SSL_VERIFY}
|
||||
- DATAPUSHER_REWRITE_RESOURCES=${DATAPUSHER_REWRITE_RESOURCES}
|
||||
- DATAPUSHER_REWRITE_URL=${DATAPUSHER_REWRITE_URL}
|
||||
|
||||
db:
|
||||
container_name: db
|
||||
build:
|
||||
context: ../../compose/2.9
|
||||
dockerfile: postgresql/Dockerfile
|
||||
args:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
networks:
|
||||
- backend
|
||||
environment:
|
||||
- DS_RO_PASS=${DATASTORE_READONLY_PASSWORD}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- PGDATA=/var/lib/postgresql/data/db
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "ckan"]
|
||||
|
||||
solr:
|
||||
container_name: solr
|
||||
image: solr:8.11.1
|
||||
networks:
|
||||
- backend
|
||||
env_file:
|
||||
- ./.ckan-env
|
||||
environment:
|
||||
- CKAN_CORE_NAME=${CKAN_CORE_NAME}
|
||||
- CKAN_VERSION=${CKAN_VERSION}
|
||||
volumes:
|
||||
- solr_data:/var/solr
|
||||
- ${PWD}/../../compose/2.9/solr8/ckan_init_solr.sh:/docker-entrypoint-initdb.d/ckan_init_solr.sh
|
||||
|
||||
redis:
|
||||
container_name: redis
|
||||
image: redis:${REDIS_VERSION}
|
||||
networks:
|
||||
- backend
|
||||
|
||||
minio:
|
||||
container_name: minio
|
||||
image: minio/minio:RELEASE.2020-08-08T04-50-06Z
|
||||
networks:
|
||||
- backend
|
||||
- frontend
|
||||
ports:
|
||||
- "0.0.0.0:9000:9000"
|
||||
environment:
|
||||
- MINIO_ACCESS_KEY=MINIOACCESSKEY
|
||||
- MINIO_SECRET_KEY=MINIOSECRETKEY
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
command: server /data
|
||||
|
||||
mc:
|
||||
container_name: mc
|
||||
image: minio/mc:RELEASE.2020-08-08T02-33-58Z
|
||||
networks:
|
||||
- backend
|
||||
depends_on:
|
||||
- minio
|
||||
entrypoint: >
|
||||
/bin/sh -c "
|
||||
/usr/bin/mc config host rm local;
|
||||
/usr/bin/mc config host add --api s3v4 local http://minio:9000 MINIOACCESSKEY MINIOSECRETKEY;
|
||||
/usr/bin/mc mb local/ckan/;
|
||||
/usr/bin/mc policy set download local/ckan/storage;
|
||||
"
|
||||
|
||||
networks:
|
||||
frontend:
|
||||
backend:
|
|
@ -1,196 +0,0 @@
|
|||
##################
|
||||
### Build CKAN ###
|
||||
##################
|
||||
FROM alpine:3.14.2 as ckanbuild
|
||||
|
||||
# Used by Github Actions to tag the image with
|
||||
ENV IMAGE_TAG=2.7.12
|
||||
|
||||
# Set CKAN version to build
|
||||
ENV GIT_URL=https://github.com/ckan/ckan.git
|
||||
ENV GIT_BRANCH=ckan-2.7.12
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
WORKDIR ${SRC_DIR}
|
||||
|
||||
# Packages to build CKAN requirements and plugins
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
curl \
|
||||
python2 \
|
||||
postgresql-dev \
|
||||
linux-headers \
|
||||
gcc \
|
||||
make \
|
||||
g++ \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
patch \
|
||||
musl-dev \
|
||||
pcre-dev \
|
||||
pcre \
|
||||
python2-dev \
|
||||
libffi-dev \
|
||||
libxml2-dev \
|
||||
libxslt-dev
|
||||
|
||||
# Install version 9.x of postgresql-dev so that CKAN requirements can be built
|
||||
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.6/main \
|
||||
postgresql-dev~=9.6
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build CKAN and requirements
|
||||
RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan
|
||||
# Copy patches and apply patches script
|
||||
COPY ./patches ${SRC_DIR}/patches
|
||||
COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh
|
||||
# Apply patches
|
||||
RUN ${SRC_DIR}/apply_ckan_patches.sh
|
||||
RUN rm -rf /srv/app/src/ckan/.git
|
||||
RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt
|
||||
RUN pip wheel --wheel-dir=/wheels uwsgi==2.0.19.1 gevent==21.12.0 greenlet==1.1.3
|
||||
|
||||
|
||||
###########################
|
||||
### Default-Extensions ####
|
||||
###########################
|
||||
FROM alpine:3.14.2 as extbuild
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
# List of default extensions
|
||||
ENV DEFAULT_EXTENSIONS envvars
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars
|
||||
ENV ENVVARS_GIT_BRANCH=0.0.1
|
||||
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
curl \
|
||||
python2 \
|
||||
python2-dev
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build the default CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM alpine:3.14.2
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/keitaroinc/docker-ckan
|
||||
|
||||
ENV APP_DIR=/srv/app
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV CKAN_DIR=${SRC_DIR}/ckan
|
||||
ENV DATA_DIR=/srv/app/data
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
ENV CKAN_SITE_URL=http://localhost:5000
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher
|
||||
|
||||
# Install necessary packages to run CKAN
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
bash \
|
||||
git \
|
||||
gettext \
|
||||
curl \
|
||||
python2 \
|
||||
libmagic \
|
||||
pcre \
|
||||
libxslt \
|
||||
libxml2 \
|
||||
tzdata \
|
||||
apache2-utils && \
|
||||
# Install version 9.x of postgresql-client so that CKAN can run
|
||||
apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.6/main \
|
||||
postgresql-client~=9.6 && \
|
||||
# Create SRC_DIR
|
||||
mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Get artifacts from build stages
|
||||
COPY --from=ckanbuild /wheels /srv/app/wheels
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
COPY --from=ckanbuild /srv/app/src/ckan ${CKAN_DIR}
|
||||
|
||||
# Additional install steps for build stages artifacts
|
||||
RUN pip install --no-index --find-links=/srv/app/wheels uwsgi==2.0.19.1 gevent==21.12.0
|
||||
|
||||
# Create a local user and group to run the app
|
||||
RUN addgroup -g 92 -S ckan && \
|
||||
adduser -u 92 -h /srv/app -H -D -S -G ckan ckan
|
||||
|
||||
WORKDIR ${CKAN_DIR}
|
||||
|
||||
# Install CKAN
|
||||
RUN pip install -e /srv/app/src/ckan && \
|
||||
cp who.ini ${APP_DIR} && \
|
||||
pip install --no-index --find-links=/srv/app/wheels -r requirements.txt && \
|
||||
# Install default CKAN extensions
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels ckanext-envvars && \
|
||||
# Create and update CKAN config
|
||||
# Set timezone
|
||||
echo "UTC" > /etc/timezone && \
|
||||
# Generate CKAN config
|
||||
paster --plugin=ckan make-config ckan ${APP_DIR}/production.ini && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "beaker.session.secret = " && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
# Set the default level for extensions to INFO
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini -s logger_ckanext -e level=INFO && \
|
||||
# Create the data directory
|
||||
mkdir ${DATA_DIR} && \
|
||||
# Change ownership to app user
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/wheels /srv/app/ext_wheels
|
||||
|
||||
# Install python2 secrets for generating sessions
|
||||
RUN pip install python2-secrets
|
||||
|
||||
# Copy necessary scripts
|
||||
COPY setup/app ${APP_DIR}
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Copy the alias script for paster to be ckan so it's compatible with 2.9
|
||||
COPY setup/bin/ckan /usr/bin/ckan
|
||||
|
||||
# Create entrypoint directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-entrypoint.d
|
||||
|
||||
# Create afterinit directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-afterinit.d
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1
|
||||
|
||||
USER ckan
|
||||
|
||||
CMD ["/srv/app/start_ckan.sh"]
|
|
@ -1,240 +0,0 @@
|
|||
##################
|
||||
### Build CKAN ###
|
||||
##################
|
||||
FROM ubuntu:focal-20210827 as ckanbuild
|
||||
|
||||
# Used by Github Actions to tag the image with
|
||||
ENV IMAGE_TAG=2.7.12-focal
|
||||
|
||||
# Set CKAN version to build
|
||||
ENV GIT_URL=https://github.com/ckan/ckan.git
|
||||
ENV GIT_BRANCH=ckan-2.7.12
|
||||
|
||||
# Set timezone
|
||||
ENV TZ=UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Set Locale
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
WORKDIR ${SRC_DIR}
|
||||
|
||||
# Set the locale
|
||||
RUN apt-get update
|
||||
RUN apt-get install --no-install-recommends -y locales
|
||||
RUN sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen
|
||||
RUN dpkg-reconfigure --frontend=noninteractive locales
|
||||
RUN update-locale LANG=${LC_ALL}
|
||||
|
||||
# Instal apt-utils
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
apt-utils
|
||||
|
||||
# Packages to build CKAN requirements and plugins
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
gnupg \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python \
|
||||
linux-headers-generic \
|
||||
gcc-10 \
|
||||
make \
|
||||
g++-10 \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
patch \
|
||||
libpcre3-dev \
|
||||
libpcre3 \
|
||||
python-dev \
|
||||
libffi-dev \
|
||||
libxml2-dev \
|
||||
libxslt-dev
|
||||
|
||||
# Install version 9.x of postgresql-dev so that CKAN requirements can be built
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN curl -s -o - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||
RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main" >> /etc/apt/sources.list.d/postgresql.list'
|
||||
RUN apt-get update
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
postgresql-server-dev-9.6
|
||||
|
||||
# Use gcc 10
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 --slave /usr/bin/gcov gcov /usr/bin/gcov-10 --slave /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/x86_64-linux-gnu-gcc-10
|
||||
|
||||
#postgresql-server-dev-9.6 Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build CKAN and requirements
|
||||
RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan
|
||||
# Copy patches and apply patches script
|
||||
COPY ./patches ${SRC_DIR}/patches
|
||||
COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh
|
||||
# Apply patches
|
||||
RUN ${SRC_DIR}/apply_ckan_patches.sh
|
||||
RUN rm -rf /srv/app/src/ckan/.git
|
||||
RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt
|
||||
RUN pip wheel --wheel-dir=/wheels uwsgi==2.0.19.1 gevent==21.12.0 greenlet==1.1.3
|
||||
|
||||
|
||||
###########################
|
||||
### Default-Extensions ####
|
||||
###########################
|
||||
FROM ubuntu:focal-20210827 as extbuild
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
# List of default extensions
|
||||
ENV DEFAULT_EXTENSIONS envvars
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars
|
||||
ENV ENVVARS_GIT_BRANCH=0.0.1
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python \
|
||||
python-dev
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build the default CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM ubuntu:focal-20210827
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/keitaroinc/docker-ckan
|
||||
|
||||
# Set timezone
|
||||
ENV TZ=UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Set Locale
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
# Set the locale
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y locales && \
|
||||
sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen && \
|
||||
dpkg-reconfigure --frontend=noninteractive locales && \
|
||||
update-locale LANG=${LC_ALL} && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV APP_DIR=/srv/app
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV CKAN_DIR=${SRC_DIR}/ckan
|
||||
ENV DATA_DIR=/srv/app/data
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
ENV CKAN_SITE_URL=http://localhost:5000
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher
|
||||
|
||||
# Install necessary packages to run CKAN
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
gettext \
|
||||
curl \
|
||||
ca-certificates \
|
||||
git \
|
||||
gnupg \
|
||||
python \
|
||||
libpython2.7 \
|
||||
libmagic1 \
|
||||
libpcre3 \
|
||||
libxslt1.1 \
|
||||
libxml2 \
|
||||
tzdata \
|
||||
apache2-utils && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
# Install version 9.x of postgresql-client so that CKAN can run
|
||||
curl -s -o - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
|
||||
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main" >> /etc/apt/sources.list.d/postgresql.list' && \
|
||||
apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
postgresql-client-9.6 && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
# Create SRC_DIR
|
||||
mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Get artifacts from build stages
|
||||
COPY --from=ckanbuild /wheels /srv/app/wheels
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
COPY --from=ckanbuild /srv/app/src/ckan ${CKAN_DIR}
|
||||
|
||||
# Additional install steps for build stages artifacts
|
||||
RUN pip install --no-index --find-links=/srv/app/wheels uwsgi==2.0.19.1 gevent==21.12.0
|
||||
# Create a local user and group to run the app
|
||||
RUN groupadd -g 92 ckan && \
|
||||
useradd -rm -d /srv/app -s /bin/bash -g ckan -u 92 ckan
|
||||
|
||||
WORKDIR ${CKAN_DIR}
|
||||
|
||||
# Install CKAN
|
||||
RUN pip install -e /srv/app/src/ckan && \
|
||||
cp who.ini ${APP_DIR} && \
|
||||
pip install --no-index --find-links=/srv/app/wheels -r requirements.txt && \
|
||||
# Install default CKAN extensions
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels ckanext-envvars && \
|
||||
# Create and update CKAN config
|
||||
# Generate CKAN config
|
||||
paster --plugin=ckan make-config ckan ${APP_DIR}/production.ini && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "beaker.session.secret = " && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
# Set the default level for extensions to INFO
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini -s logger_ckanext -e level=INFO && \
|
||||
# Create the data directory
|
||||
mkdir ${DATA_DIR} && \
|
||||
# Change ownership to app user
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/wheels /srv/app/ext_wheels
|
||||
|
||||
# Copy necessary scripts
|
||||
COPY setup/app ${APP_DIR}
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Copy the alias script for paster to be ckan so it's compatible with 2.9
|
||||
COPY setup/bin/ckan /usr/bin/ckan
|
||||
|
||||
# Create entrypoint directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-entrypoint.d
|
||||
|
||||
# Create afterinit directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-afterinit.d
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1
|
||||
|
||||
USER ckan
|
||||
|
||||
CMD ["/srv/app/start_ckan.sh"]
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
shopt -s nullglob
|
||||
for patch in patches/*.patch; do
|
||||
/usr/bin/patch -p0 -i $patch
|
||||
done
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# this is called before uwsgi is executed
|
||||
# uset his to add extra scripts before ckan is started
|
|
@ -1,25 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Maintenance</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Maintenance</h1>
|
||||
<p>Our data portal is currently in maintenance, please try in a while.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Maintenance</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Maintenance</h1>
|
||||
<p>Our data portal is currently in maintenance, please try in a while.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,38 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
from BaseHTTPServer import HTTPServer
|
||||
from SocketServer import ThreadingMixIn
|
||||
import os
|
||||
|
||||
PORT = 5000
|
||||
|
||||
web_dir = os.path.join(os.path.dirname(__file__))
|
||||
os.chdir(web_dir)
|
||||
|
||||
Handler = SimpleHTTPRequestHandler
|
||||
|
||||
|
||||
class MaintenanceServer(ThreadingMixIn, HTTPServer):
|
||||
"""Handle requests in a separate thread."""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
httpd = MaintenanceServer(("0.0.0.0", PORT), Handler)
|
||||
print("Starting maintenance mode")
|
||||
httpd.serve_forever()
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import psycopg2
|
||||
import urllib2
|
||||
import re
|
||||
|
||||
import time
|
||||
|
||||
ckan_ini = os.environ.get('CKAN_INI', '/srv/app/production.ini')
|
||||
|
||||
RETRY = 5
|
||||
|
||||
def check_db_connection(retry=None):
|
||||
|
||||
print('[prerun] Start check_db_connection...')
|
||||
|
||||
if retry is None:
|
||||
retry = RETRY
|
||||
elif retry == 0:
|
||||
print('[prerun] Giving up after 5 tries...')
|
||||
sys.exit(1)
|
||||
|
||||
conn_str = os.environ.get('CKAN_SQLALCHEMY_URL', '')
|
||||
try:
|
||||
connection = psycopg2.connect(conn_str)
|
||||
|
||||
except psycopg2.Error as e:
|
||||
print((str(e)))
|
||||
print('[prerun] Unable to connect to the database...try again in a while.')
|
||||
import time
|
||||
time.sleep(10)
|
||||
check_db_connection(retry = retry - 1)
|
||||
else:
|
||||
connection.close()
|
||||
|
||||
def check_solr_connection(retry=None):
|
||||
|
||||
print('[prerun] Start check_solr_connection...')
|
||||
|
||||
if retry is None:
|
||||
retry = RETRY
|
||||
elif retry == 0:
|
||||
print('[prerun] Giving up after 5 tries...')
|
||||
sys.exit(1)
|
||||
|
||||
url = os.environ.get('CKAN_SOLR_URL', '')
|
||||
search_url = '{url}/select/?q=*&wt=json'.format(url=url)
|
||||
|
||||
try:
|
||||
connection = urllib2.urlopen(search_url)
|
||||
except urllib2.URLError as e:
|
||||
print('[prerun] Unable to connect to solr...try again in a while.')
|
||||
import time
|
||||
time.sleep(10)
|
||||
check_solr_connection(retry = retry - 1)
|
||||
else:
|
||||
import re
|
||||
conn_info = connection.read()
|
||||
# SolrCloud
|
||||
conn_info = re.sub(r'"zkConnected":true', '"zkConnected":True', conn_info)
|
||||
eval(conn_info)
|
||||
|
||||
def init_db():
|
||||
|
||||
print('[prerun] Start init_db...')
|
||||
|
||||
db_command = ['paster', '--plugin=ckan', 'db', 'init', '-c', ckan_ini]
|
||||
|
||||
print('[prerun] Initializing or upgrading db - start using paster db init')
|
||||
try:
|
||||
# run init scripts
|
||||
subprocess.check_output(db_command, stderr=subprocess.STDOUT)
|
||||
|
||||
print('[prerun] Initializing or upgrading db - end')
|
||||
except subprocess.CalledProcessError as e:
|
||||
if 'OperationalError' in e.output:
|
||||
print('[prerun] Database not ready, waiting a bit before exit...')
|
||||
import time
|
||||
time.sleep(5)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print((e.output))
|
||||
raise e
|
||||
print('[prerun] Initializing or upgrading db - finish')
|
||||
|
||||
|
||||
def init_datastore():
|
||||
|
||||
conn_str = os.environ.get('CKAN_DATASTORE_WRITE_URL')
|
||||
if not conn_str:
|
||||
print('[prerun] Skipping datastore initialization')
|
||||
return
|
||||
|
||||
datastore_perms_command = ['paster', '--plugin=ckan', 'datastore',
|
||||
'set-permissions', '-c', ckan_ini]
|
||||
|
||||
connection = psycopg2.connect(conn_str)
|
||||
cursor = connection.cursor()
|
||||
|
||||
print('[prerun] Initializing datastore db - start')
|
||||
try:
|
||||
datastore_perms = subprocess.Popen(
|
||||
datastore_perms_command,
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
perms_sql = datastore_perms.stdout.read()
|
||||
# Remove internal pg command as psycopg2 does not like it
|
||||
perms_sql = re.sub('\\\\connect \"(.*)\"', '', perms_sql.decode('utf-8'))
|
||||
cursor.execute(perms_sql)
|
||||
for notice in connection.notices:
|
||||
print(notice)
|
||||
|
||||
connection.commit()
|
||||
|
||||
print('[prerun] Initializing datastore db - end')
|
||||
print((datastore_perms.stdout.read()))
|
||||
except psycopg2.Error as e:
|
||||
print('[prerun] Could not initialize datastore')
|
||||
print((str(e)))
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
if 'OperationalError' in e.output:
|
||||
print((e.output))
|
||||
print('[prerun] Database not ready, waiting a bit before exit...')
|
||||
time.sleep(5)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print((e.output))
|
||||
raise e
|
||||
finally:
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
|
||||
def create_sysadmin():
|
||||
|
||||
print('[prerun] Start create_sysadmin...')
|
||||
|
||||
name = os.environ.get('CKAN_SYSADMIN_NAME')
|
||||
password = os.environ.get('CKAN_SYSADMIN_PASSWORD')
|
||||
email = os.environ.get('CKAN_SYSADMIN_EMAIL')
|
||||
|
||||
if name and password and email:
|
||||
|
||||
# Check if user exists
|
||||
command = ['paster', '--plugin=ckan', 'user', name, '-c', ckan_ini]
|
||||
|
||||
out = subprocess.check_output(command)
|
||||
if 'User:None' not in re.sub(r'\s', '', out.decode('utf-8')):
|
||||
print('[prerun] Sysadmin user exists, skipping creation')
|
||||
return
|
||||
|
||||
# Create user
|
||||
command = ['paster', '--plugin=ckan', 'user', 'add',
|
||||
name,
|
||||
'password=' + password,
|
||||
'email=' + email,
|
||||
'-c', ckan_ini]
|
||||
|
||||
subprocess.call(command)
|
||||
print(('[prerun] Created user {0}'.format(name)))
|
||||
|
||||
# Make it sysadmin
|
||||
command = ['paster', '--plugin=ckan', 'sysadmin', 'add',
|
||||
name,
|
||||
'-c', ckan_ini]
|
||||
|
||||
subprocess.call(command)
|
||||
print(('[prerun] Made user {0} a sysadmin'.format(name)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
maintenance = os.environ.get('MAINTENANCE_MODE', '').lower() == 'true'
|
||||
|
||||
if maintenance:
|
||||
print('[prerun] Maintenance mode, skipping setup...')
|
||||
else:
|
||||
check_db_connection()
|
||||
check_solr_connection()
|
||||
init_db()
|
||||
if os.environ.get('CKAN_DATASTORE_WRITE_URL'):
|
||||
init_datastore()
|
||||
create_sysadmin()
|
|
@ -1,74 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Run any startup scripts provided by images extending this one
|
||||
if [[ -d "${APP_DIR}/docker-entrypoint.d" ]]
|
||||
then
|
||||
for f in ${APP_DIR}/docker-entrypoint.d/*; do
|
||||
case "$f" in
|
||||
*.sh) echo "$0: Running init file $f"; . "$f" ;;
|
||||
*.py) echo "$0: Running init file $f"; python "$f"; echo ;;
|
||||
*) echo "$0: Ignoring $f (not an sh or py file)" ;;
|
||||
esac
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
# Add session secret from chart
|
||||
if [[ -z $BEAKER_SESSION_SECRET || -v $BEAKER_SESSION_SECRET ]];then
|
||||
echo "Not all environment variables are set. Generating sessions..."
|
||||
else
|
||||
echo "Setting session secrets from environment variables"
|
||||
paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$BEAKER_SESSION_SECRET"
|
||||
fi
|
||||
|
||||
if grep -E "beaker.session.secret ?= ?$" $APP_DIR/production.ini
|
||||
then
|
||||
echo "Setting beaker.session.secret in ini file"
|
||||
paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$(python -c 'import secrets; print(secrets.token_urlsafe())')"
|
||||
fi
|
||||
|
||||
# Set the common uwsgi options
|
||||
echo "Starting UWSGI with '${UWSGI_PROC_NO:-2}' workers"
|
||||
|
||||
UWSGI_OPTS="--socket /tmp/uwsgi.sock --uid 92 --gid 92 --http :5000 --master --enable-threads --paste config:/srv/app/production.ini --paste-logger /srv/app/production.ini --lazy-apps --gevent 2000 -p ${UWSGI_PROC_NO:-2} -L --gevent-early-monkey-patch"
|
||||
|
||||
# Run the prerun script to init CKAN and create the default admin user
|
||||
python prerun.py || { echo '[CKAN prerun] FAILED. Exiting...' ; exit 1; }
|
||||
|
||||
# Check if we are in maintenance mode and if yes serve the maintenance pages
|
||||
if [ "$MAINTENANCE_MODE" = true ]; then PYTHONUNBUFFERED=1 python maintenance/serve.py; fi
|
||||
|
||||
# Run any after prerun/init scripts provided by images extending this one
|
||||
if [[ -d "${APP_DIR}/docker-afterinit.d" ]]
|
||||
then
|
||||
for f in ${APP_DIR}/docker-afterinit.d/*; do
|
||||
case "$f" in
|
||||
*.sh) echo "$0: Running after prerun init file $f"; . "$f" ;;
|
||||
*.py) echo "$0: Running after prerun init file $f"; python "$f"; echo ;;
|
||||
*) echo "$0: Ignoring $f (not an sh or py file)" ;;
|
||||
esac
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
if [ "$PASSWORD_PROTECT" = true ]
|
||||
then
|
||||
if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ]
|
||||
then
|
||||
# Generate htpasswd file for basicauth
|
||||
htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD
|
||||
# Start uwsgi with basicauth
|
||||
uwsgi --ini /srv/app/uwsgi.conf --pcre-jit $UWSGI_OPTS
|
||||
else
|
||||
echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Start uwsgi
|
||||
uwsgi $UWSGI_OPTS
|
||||
fi
|
||||
else
|
||||
echo "[prerun] failed...not starting CKAN."
|
||||
fi
|
|
@ -1,2 +0,0 @@
|
|||
[uwsgi]
|
||||
route = ^(?!/api).*$ basicauth:Restricted,/srv/app/.htpasswd
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
# CKAN <2.9 uses paster and the ckan plugin for paster which expects the configuration to be passed
|
||||
# to a subcommand, example: paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions
|
||||
# CKAN >2.9 ckan CLI command expects the configuration option as the second and third parameter
|
||||
# Example: ckan -c /srv/app/production.ini datastore set-permissions
|
||||
#
|
||||
# Shift three arguments so that we can reorder the argument list
|
||||
# ckan -c /srv/app/production.ini datastore set-permissions
|
||||
# becomes
|
||||
# paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions
|
||||
config_switch=$1
|
||||
config_file=$2
|
||||
subcommand=$3
|
||||
shift 3
|
||||
paster --plugin=ckan "$subcommand" "$config_switch" "$config_file" "$@"
|
|
@ -1,189 +0,0 @@
|
|||
##################
|
||||
### Build CKAN ###
|
||||
##################
|
||||
FROM alpine:3.14.2 as ckanbuild
|
||||
|
||||
# Used by Github Actions to tag the image with
|
||||
ENV IMAGE_TAG=2.8.12
|
||||
|
||||
# Set CKAN version to build
|
||||
ENV GIT_URL=https://github.com/ckan/ckan.git
|
||||
ENV GIT_BRANCH=ckan-2.8.12
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
WORKDIR ${SRC_DIR}
|
||||
|
||||
# Packages to build CKAN requirements and plugins
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
curl \
|
||||
python2 \
|
||||
postgresql-dev \
|
||||
linux-headers \
|
||||
gcc \
|
||||
make \
|
||||
g++ \
|
||||
autoconf \
|
||||
automake \
|
||||
patch \
|
||||
libtool \
|
||||
musl-dev \
|
||||
pcre-dev \
|
||||
pcre \
|
||||
python2-dev \
|
||||
libffi-dev \
|
||||
libxml2-dev \
|
||||
libxslt-dev
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build CKAN and requirements
|
||||
RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan
|
||||
# Copy patches and apply patches script
|
||||
COPY ./patches ${SRC_DIR}/patches
|
||||
COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh
|
||||
# Apply patches
|
||||
RUN ${SRC_DIR}/apply_ckan_patches.sh
|
||||
RUN rm -rf /srv/app/src/ckan/.git
|
||||
RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt
|
||||
RUN pip wheel --wheel-dir=/wheels uwsgi==2.0.19.1 gevent==21.12.0 greenlet==1.1.3
|
||||
|
||||
|
||||
###########################
|
||||
### Default-Extensions ####
|
||||
###########################
|
||||
FROM alpine:3.14.2 as extbuild
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
# List of default extensions
|
||||
ENV DEFAULT_EXTENSIONS envvars
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars
|
||||
ENV ENVVARS_GIT_BRANCH=0.0.1
|
||||
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
curl \
|
||||
python2 \
|
||||
python2-dev
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build the default CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM alpine:3.14.2
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/keitaroinc/docker-ckan
|
||||
|
||||
ENV APP_DIR=/srv/app
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV CKAN_DIR=${SRC_DIR}/ckan
|
||||
ENV DATA_DIR=/srv/app/data
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
ENV CKAN_SITE_URL=http://localhost:5000
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher
|
||||
|
||||
# Install necessary packages to run CKAN
|
||||
RUN apk add --no-cache git \
|
||||
bash \
|
||||
git \
|
||||
gettext \
|
||||
curl \
|
||||
postgresql-client \
|
||||
python2 \
|
||||
libmagic \
|
||||
pcre \
|
||||
libxslt \
|
||||
libxml2 \
|
||||
tzdata \
|
||||
apache2-utils && \
|
||||
# Create SRC_DIR
|
||||
mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Get artifacts from build stages
|
||||
COPY --from=ckanbuild /wheels /srv/app/wheels
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
COPY --from=ckanbuild /srv/app/src/ckan ${CKAN_DIR}
|
||||
|
||||
# Additional install steps for build stages artifacts
|
||||
RUN pip install --no-index --find-links=/srv/app/wheels uwsgi==2.0.19.1 gevent==21.12.0
|
||||
|
||||
# Create a local user and group to run the app
|
||||
RUN addgroup -g 92 -S ckan && \
|
||||
adduser -u 92 -h /srv/app -H -D -S -G ckan ckan
|
||||
|
||||
WORKDIR ${CKAN_DIR}
|
||||
|
||||
# Install CKAN
|
||||
RUN pip install -e /srv/app/src/ckan && \
|
||||
cp who.ini ${APP_DIR} && \
|
||||
pip install --no-index --find-links=/srv/app/wheels -r requirements.txt && \
|
||||
# Install default CKAN extensions
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels ckanext-envvars && \
|
||||
# Create and update CKAN config
|
||||
# Set timezone
|
||||
echo "UTC" > /etc/timezone && \
|
||||
# Generate CKAN config
|
||||
paster --plugin=ckan make-config ckan ${APP_DIR}/production.ini && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "beaker.session.secret = " && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
# Set the default level for extensions to INFO
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini -s logger_ckanext -e level=INFO && \
|
||||
# Create the data directory
|
||||
mkdir ${DATA_DIR} && \
|
||||
# Change ownership to app user
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/wheels /srv/app/ext_wheels
|
||||
|
||||
# Install python2 secrets for generating sessions
|
||||
RUN pip install python2-secrets
|
||||
|
||||
# Copy necessary scripts
|
||||
COPY setup/app ${APP_DIR}
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Copy the alias script for paster to be ckan so it's compatible with 2.9
|
||||
COPY setup/bin/ckan /usr/bin/ckan
|
||||
|
||||
# Create entrypoint directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-entrypoint.d
|
||||
|
||||
# Create afterinit directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-afterinit.d
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1
|
||||
|
||||
USER ckan
|
||||
|
||||
CMD ["/srv/app/start_ckan.sh"]
|
|
@ -1,226 +0,0 @@
|
|||
##################
|
||||
### Build CKAN ###
|
||||
##################
|
||||
FROM ubuntu:focal-20210827 as ckanbuild
|
||||
|
||||
# Used by Github Actions to tag the image with
|
||||
ENV IMAGE_TAG=2.8.12-focal
|
||||
|
||||
# Set CKAN version to build
|
||||
ENV GIT_URL=https://github.com/ckan/ckan.git
|
||||
ENV GIT_BRANCH=ckan-2.8.12
|
||||
|
||||
# Set timezone
|
||||
ENV TZ=UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Set Locale
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
WORKDIR ${SRC_DIR}
|
||||
|
||||
# Set the locale
|
||||
RUN apt-get update
|
||||
RUN apt-get install --no-install-recommends -y locales
|
||||
RUN sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen
|
||||
RUN dpkg-reconfigure --frontend=noninteractive locales
|
||||
RUN update-locale LANG=${LC_ALL}
|
||||
|
||||
# Instal apt-utils
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
apt-utils
|
||||
|
||||
# Packages to build CKAN requirements and plugins
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python \
|
||||
libpq-dev \
|
||||
linux-headers-generic \
|
||||
gcc-10 \
|
||||
make \
|
||||
g++-10 \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
patch \
|
||||
libpcre3-dev \
|
||||
libpcre3 \
|
||||
python-dev \
|
||||
libffi-dev \
|
||||
libxml2-dev \
|
||||
libxslt-dev
|
||||
|
||||
# Use gcc 10
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 --slave /usr/bin/gcov gcov /usr/bin/gcov-10 --slave /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/x86_64-linux-gnu-gcc-10
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build CKAN and requirements
|
||||
RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan
|
||||
# Copy patches and apply patches script
|
||||
COPY ./patches ${SRC_DIR}/patches
|
||||
COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh
|
||||
# Apply patches
|
||||
RUN ${SRC_DIR}/apply_ckan_patches.sh
|
||||
RUN rm -rf /srv/app/src/ckan/.git
|
||||
RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt
|
||||
RUN pip wheel --wheel-dir=/wheels uwsgi==2.0.19.1 gevent==21.12.0 greenlet==1.1.3
|
||||
|
||||
|
||||
###########################
|
||||
### Default-Extensions ####
|
||||
###########################
|
||||
FROM ubuntu:focal-20210827 as extbuild
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
# List of default extensions
|
||||
ENV DEFAULT_EXTENSIONS envvars
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars
|
||||
ENV ENVVARS_GIT_BRANCH=0.0.1
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python \
|
||||
python-dev
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Fetch and build the default CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM ubuntu:focal-20210827
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/keitaroinc/docker-ckan
|
||||
|
||||
# Set timezone
|
||||
ENV TZ=UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Set Locale
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
# Set the locale
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y locales && \
|
||||
sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen && \
|
||||
dpkg-reconfigure --frontend=noninteractive locales && \
|
||||
update-locale LANG=${LC_ALL} && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV APP_DIR=/srv/app
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV CKAN_DIR=${SRC_DIR}/ckan
|
||||
ENV DATA_DIR=/srv/app/data
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
ENV CKAN_SITE_URL=http://localhost:5000
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher
|
||||
|
||||
# Install necessary packages to run CKAN
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
gettext \
|
||||
curl \
|
||||
ca-certificates \
|
||||
git \
|
||||
libpq5 \
|
||||
postgresql-client \
|
||||
python \
|
||||
libpython2.7 \
|
||||
libmagic1 \
|
||||
libpcre3 \
|
||||
libxslt1.1 \
|
||||
libxml2 \
|
||||
tzdata \
|
||||
apache2-utils && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
# Create SRC_DIR
|
||||
mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py 'pip==20.3.3'
|
||||
|
||||
# Get artifacts from build stages
|
||||
COPY --from=ckanbuild /wheels /srv/app/wheels
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
COPY --from=ckanbuild /srv/app/src/ckan ${CKAN_DIR}
|
||||
|
||||
# Additional install steps for build stages artifacts
|
||||
RUN pip install --no-index --find-links=/srv/app/wheels uwsgi==2.0.19.1 gevent==21.12.0
|
||||
|
||||
# Create a local user and group to run the app
|
||||
RUN groupadd -g 92 ckan && \
|
||||
useradd -rm -d /srv/app -s /bin/bash -g ckan -u 92 ckan
|
||||
|
||||
WORKDIR ${CKAN_DIR}
|
||||
|
||||
# Install CKAN
|
||||
RUN pip install -e /srv/app/src/ckan && \
|
||||
cp who.ini ${APP_DIR} && \
|
||||
pip install --no-index --find-links=/srv/app/wheels -r requirements.txt && \
|
||||
# Install default CKAN extensions
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels ckanext-envvars && \
|
||||
# Create and update CKAN config
|
||||
# Generate CKAN config
|
||||
paster --plugin=ckan make-config ckan ${APP_DIR}/production.ini && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "beaker.session.secret = " && \
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
# Set the default level for extensions to INFO
|
||||
paster --plugin=ckan config-tool ${APP_DIR}/production.ini -s logger_ckanext -e level=INFO && \
|
||||
# Create the data directory
|
||||
mkdir ${DATA_DIR} && \
|
||||
# Change ownership to app user
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/wheels /srv/app/ext_wheels
|
||||
|
||||
# Copy necessary scripts
|
||||
COPY setup/app ${APP_DIR}
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Copy the alias script for paster to be ckan so it's compatible with 2.9
|
||||
COPY setup/bin/ckan /usr/bin/ckan
|
||||
|
||||
# Create entrypoint directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-entrypoint.d
|
||||
|
||||
# Create afterinit directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-afterinit.d
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1
|
||||
|
||||
USER ckan
|
||||
|
||||
CMD ["/srv/app/start_ckan.sh"]
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
shopt -s nullglob
|
||||
for patch in patches/*.patch; do
|
||||
/usr/bin/patch -p0 -i $patch
|
||||
done
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# this is called before uwsgi is executed
|
||||
# uset his to add extra scripts before ckan is started
|
|
@ -1,25 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Maintenance</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Maintenance</h1>
|
||||
<p>Our data portal is currently in maintenance, please try in a while.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Maintenance</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Maintenance</h1>
|
||||
<p>Our data portal is currently in maintenance, please try in a while.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,38 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
from BaseHTTPServer import HTTPServer
|
||||
from SocketServer import ThreadingMixIn
|
||||
import os
|
||||
|
||||
PORT = 5000
|
||||
|
||||
web_dir = os.path.join(os.path.dirname(__file__))
|
||||
os.chdir(web_dir)
|
||||
|
||||
Handler = SimpleHTTPRequestHandler
|
||||
|
||||
|
||||
class MaintenanceServer(ThreadingMixIn, HTTPServer):
|
||||
"""Handle requests in a separate thread."""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
httpd = MaintenanceServer(("0.0.0.0", PORT), Handler)
|
||||
print("Starting maintenance mode")
|
||||
httpd.serve_forever()
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import psycopg2
|
||||
import urllib2
|
||||
import re
|
||||
|
||||
import time
|
||||
|
||||
ckan_ini = os.environ.get('CKAN_INI', '/srv/app/production.ini')
|
||||
|
||||
RETRY = 5
|
||||
|
||||
def check_db_connection(retry=None):
|
||||
|
||||
print('[prerun] Start check_db_connection...')
|
||||
|
||||
if retry is None:
|
||||
retry = RETRY
|
||||
elif retry == 0:
|
||||
print('[prerun] Giving up after 5 tries...')
|
||||
sys.exit(1)
|
||||
|
||||
conn_str = os.environ.get('CKAN_SQLALCHEMY_URL', '')
|
||||
try:
|
||||
connection = psycopg2.connect(conn_str)
|
||||
|
||||
except psycopg2.Error as e:
|
||||
print((str(e)))
|
||||
print('[prerun] Unable to connect to the database...try again in a while.')
|
||||
import time
|
||||
time.sleep(10)
|
||||
check_db_connection(retry = retry - 1)
|
||||
else:
|
||||
connection.close()
|
||||
|
||||
def check_solr_connection(retry=None):
|
||||
|
||||
print('[prerun] Start check_solr_connection...')
|
||||
|
||||
if retry is None:
|
||||
retry = RETRY
|
||||
elif retry == 0:
|
||||
print('[prerun] Giving up after 5 tries...')
|
||||
sys.exit(1)
|
||||
|
||||
url = os.environ.get('CKAN_SOLR_URL', '')
|
||||
search_url = '{url}/select/?q=*&wt=json'.format(url=url)
|
||||
|
||||
try:
|
||||
connection = urllib2.urlopen(search_url)
|
||||
except urllib2.URLError as e:
|
||||
print('[prerun] Unable to connect to solr...try again in a while.')
|
||||
import time
|
||||
time.sleep(10)
|
||||
check_solr_connection(retry = retry - 1)
|
||||
else:
|
||||
import re
|
||||
conn_info = connection.read()
|
||||
# SolrCloud
|
||||
conn_info = re.sub(r'"zkConnected":true', '"zkConnected":True', conn_info)
|
||||
eval(conn_info)
|
||||
|
||||
def init_db():
|
||||
|
||||
print('[prerun] Start init_db...')
|
||||
|
||||
db_command = ['paster', '--plugin=ckan', 'db', 'init', '-c', ckan_ini]
|
||||
|
||||
print('[prerun] Initializing or upgrading db - start using paster db init')
|
||||
try:
|
||||
# run init scripts
|
||||
subprocess.check_output(db_command, stderr=subprocess.STDOUT)
|
||||
|
||||
print('[prerun] Initializing or upgrading db - end')
|
||||
except subprocess.CalledProcessError as e:
|
||||
if 'OperationalError' in e.output:
|
||||
print('[prerun] Database not ready, waiting a bit before exit...')
|
||||
import time
|
||||
time.sleep(5)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print((e.output))
|
||||
raise e
|
||||
print('[prerun] Initializing or upgrading db - finish')
|
||||
|
||||
|
||||
def init_datastore():
|
||||
|
||||
conn_str = os.environ.get('CKAN_DATASTORE_WRITE_URL')
|
||||
if not conn_str:
|
||||
print('[prerun] Skipping datastore initialization')
|
||||
return
|
||||
|
||||
datastore_perms_command = ['paster', '--plugin=ckan', 'datastore',
|
||||
'set-permissions', '-c', ckan_ini]
|
||||
|
||||
connection = psycopg2.connect(conn_str)
|
||||
cursor = connection.cursor()
|
||||
|
||||
print('[prerun] Initializing datastore db - start')
|
||||
try:
|
||||
datastore_perms = subprocess.Popen(
|
||||
datastore_perms_command,
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
perms_sql = datastore_perms.stdout.read()
|
||||
# Remove internal pg command as psycopg2 does not like it
|
||||
perms_sql = re.sub('\\\\connect \"(.*)\"', '', perms_sql.decode('utf-8'))
|
||||
cursor.execute(perms_sql)
|
||||
for notice in connection.notices:
|
||||
print(notice)
|
||||
|
||||
connection.commit()
|
||||
|
||||
print('[prerun] Initializing datastore db - end')
|
||||
print((datastore_perms.stdout.read()))
|
||||
except psycopg2.Error as e:
|
||||
print('[prerun] Could not initialize datastore')
|
||||
print((str(e)))
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
if 'OperationalError' in e.output:
|
||||
print((e.output))
|
||||
print('[prerun] Database not ready, waiting a bit before exit...')
|
||||
time.sleep(5)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print((e.output))
|
||||
raise e
|
||||
finally:
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
|
||||
def create_sysadmin():
|
||||
|
||||
print('[prerun] Start create_sysadmin...')
|
||||
|
||||
name = os.environ.get('CKAN_SYSADMIN_NAME')
|
||||
password = os.environ.get('CKAN_SYSADMIN_PASSWORD')
|
||||
email = os.environ.get('CKAN_SYSADMIN_EMAIL')
|
||||
|
||||
if name and password and email:
|
||||
|
||||
# Check if user exists
|
||||
command = ['paster', '--plugin=ckan', 'user', name, '-c', ckan_ini]
|
||||
|
||||
out = subprocess.check_output(command)
|
||||
if 'User:None' not in re.sub(r'\s', '', out.decode('utf-8')):
|
||||
print('[prerun] Sysadmin user exists, skipping creation')
|
||||
return
|
||||
|
||||
# Create user
|
||||
command = ['paster', '--plugin=ckan', 'user', 'add',
|
||||
name,
|
||||
'password=' + password,
|
||||
'email=' + email,
|
||||
'-c', ckan_ini]
|
||||
|
||||
subprocess.call(command)
|
||||
print(('[prerun] Created user {0}'.format(name)))
|
||||
|
||||
# Make it sysadmin
|
||||
command = ['paster', '--plugin=ckan', 'sysadmin', 'add',
|
||||
name,
|
||||
'-c', ckan_ini]
|
||||
|
||||
subprocess.call(command)
|
||||
print(('[prerun] Made user {0} a sysadmin'.format(name)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
maintenance = os.environ.get('MAINTENANCE_MODE', '').lower() == 'true'
|
||||
|
||||
if maintenance:
|
||||
print('[prerun] Maintenance mode, skipping setup...')
|
||||
else:
|
||||
check_db_connection()
|
||||
check_solr_connection()
|
||||
init_db()
|
||||
if os.environ.get('CKAN_DATASTORE_WRITE_URL'):
|
||||
init_datastore()
|
||||
create_sysadmin()
|
|
@ -1,74 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Run any startup scripts provided by images extending this one
|
||||
if [[ -d "${APP_DIR}/docker-entrypoint.d" ]]
|
||||
then
|
||||
for f in ${APP_DIR}/docker-entrypoint.d/*; do
|
||||
case "$f" in
|
||||
*.sh) echo "$0: Running init file $f"; . "$f" ;;
|
||||
*.py) echo "$0: Running init file $f"; python "$f"; echo ;;
|
||||
*) echo "$0: Ignoring $f (not an sh or py file)" ;;
|
||||
esac
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
# Add session secret from chart
|
||||
if [[ -z $BEAKER_SESSION_SECRET || -v $BEAKER_SESSION_SECRET ]];then
|
||||
echo "Not all environment variables are set. Generating sessions..."
|
||||
else
|
||||
echo "Setting session secrets from environment variables"
|
||||
paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$BEAKER_SESSION_SECRET"
|
||||
fi
|
||||
|
||||
if grep -E "beaker.session.secret ?= ?$" $APP_DIR/production.ini
|
||||
then
|
||||
echo "Setting beaker.session.secret in ini file"
|
||||
paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$(python -c 'import secrets; print(secrets.token_urlsafe())')"
|
||||
fi
|
||||
|
||||
# Set the common uwsgi options
|
||||
echo "Starting UWSGI with '${UWSGI_PROC_NO:-2}' workers"
|
||||
|
||||
UWSGI_OPTS="--socket /tmp/uwsgi.sock --uid 92 --gid 92 --http :5000 --master --enable-threads --paste config:/srv/app/production.ini --paste-logger /srv/app/production.ini --lazy-apps --gevent 2000 -p ${UWSGI_PROC_NO:-2} -L --gevent-early-monkey-patch"
|
||||
|
||||
# Run the prerun script to init CKAN and create the default admin user
|
||||
python prerun.py || { echo '[CKAN prerun] FAILED. Exiting...' ; exit 1; }
|
||||
|
||||
# Check if we are in maintenance mode and if yes serve the maintenance pages
|
||||
if [ "$MAINTENANCE_MODE" = true ]; then PYTHONUNBUFFERED=1 python maintenance/serve.py; fi
|
||||
|
||||
# Run any after prerun/init scripts provided by images extending this one
|
||||
if [[ -d "${APP_DIR}/docker-afterinit.d" ]]
|
||||
then
|
||||
for f in ${APP_DIR}/docker-afterinit.d/*; do
|
||||
case "$f" in
|
||||
*.sh) echo "$0: Running after prerun init file $f"; . "$f" ;;
|
||||
*.py) echo "$0: Running after prerun init file $f"; python "$f"; echo ;;
|
||||
*) echo "$0: Ignoring $f (not an sh or py file)" ;;
|
||||
esac
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
if [ "$PASSWORD_PROTECT" = true ]
|
||||
then
|
||||
if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ]
|
||||
then
|
||||
# Generate htpasswd file for basicauth
|
||||
htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD
|
||||
# Start uwsgi with basicauth
|
||||
uwsgi --ini /srv/app/uwsgi.conf --pcre-jit $UWSGI_OPTS
|
||||
else
|
||||
echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Start uwsgi
|
||||
uwsgi $UWSGI_OPTS
|
||||
fi
|
||||
else
|
||||
echo "[prerun] failed...not starting CKAN."
|
||||
fi
|
|
@ -1,2 +0,0 @@
|
|||
[uwsgi]
|
||||
route = ^(?!/api).*$ basicauth:Restricted,/srv/app/.htpasswd
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
# CKAN <2.9 uses paster and the ckan plugin for paster which expects the configuration to be passed
|
||||
# to a subcommand, example: paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions
|
||||
# CKAN >2.9 ckan CLI command expects the configuration option as the second and third parameter
|
||||
# Example: ckan -c /srv/app/production.ini datastore set-permissions
|
||||
#
|
||||
# Shift three arguments so that we can reorder the argument list
|
||||
# ckan -c /srv/app/production.ini datastore set-permissions
|
||||
# becomes
|
||||
# paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions
|
||||
config_switch=$1
|
||||
config_file=$2
|
||||
subcommand=$3
|
||||
shift 3
|
||||
paster --plugin=ckan "$subcommand" "$config_switch" "$config_file" "$@"
|
|
@ -1,203 +0,0 @@
|
|||
##################
|
||||
### Build CKAN ###
|
||||
##################
|
||||
FROM alpine:3.13.7 as ckanbuild
|
||||
|
||||
# Used by Github Actions to tag the image with
|
||||
ENV IMAGE_TAG=2.9.11
|
||||
|
||||
# Set CKAN version to build
|
||||
ENV GIT_URL=https://github.com/ckan/ckan.git
|
||||
ENV GIT_BRANCH=ckan-2.9.11
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
WORKDIR ${SRC_DIR}
|
||||
|
||||
# Packages to build CKAN requirements and plugins
|
||||
RUN apk add --no-cache \
|
||||
python3 \
|
||||
python3-dev \
|
||||
git \
|
||||
curl \
|
||||
postgresql-dev \
|
||||
linux-headers \
|
||||
gcc \
|
||||
make \
|
||||
g++ \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
patch \
|
||||
musl-dev \
|
||||
pcre-dev \
|
||||
pcre \
|
||||
libffi-dev \
|
||||
libxml2-dev \
|
||||
libxslt-dev
|
||||
|
||||
# Link python to python3
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py
|
||||
|
||||
# Downgrade setuptools so that CKAN requirements can be built
|
||||
RUN pip install setuptools==44.1.0
|
||||
|
||||
# Fetch and build CKAN and requirements
|
||||
RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan
|
||||
# Copy patches and apply patches script
|
||||
COPY ./patches ${SRC_DIR}/patches
|
||||
COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh
|
||||
# Apply patches
|
||||
RUN cd ${SRC_DIR} && ls -lah ${SRC_DIR} && ash ${SRC_DIR}/apply_ckan_patches.sh
|
||||
RUN rm -rf /srv/app/src/ckan/.git
|
||||
|
||||
# Create a constraint file that limits the Cython version to a compatible one, see https://github.com/yaml/pyyaml/issues/736
|
||||
RUN echo 'Cython < 3.0' > /tmp/constraint.txt
|
||||
RUN PIP_CONSTRAINT=/tmp/constraint.txt pip wheel --wheel-dir=/wheels PyYAML==5.4.1
|
||||
|
||||
# RUN pip-compile ckan/requirements.in
|
||||
RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt
|
||||
RUN pip wheel --wheel-dir=/wheels uWSGI==2.0.20 gevent==21.12.0 greenlet==1.1.3
|
||||
|
||||
###########################
|
||||
### Default-Extensions ####
|
||||
###########################
|
||||
FROM alpine:3.13.7 as extbuild
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
# List of default extensions
|
||||
ENV DEFAULT_EXTENSIONS envvars
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars
|
||||
ENV ENVVARS_GIT_BRANCH=0.0.1
|
||||
|
||||
RUN apk add --no-cache \
|
||||
python3 \
|
||||
python3-dev \
|
||||
git \
|
||||
curl
|
||||
|
||||
# Link python to python3
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py
|
||||
|
||||
# Fetch and build the default CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM alpine:3.13.7
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/keitaroinc/docker-ckan
|
||||
|
||||
ENV APP_DIR=/srv/app
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV CKAN_DIR=${SRC_DIR}/ckan
|
||||
ENV DATA_DIR=/srv/app/data
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
ENV CKAN_SITE_URL=http://localhost:5000
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher
|
||||
|
||||
# Install necessary packages to run CKAN
|
||||
RUN apk add --no-cache \
|
||||
python3 \
|
||||
bash \
|
||||
git \
|
||||
gettext \
|
||||
curl \
|
||||
postgresql-client \
|
||||
libmagic \
|
||||
pcre \
|
||||
libxslt \
|
||||
libxml2 \
|
||||
tzdata \
|
||||
apache2-utils && \
|
||||
# Create SRC_DIR
|
||||
mkdir -p ${SRC_DIR} && \
|
||||
# Link python to python3
|
||||
ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py
|
||||
|
||||
# Get artifacts from build stages
|
||||
COPY --from=ckanbuild /wheels /srv/app/wheels
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
COPY --from=ckanbuild /srv/app/src/ckan ${CKAN_DIR}
|
||||
|
||||
# Additional install steps for build stages artifacts
|
||||
RUN pip install --no-index --find-links=/srv/app/wheels uWSGI==2.0.20 gevent==21.12.0
|
||||
|
||||
# Create a local user and group to run the app
|
||||
RUN addgroup -g 92 -S ckan && \
|
||||
adduser -u 92 -h /srv/app -H -D -S -G ckan ckan
|
||||
|
||||
WORKDIR ${CKAN_DIR}
|
||||
|
||||
# Install CKAN
|
||||
RUN pip install -e /srv/app/src/ckan && \
|
||||
cp who.ini ${APP_DIR} && \
|
||||
pip install --no-index --find-links=/srv/app/wheels -r requirements.txt && \
|
||||
# Install default CKAN extensions
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels ckanext-envvars && \
|
||||
# Create and update CKAN config
|
||||
# Set timezone
|
||||
echo "UTC" > /etc/timezone && \
|
||||
# Generate CKAN config
|
||||
ckan generate config ${APP_DIR}/production.ini && \
|
||||
ckan config-tool ${APP_DIR}/production.ini "beaker.session.secret = " && \
|
||||
# Configure plugins
|
||||
ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
# Create the data directory
|
||||
mkdir ${DATA_DIR} && \
|
||||
# Webassets can't be loaded from env variables at runtime, it needs to be in the config so that it is created
|
||||
ckan config-tool ${APP_DIR}/production.ini "ckan.webassets.path = ${DATA_DIR}/webassets" && \
|
||||
# Set the default level for extensions to INFO
|
||||
ckan config-tool ${APP_DIR}/production.ini -s logger_ckanext -e level=INFO && \
|
||||
# Change ownership to app user
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
RUN pip install sqlalchemy==1.3.19
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/wheels /srv/app/ext_wheels
|
||||
|
||||
# Copy necessary scripts
|
||||
COPY setup/app ${APP_DIR}
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Create entrypoint directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-entrypoint.d
|
||||
|
||||
# Create afterinit directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-afterinit.d
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1
|
||||
|
||||
USER ckan
|
||||
|
||||
CMD ["/srv/app/start_ckan.sh"]
|
|
@ -1,244 +0,0 @@
|
|||
##################
|
||||
### Build CKAN ###
|
||||
##################
|
||||
FROM ubuntu:focal-20210827 as ckanbuild
|
||||
|
||||
# Used by Github Actions to tag the image with
|
||||
ENV IMAGE_TAG=2.9.11-focal
|
||||
|
||||
# Set CKAN version to build
|
||||
ENV GIT_URL=https://github.com/ckan/ckan.git
|
||||
ENV GIT_BRANCH=ckan-2.9.11
|
||||
|
||||
# Set timezone
|
||||
ENV TZ=UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Set Locale
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
WORKDIR ${SRC_DIR}
|
||||
|
||||
# Set the locale
|
||||
RUN apt-get update
|
||||
RUN apt-get install --no-install-recommends -y locales
|
||||
RUN sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen
|
||||
RUN dpkg-reconfigure --frontend=noninteractive locales
|
||||
RUN update-locale LANG=${LC_ALL}
|
||||
|
||||
# Instal apt-utils
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
apt-utils
|
||||
|
||||
# Packages to build CKAN requirements and plugins
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
libpq-dev \
|
||||
linux-headers-generic \
|
||||
gcc-10 \
|
||||
make \
|
||||
g++-10 \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
patch \
|
||||
libpcre3-dev \
|
||||
libpcre3 \
|
||||
python3-dev \
|
||||
libffi-dev \
|
||||
libxml2-dev \
|
||||
libxslt-dev
|
||||
|
||||
# Use gcc 10
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 --slave /usr/bin/gcov gcov /usr/bin/gcov-10 --slave /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/x86_64-linux-gnu-gcc-10
|
||||
|
||||
# Link python to python3
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py
|
||||
|
||||
# Downgrade setuptools so that CKAN requirements can be built
|
||||
RUN pip install setuptools==44.1.0
|
||||
|
||||
# Fetch and build CKAN and requirements
|
||||
RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan
|
||||
# Copy patches and apply patches script
|
||||
COPY ./patches ${SRC_DIR}/patches
|
||||
COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh
|
||||
# Apply patches
|
||||
RUN ${SRC_DIR}/apply_ckan_patches.sh
|
||||
RUN rm -rf /srv/app/src/ckan/.git
|
||||
RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt
|
||||
RUN pip wheel --wheel-dir=/wheels uWSGI==2.0.20 gevent==21.12.0 greenlet==1.1.3
|
||||
|
||||
|
||||
###########################
|
||||
### Default-Extensions ####
|
||||
###########################
|
||||
FROM ubuntu:focal-20210827 as extbuild
|
||||
|
||||
# Set src dirs
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
|
||||
# List of default extensions
|
||||
ENV DEFAULT_EXTENSIONS envvars
|
||||
|
||||
# Locations and tags, please use specific tags or revisions
|
||||
ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars
|
||||
ENV ENVVARS_GIT_BRANCH=0.0.1
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
python3-dev
|
||||
|
||||
# Link python to python3
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# Create the src directory
|
||||
RUN mkdir -p ${SRC_DIR}
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py
|
||||
|
||||
# Downgrade setuptools so that CKAN requirements can be built
|
||||
RUN pip install setuptools==44.1.0
|
||||
|
||||
# Fetch and build the default CKAN extensions
|
||||
RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars
|
||||
|
||||
############
|
||||
### MAIN ###
|
||||
############
|
||||
FROM ubuntu:focal-20210827
|
||||
|
||||
LABEL maintainer="Keitaro Inc <info@keitaro.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/keitaroinc/docker-ckan
|
||||
|
||||
# Set timezone
|
||||
ENV TZ=UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Set Locale
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
# Set the locale
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y locales && \
|
||||
sed -i "/$LC_ALL/s/^# //g" /etc/locale.gen && \
|
||||
dpkg-reconfigure --frontend=noninteractive locales && \
|
||||
update-locale LANG=${LC_ALL} && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV APP_DIR=/srv/app
|
||||
ENV SRC_DIR=/srv/app/src
|
||||
ENV CKAN_DIR=${SRC_DIR}/ckan
|
||||
ENV DATA_DIR=/srv/app/data
|
||||
ENV PIP_SRC=${SRC_DIR}
|
||||
ENV CKAN_SITE_URL=http://localhost:5000
|
||||
ENV CKAN__PLUGINS envvars image_view text_view recline_view datastore datapusher
|
||||
|
||||
# Install necessary packages to run CKAN
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
gettext \
|
||||
curl \
|
||||
ca-certificates \
|
||||
libpq5 \
|
||||
git \
|
||||
postgresql-client \
|
||||
python3 \
|
||||
python3-distutils \
|
||||
libpython3.8 \
|
||||
libmagic1 \
|
||||
libpcre3 \
|
||||
libxslt1.1 \
|
||||
libxml2 \
|
||||
tzdata \
|
||||
apache2-utils && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
# Create SRC_DIR
|
||||
mkdir -p ${SRC_DIR} && \
|
||||
# Link python to python3
|
||||
ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# Install pip
|
||||
RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \
|
||||
python ${SRC_DIR}/get-pip.py
|
||||
|
||||
# Downgrade setuptools so that CKAN requirements can be built
|
||||
RUN pip install setuptools==44.1.0
|
||||
|
||||
# Get artifacts from build stages
|
||||
COPY --from=ckanbuild /wheels /srv/app/wheels
|
||||
COPY --from=extbuild /wheels /srv/app/ext_wheels
|
||||
COPY --from=ckanbuild /srv/app/src/ckan ${CKAN_DIR}
|
||||
|
||||
# Additional install steps for build stages artifacts
|
||||
RUN pip install --no-index --find-links=/srv/app/wheels uWSGI==2.0.20 gevent==21.12.0
|
||||
|
||||
# Create a local user and group to run the app
|
||||
RUN groupadd -g 92 ckan && \
|
||||
useradd -rm -d /srv/app -s /bin/bash -g ckan -u 92 ckan
|
||||
|
||||
WORKDIR ${CKAN_DIR}
|
||||
|
||||
# Install CKAN
|
||||
RUN pip install -e /srv/app/src/ckan && \
|
||||
cp who.ini ${APP_DIR} && \
|
||||
pip install --no-index --find-links=/srv/app/wheels -r requirements.txt && \
|
||||
# Install default CKAN extensions
|
||||
pip install --no-index --find-links=/srv/app/ext_wheels ckanext-envvars && \
|
||||
# Create and update CKAN config
|
||||
# Generate CKAN config
|
||||
ckan generate config ${APP_DIR}/production.ini && \
|
||||
# Configure plugins
|
||||
ckan config-tool ${APP_DIR}/production.ini "beaker.session.secret = " && \
|
||||
ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \
|
||||
# Create the data directory
|
||||
mkdir ${DATA_DIR} && \
|
||||
# Webassets can't be loaded from env variables at runtime, it needs to be in the config so that it is created
|
||||
ckan config-tool ${APP_DIR}/production.ini "ckan.webassets.path = ${DATA_DIR}/webassets" && \
|
||||
# Set the default level for extensions to INFO
|
||||
ckan config-tool ${APP_DIR}/production.ini -s logger_ckanext -e level=INFO && \
|
||||
# Change ownership to app user
|
||||
chown -R ckan:ckan /srv/app
|
||||
|
||||
# Remove wheels
|
||||
RUN rm -rf /srv/app/wheels /srv/app/ext_wheels
|
||||
|
||||
# Copy necessary scripts
|
||||
COPY setup/app ${APP_DIR}
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
# Create entrypoint directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-entrypoint.d
|
||||
|
||||
# Create afterinit directory for children image scripts
|
||||
ONBUILD RUN mkdir docker-afterinit.d
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1
|
||||
|
||||
USER ckan
|
||||
|
||||
CMD ["/srv/app/start_ckan.sh"]
|
|
@ -1,11 +0,0 @@
|
|||
--- ckan/ckan/model/__init__.py
|
||||
+++ ckan/ckan/model/__init__.py
|
||||
@@ -276,7 +276,7 @@ class Repository():
|
||||
self.reset_alembic_output()
|
||||
alembic_config = AlembicConfig(self._alembic_ini)
|
||||
alembic_config.set_main_option(
|
||||
- "sqlalchemy.url", config.get("sqlalchemy.url")
|
||||
+ "sqlalchemy.url", config.get("sqlalchemy.url").replace('%', '%%')
|
||||
)
|
||||
try:
|
||||
sqlalchemy_migrate_version = self.metadata.bind.execute(
|
|
@ -1,11 +0,0 @@
|
|||
--- ckan/ckanext/datastore/backend/postgres.py
|
||||
+++ ckan/ckanext/datastore/backend/postgres.py
|
||||
@@ -1809,7 +1809,7 @@ class DatastorePostgresqlBackend(DatastoreBackend):
|
||||
read only user.
|
||||
'''
|
||||
write_connection = self._get_write_engine().connect()
|
||||
- read_connection_user = sa_url.make_url(self.read_url).username
|
||||
+ read_connection_user = sa_url.make_url(self.read_url).username.split("@")[0]
|
||||
|
||||
drop_foo_sql = u'DROP TABLE IF EXISTS _foo'
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
shopt -s nullglob
|
||||
for patch in patches/*.patch; do
|
||||
/usr/bin/patch -p0 -i $patch
|
||||
done
|
|
@ -1,39 +0,0 @@
|
|||
[uwsgi]
|
||||
route = ^(?!/api).*$ basicauth:Restricted,/srv/app/.htpasswd
|
||||
|
||||
socket = /tmp/uwsgi.sock
|
||||
uid = ckan
|
||||
gid = ckan
|
||||
http = :5000
|
||||
|
||||
master = true
|
||||
enable-threads = true
|
||||
lazy-apps = true
|
||||
gevent-early-monkey-patch = true
|
||||
vacuum = true
|
||||
single-interpreter= true
|
||||
die-on-term = true
|
||||
need-app = true
|
||||
auto-procname = true
|
||||
|
||||
wsgi-file = /srv/app/wsgi.py
|
||||
module = wsgi:application
|
||||
gevent = 2000
|
||||
callable = application
|
||||
paste = config:/srv/app/production.ini
|
||||
paste-logger = /srv/app/production.ini
|
||||
|
||||
post-buffering = 1
|
||||
buffer-size= 12288
|
||||
max-requests = 3000
|
||||
max-worker-lifetime = 3600
|
||||
reload-on-rss = 4096
|
||||
worker-reload-mercy = 60
|
||||
socket-timeout = 300
|
||||
queue = 1000
|
||||
queue-blocksize = 204800
|
||||
static-gzip-all = true
|
||||
listen = 1000
|
||||
http-timeout = 1000
|
||||
http-headers-timeout = 1000
|
||||
http-connect-timeout = 1000
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# this is called before uwsgi is executed
|
||||
# uset his to add extra scripts before ckan is started
|
|
@ -1,25 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Maintenance</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Maintenance</h1>
|
||||
<p>Our data portal is currently in maintenance, please try in a while.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Maintenance</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Maintenance</h1>
|
||||
<p>Our data portal is currently in maintenance, please try in a while.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,35 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler
|
||||
import os
|
||||
|
||||
PORT = 5000
|
||||
|
||||
web_dir = os.path.join(os.path.dirname(__file__))
|
||||
os.chdir(web_dir)
|
||||
|
||||
|
||||
def run(server_class=ThreadingHTTPServer, handler_class=SimpleHTTPRequestHandler):
|
||||
server_address = ("0.0.0.0", PORT)
|
||||
httpd = server_class(server_address, handler_class)
|
||||
print("Starting maintenance mode")
|
||||
httpd.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from multiprocessing import connection
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import psycopg2
|
||||
from sqlalchemy.engine.url import make_url
|
||||
import urllib.request, urllib.error, urllib.parse, base64
|
||||
import re
|
||||
import json
|
||||
|
||||
import time
|
||||
|
||||
ckan_ini = os.environ.get('CKAN_INI', '/srv/app/production.ini')
|
||||
|
||||
RETRY = 5
|
||||
|
||||
def check_db_connection(retry=None):
|
||||
|
||||
print('[prerun] Start check_db_connection...')
|
||||
|
||||
if retry is None:
|
||||
retry = RETRY
|
||||
elif retry == 0:
|
||||
print('[prerun] Giving up after 5 tries...')
|
||||
sys.exit(1)
|
||||
|
||||
conn_str = os.environ.get('CKAN_SQLALCHEMY_URL', '')
|
||||
try:
|
||||
db_user = make_url(conn_str).username
|
||||
db_passwd = make_url(conn_str).password
|
||||
db_host = make_url(conn_str).host
|
||||
db_name = make_url(conn_str).database
|
||||
connection = psycopg2.connect(user=db_user,
|
||||
host=db_host,
|
||||
password=db_passwd,
|
||||
database=db_name)
|
||||
|
||||
except psycopg2.Error as e:
|
||||
print((str(e)))
|
||||
print('[prerun] Unable to connect to the database...try again in a while.')
|
||||
import time
|
||||
time.sleep(10)
|
||||
check_db_connection(retry = retry - 1)
|
||||
else:
|
||||
connection.close()
|
||||
|
||||
def check_solr_connection(retry=None):
|
||||
|
||||
print('[prerun] Start check_solr_connection...')
|
||||
|
||||
if retry is None:
|
||||
retry = RETRY
|
||||
elif retry == 0:
|
||||
print('[prerun] Giving up after 5 tries...')
|
||||
sys.exit(1)
|
||||
|
||||
url = os.environ.get('CKAN_SOLR_URL', '')
|
||||
username = os.environ.get('CKAN_SOLR_USER', '')
|
||||
password = os.environ.get('CKAN_SOLR_PASSWORD', '')
|
||||
search_url = '{url}/schema/name?wt=json'.format(url=url)
|
||||
|
||||
|
||||
|
||||
try:
|
||||
if not username:
|
||||
connection = urllib.request.urlopen(search_url)
|
||||
else:
|
||||
request = urllib.request.Request(search_url)
|
||||
base64string = base64.b64encode(bytes('%s:%s' % (username, password),'ascii'))
|
||||
request.add_header("Authorization", "Basic %s" % base64string.decode('utf-8'))
|
||||
connection = urllib.request.urlopen(request)
|
||||
except urllib.error.URLError as e:
|
||||
print('[prerun] Unable to connect to solr...try again in a while.')
|
||||
import time
|
||||
time.sleep(10)
|
||||
check_solr_connection(retry = retry - 1)
|
||||
else:
|
||||
import re
|
||||
conn_info = connection.read()
|
||||
schema_name = json.loads(conn_info)
|
||||
if 'ckan' in schema_name['name']:
|
||||
print('[prerun] Succesfully connected to solr and CKAN schema loaded')
|
||||
else:
|
||||
print('[prerun] Succesfully connected to solr, but CKAN schema not found')
|
||||
sys.exit(1)
|
||||
|
||||
def init_db():
|
||||
|
||||
print('[prerun] Start init_db...')
|
||||
|
||||
db_command = ['ckan', '-c', ckan_ini, 'db', 'init']
|
||||
|
||||
print('[prerun] Initializing or upgrading db - start using ckan db init')
|
||||
try:
|
||||
# run init scripts
|
||||
subprocess.check_output(db_command, stderr=subprocess.STDOUT)
|
||||
|
||||
print('[prerun] Initializing or upgrading db - end')
|
||||
except subprocess.CalledProcessError as e:
|
||||
if 'OperationalError' in str(e.output):
|
||||
print(e.output.decode('utf-8'))
|
||||
print('[prerun] Database not ready, waiting a bit before exit...')
|
||||
import time
|
||||
time.sleep(5)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print(e.output.decode('utf-8'))
|
||||
raise e
|
||||
print('[prerun] Initializing or upgrading db - finish')
|
||||
|
||||
|
||||
def init_datastore():
|
||||
|
||||
conn_str = os.environ.get('CKAN_DATASTORE_WRITE_URL')
|
||||
if not conn_str:
|
||||
print('[prerun] Skipping datastore initialization')
|
||||
return
|
||||
|
||||
datastore_perms_command = ['ckan', '-c', ckan_ini, 'datastore',
|
||||
'set-permissions']
|
||||
|
||||
db_user = make_url(conn_str).username
|
||||
db_passwd = make_url(conn_str).password
|
||||
db_host = make_url(conn_str).host
|
||||
db_name = make_url(conn_str).database
|
||||
connection = psycopg2.connect(user=db_user,
|
||||
host=db_host,
|
||||
password=db_passwd,
|
||||
database=db_name)
|
||||
cursor = connection.cursor()
|
||||
|
||||
print('[prerun] Initializing datastore db - start')
|
||||
try:
|
||||
datastore_perms = subprocess.Popen(
|
||||
datastore_perms_command,
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
perms_sql = datastore_perms.stdout.read()
|
||||
perms_sql = perms_sql.decode('utf-8')
|
||||
perms_sql = perms_sql.replace("@"+db_host, "")
|
||||
# Remove internal pg command as psycopg2 does not like it
|
||||
perms_sql = re.sub('\\\\connect \"(.*)\"', '', perms_sql)
|
||||
cursor.execute(perms_sql)
|
||||
for notice in connection.notices:
|
||||
print(notice)
|
||||
|
||||
connection.commit()
|
||||
|
||||
print('[prerun] Initializing datastore db - end')
|
||||
print((datastore_perms.stdout.read()))
|
||||
except psycopg2.Error as e:
|
||||
print('[prerun] Could not initialize datastore')
|
||||
print(e.decode('utf-8'))
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
if 'OperationalError' in str(e.output):
|
||||
print(e.output.decode('utf-8'))
|
||||
print('[prerun] Database not ready, waiting a bit before exit...')
|
||||
time.sleep(5)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print(e.output.decode('utf-8'))
|
||||
raise e
|
||||
finally:
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
|
||||
def create_sysadmin():
|
||||
|
||||
print('[prerun] Start create_sysadmin...')
|
||||
|
||||
name = os.environ.get('CKAN_SYSADMIN_NAME')
|
||||
password = os.environ.get('CKAN_SYSADMIN_PASSWORD')
|
||||
email = os.environ.get('CKAN_SYSADMIN_EMAIL')
|
||||
|
||||
if name and password and email:
|
||||
|
||||
# Check if user exists
|
||||
command = ['ckan', '-c', ckan_ini, 'user', 'show', name]
|
||||
|
||||
out = subprocess.check_output(command)
|
||||
if 'User:None' not in re.sub(r'\s', '', out.decode('utf-8')):
|
||||
print('[prerun] Sysadmin user exists, skipping creation')
|
||||
return
|
||||
|
||||
# Create user
|
||||
command = ['ckan', '-c', ckan_ini, 'user', 'add',
|
||||
name,
|
||||
'password=' + password,
|
||||
'email=' + email]
|
||||
|
||||
subprocess.call(command)
|
||||
print(('[prerun] Created user {0}'.format(name)))
|
||||
|
||||
# Make it sysadmin
|
||||
command = ['ckan', '-c', ckan_ini, 'sysadmin', 'add',
|
||||
name]
|
||||
|
||||
subprocess.call(command)
|
||||
print(('[prerun] Made user {0} a sysadmin'.format(name)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
maintenance = os.environ.get('MAINTENANCE_MODE', '').lower() == 'true'
|
||||
|
||||
if maintenance:
|
||||
print('[prerun] Maintenance mode, skipping setup...')
|
||||
else:
|
||||
check_db_connection()
|
||||
check_solr_connection()
|
||||
init_db()
|
||||
if os.environ.get('CKAN_DATASTORE_WRITE_URL'):
|
||||
init_datastore()
|
||||
create_sysadmin()
|
|
@ -1,76 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Run any startup scripts provided by images extending this one
|
||||
if [[ -d "${APP_DIR}/docker-entrypoint.d" ]]
|
||||
then
|
||||
for f in ${APP_DIR}/docker-entrypoint.d/*; do
|
||||
case "$f" in
|
||||
*.sh) echo "$0: Running init file $f"; . "$f" ;;
|
||||
*.py) echo "$0: Running init file $f"; python "$f"; echo ;;
|
||||
*) echo "$0: Ignoring $f (not an sh or py file)" ;;
|
||||
esac
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
# Add session secret from chart
|
||||
if [[ -z $BEAKER_SESSION_SECRET || -v $BEAKER_SESSION_SECRET || -z $JWT_ENCODE_SECRET || -v $JWT_ENCODE_SECRET || -z $JWT_DECODE_SECRET || -v $JWT_DECODE_SECRET ]];then
|
||||
echo "Not all environment variables are set. Generating sessions..."
|
||||
else
|
||||
echo "Setting session secrets from environment variables"
|
||||
ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$BEAKER_SESSION_SECRET"
|
||||
ckan config-tool $APP_DIR/production.ini "api_token.jwt.encode.secret=$JWT_ENCODE_SECRET"
|
||||
ckan config-tool $APP_DIR/production.ini "api_token.jwt.decode.secret=$JWT_DECODE_SECRET"
|
||||
fi
|
||||
|
||||
if grep -E "beaker.session.secret ?= ?$" $APP_DIR/production.ini
|
||||
then
|
||||
echo "Setting secrets in ini file"
|
||||
ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$(python3 -c 'import secrets; print(secrets.token_urlsafe())')"
|
||||
ckan config-tool $APP_DIR/production.ini "WTF_CSRF_SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_urlsafe())')"
|
||||
JWT_SECRET=$(python3 -c 'import secrets; print("string:" + secrets.token_urlsafe())')
|
||||
ckan config-tool $APP_DIR/production.ini "api_token.jwt.encode.secret=$JWT_SECRET"
|
||||
ckan config-tool $APP_DIR/production.ini "api_token.jwt.decode.secret=$JWT_SECRET"
|
||||
fi
|
||||
|
||||
# Run the prerun script to init CKAN and create the default admin user
|
||||
python prerun.py || { echo '[CKAN prerun] FAILED. Exiting...' ; exit 1; }
|
||||
|
||||
# Check if we are in maintenance mode and if yes serve the maintenance pages
|
||||
if [ "$MAINTENANCE_MODE" = true ]; then PYTHONUNBUFFERED=1 python maintenance/serve.py; fi
|
||||
|
||||
# Run any after prerun/init scripts provided by images extending this one
|
||||
if [[ -d "${APP_DIR}/docker-afterinit.d" ]]
|
||||
then
|
||||
for f in ${APP_DIR}/docker-afterinit.d/*; do
|
||||
case "$f" in
|
||||
*.sh) echo "$0: Running after prerun init file $f"; . "$f" ;;
|
||||
*.py) echo "$0: Running after prerun init file $f"; python "$f"; echo ;;
|
||||
*) echo "$0: Ignoring $f (not an sh or py file)" ;;
|
||||
esac
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
if [ "$PASSWORD_PROTECT" = true ]
|
||||
then
|
||||
if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ]
|
||||
then
|
||||
# Generate htpasswd file for basicauth
|
||||
htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD
|
||||
# Start uwsgi with basicauth
|
||||
uwsgi --ini /srv/app/basic-auth-uwsgi.conf -p ${UWSGI_PROC_NO:-2} --pcre-jit
|
||||
else
|
||||
echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Start uwsgi
|
||||
echo "Starting UWSGI with '${UWSGI_PROC_NO:-2}' workers"
|
||||
uwsgi --ini /srv/app/uwsgi.conf -p ${UWSGI_PROC_NO:-2}
|
||||
fi
|
||||
else
|
||||
echo "[prerun] failed...not starting CKAN."
|
||||
fi
|
|
@ -1,37 +0,0 @@
|
|||
[uwsgi]
|
||||
socket = /tmp/uwsgi.sock
|
||||
uid = ckan
|
||||
gid = ckan
|
||||
http = :5000
|
||||
|
||||
master = true
|
||||
enable-threads = true
|
||||
lazy-apps = true
|
||||
gevent-early-monkey-patch = true
|
||||
vacuum = true
|
||||
single-interpreter= true
|
||||
die-on-term = true
|
||||
need-app = true
|
||||
auto-procname = true
|
||||
|
||||
wsgi-file = /srv/app/wsgi.py
|
||||
module = wsgi:application
|
||||
gevent = 2000
|
||||
callable = application
|
||||
paste = config:/srv/app/production.ini
|
||||
paste-logger = /srv/app/production.ini
|
||||
|
||||
post-buffering = 1
|
||||
buffer-size= 12288
|
||||
max-requests = 3000
|
||||
max-worker-lifetime = 3600
|
||||
reload-on-rss = 4096
|
||||
worker-reload-mercy = 60
|
||||
socket-timeout = 300
|
||||
queue = 1000
|
||||
queue-blocksize = 204800
|
||||
static-gzip-all = true
|
||||
listen = 1000
|
||||
http-timeout = 1000
|
||||
http-headers-timeout = 1000
|
||||
http-connect-timeout = 1000
|
|
@ -1,28 +0,0 @@
|
|||
"""
|
||||
Copyright (c) 2016 Keitaro AB
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from ckan.config.middleware import make_app
|
||||
from ckan.cli import CKANConfigLoader
|
||||
from logging.config import fileConfig as loggingFileConfig
|
||||
config_filepath = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), u'production.ini')
|
||||
abspath = os.path.join(os.path.dirname(os.path.abspath(__file__)))
|
||||
loggingFileConfig(config_filepath)
|
||||
config = CKANConfigLoader(config_filepath).get_config()
|
||||
application = make_app(config)
|
Loading…
Reference in New Issue