Skip to content

Commit 10a5add

Browse files
committed
refactor(config): split into base.ini + env.ini + secrets.ini
Config merge order at startup: base.ini < env.ini < secrets.ini - deploy/base.ini: common config (baked into image) - deploy/staging.ini: staging-specific (CI creates ConfigMap) - deploy/production.ini: prod-specific (CI creates ConfigMap) - Entrypoint merges all three into /tmp/production.ini - CI workflow creates ckan-env-config ConfigMap per environment
1 parent e26294d commit 10a5add

6 files changed

Lines changed: 371 additions & 344 deletions

File tree

.github/workflows/build-deploy.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,24 @@ jobs:
108108
echo "${{ secrets.KUBECONFIG_BASE64 }}" | base64 -d > ~/.kube/config
109109
chmod 600 ~/.kube/config
110110
111+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
112+
111113
- name: Deploy to AKS
112114
run: |
115+
# Determine env config file
116+
if [[ "${{ steps.params.outputs.namespace }}" == "adr-p" ]]; then
117+
ENV_CONFIG="deploy/production.ini"
118+
else
119+
ENV_CONFIG="deploy/staging.ini"
120+
fi
121+
122+
# Create/update env ConfigMap
123+
kubectl create configmap ckan-env-config \
124+
--from-file=env.ini=$ENV_CONFIG \
125+
-n ${{ steps.params.outputs.namespace }} \
126+
--dry-run=client -o yaml | kubectl apply -f -
127+
128+
# Update image
113129
kubectl set image deployment/ckan \
114130
ckan=${{ env.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ steps.params.outputs.image_tag }} \
115131
-n ${{ steps.params.outputs.namespace }}

deploy/Dockerfile.prod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ RUN ln -s /usr/lib/adx /usr/lib/ckan
8181

8282
# Copy entrypoint and config files
8383
COPY deploy/ckan-entrypoint-prod.sh /ckan-entrypoint.sh
84-
COPY deploy/production.ini $CKAN_CONFIG/base.ini
84+
COPY deploy/base.ini $CKAN_CONFIG/base.ini
8585
COPY ckan/adx_who.ini $CKAN_CONFIG/who.ini
8686
COPY ckan/ckan_supervisor.conf /etc/supervisor/conf.d/ckan_supervisor.conf
8787
COPY deploy/uwsgi.ini /usr/lib/adx/uwsgi.ini

deploy/base.ini

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
#
2+
# CKAN - Pylons configuration
3+
#
4+
# These are some of the configuration options available for your CKAN
5+
# instance. Check the documentation in 'doc/configuration.rst' or at the
6+
# following URL for a description of what they do and the full list of
7+
# available options:
8+
#
9+
# http://docs.ckan.org/en/latest/maintaining/configuration.html
10+
#
11+
# The %(here)s variable will be replaced with the parent directory of this file
12+
#
13+
14+
[DEFAULT]
15+
16+
# WARNING: *THIS SETTING MUST BE SET TO FALSE ON A PUBLIC ENVIRONMENT*
17+
# With debug mode enabled, a visitor to your site could execute malicious commands.
18+
debug = false
19+
20+
[app:main]
21+
use = egg:ckan
22+
23+
## Development settings
24+
ckan.devserver.host = localhost
25+
ckan.devserver.port = 5000
26+
27+
28+
## CKAN <2.11 Session settings
29+
cache_dir = /tmp/%(ckan.site_id)s/
30+
beaker.session.key = ckan
31+
beaker.session.type = ext:redis
32+
beaker.session.url = redis://redis:6379/3
33+
beaker.session.cookie_expires = 86400
34+
beaker.session.timeout = 86400
35+
# This is the secret token that the beaker library uses to hash the cookie sent
36+
# to the client. `ckan generate config` generates a unique value for this each
37+
# time it generates a config file.
38+
# NOTE: Must be set directly - CKAN 2.11 doesn't support separate secrets.ini loading
39+
beaker.session.secret = ${BEAKER_SESSION_SECRET}
40+
41+
## CKAN >=2.11 Session settings
42+
## Using default cookie session storage until this issue is resolved:
43+
## https://github.com/ckan/ckan/issues/8547
44+
## SESSION_TYPE = redis
45+
## SESSION_COOKIE_NAME = ckan
46+
## SESSION_PERMANENT = true
47+
## PERMANENT_SESSION_LIFETIME = 86400
48+
# The secret token that is used for session management and other security related tasks as well
49+
# NOTE: Must be set directly - CKAN 2.11 doesn't support CKAN__SECRET_KEY env var reliably
50+
SECRET_KEY = ${SECRET_KEY}
51+
52+
# CSRF Protection - enabled by default (WTF_CSRF_ENABLED = True)
53+
# FileUploader in ckanext-unaids sends X-CSRFToken header
54+
55+
# `ckan generate config` generates a unique value for this each time it generates
56+
# a config file.
57+
app_instance_uuid = 853f1fc8-aba1-411e-9071-44e3cdce64dd
58+
59+
# repoze.who config
60+
who.config_file = %(here)s/who.ini
61+
who.log_level = warning
62+
who.log_file = %(cache_dir)s/who_log.ini
63+
# Session timeout (user logged out after period of inactivity, in seconds).
64+
# Inactive by default, so the session doesn't expire.
65+
# who.timeout = 86400
66+
67+
## Database Settings
68+
69+
# PostgreSQL' full-text search parameters
70+
ckan.datastore.default_fts_lang = english
71+
ckan.datastore.default_fts_index_method = gist
72+
73+
74+
## Site Settings
75+
76+
# ckan.site_url = # configured with env CKAN_SITE_URL
77+
# ckan.use_pylons_response_cleanup_middleware = true
78+
79+
## Upload Settings
80+
ckan.upload.user.types = image
81+
ckan.upload.user.mimetypes = image/png image/bmp image/jpeg image/svg+xml
82+
83+
## Authorization Settings
84+
85+
ckan.auth.anon_create_dataset = false
86+
ckan.auth.create_unowned_dataset = false
87+
ckan.auth.create_dataset_if_not_in_organization = false
88+
ckan.auth.user_create_groups = false
89+
ckan.auth.user_create_organizations = false
90+
ckan.auth.user_delete_groups = true
91+
ckan.auth.user_delete_organizations = true
92+
ckan.auth.create_user_via_api = false
93+
ckan.auth.create_user_via_web = true
94+
ckan.auth.roles_that_cascade_to_sub_groups = admin
95+
ckan.auth.public_user_details = true
96+
ckan.auth.public_activity_stream_detail = true
97+
ckan.auth.allow_dataset_collaborators = true
98+
ckan.auth.create_default_api_keys = false
99+
100+
## API Token Settings
101+
api_token.nbytes = 60
102+
# NOTE: string: prefix is required - CKAN treats bare values as filenames
103+
# These must be set directly (CKAN 2.11 doesn't load secrets.ini separately)
104+
api_token.jwt.encode.secret = string:${JWT_SECRET}
105+
api_token.jwt.decode.secret = string:${JWT_SECRET}
106+
api_token.jwt.algorithm = HS256
107+
108+
## API Token: expire_api_token plugin
109+
expire_api_token.default_lifetime = 3600
110+
111+
## Search Settings
112+
113+
ckan.site_id = default
114+
#solr_url = http://127.0.0.1:8983/solr
115+
solr_timeout = 60
116+
117+
118+
## Redis Settings
119+
120+
# URL to your Redis instance, including the database to be used.
121+
# ckan.redis.url = redis://localhost:6379/0 # Fjelltopp sets through ENV VAR
122+
123+
124+
## CORS Settings
125+
126+
# If cors.origin_allow_all is true, all origins are allowed.
127+
# If false, the cors.origin_whitelist is used.
128+
# ckan.cors.origin_allow_all = true
129+
# cors.origin_whitelist is a space separated list of allowed domains.
130+
# ckan.cors.origin_whitelist = http://example1.com http://example2.com
131+
132+
## Cache settings that are set by CKAN core
133+
ckan.cache_enabled = true
134+
ckan.cache_expires = 604800
135+
ckan.static_max_age = 604800
136+
137+
## Plugins Settings
138+
139+
ckanext.emailasusername.auto_generate_username_from_fullname = True
140+
ckanext.emailasusername.require_user_email_input_confirmation = False
141+
142+
# Note: Add ``datastore`` to enable the CKAN DataStore
143+
# Add ``datapusher`` to enable DataPusher
144+
# Add ``resource_proxy`` to enable resorce proxying and get around the
145+
# same origin policy
146+
ckan.plugins = activity unaids fork scheming_datasets blob_storage emailasusername restricted authz_service stats datastore datapusher validation ytp_request pages harvest versions auth saml2auth
147+
148+
149+
# Giftless/LFS server URL - set in env.ini (staging.ini or production.ini)
150+
# ckanext.blob_storage.storage_service_url = (from env.ini)
151+
152+
ckanext.authz_service.jwt_private_key_file = /etc/ckan/jwt-rs256.key
153+
ckanext.authz_service.jwt_public_key_file = /etc/ckan/jwt-rs256.key.pub
154+
155+
# Define which views should be created by default
156+
# (plugins must be loaded in ckan.plugins)
157+
ckan.views.default_views = geojson_view unaids_recline_view pdf_view image_view text_view
158+
159+
# Customize which text formats the text_view plugin will show
160+
#ckan.preview.json_formats = json
161+
#ckan.preview.xml_formats = xml rdf rdf+xml owl+xml atom rss
162+
#ckan.preview.text_formats = txt plain text/plain
163+
164+
# Customize which image formats the image_view plugin will show
165+
#ckan.preview.image_formats = png jpeg jpg gif
166+
167+
## Front-End Settings
168+
169+
ckan.site_title = The AIDS Data Repository
170+
ckan.site_logo = /adr_simple.png
171+
ckan.site_description = Data Catalogue
172+
ckan.favicon = /images/favicon.ico
173+
ckan.gravatar_default = identicon
174+
ckan.preview.direct = png jpg gif
175+
ckan.preview.loadable = html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json
176+
ckan.display_timezone = server
177+
178+
# package_hide_extras = for_search_index_only
179+
#package_edit_return_url = http://another.frontend/dataset/<NAME>
180+
#package_new_return_url = http://another.frontend/dataset/<NAME>
181+
#licenses_group_url = http://licenses.opendefinition.org/licenses/groups/ckan.json
182+
# ckan.template_footer_end =
183+
184+
185+
## Internationalisation Settings
186+
ckan.locale_default = en
187+
ckan.locale_order = en fr pt_PT
188+
ckan.locales_offered = en fr pt_PT
189+
ckan.locales_filtered_out = en_GB
190+
191+
## Feeds Settings
192+
193+
ckan.feeds.authority_name =
194+
ckan.feeds.date =
195+
ckan.feeds.author_name =
196+
ckan.feeds.author_link =
197+
198+
## Storage Settings
199+
200+
#ckan.storage_path = /var/lib/ckan
201+
ckan.max_resource_size = 100
202+
#ckan.max_image_size = 2
203+
204+
## Webassets Settings
205+
ckan.webassets.use_x_sendfile = true
206+
ckan.webassets.path = /var/lib/ckan/webassets
207+
208+
209+
## Datapusher settings
210+
211+
# Make sure you have set up the DataStore
212+
213+
ckan.datapusher.formats = csv xls xlsx tsv application/csv application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet geojson
214+
ckan.datapusher.url = http://datapusher:8800
215+
# Generate a real token: ckan -c /etc/ckan/production.ini user token add admin datapusher
216+
ckan.datapusher.api_token = ${CKAN_DATAPUSHER_API_TOKEN}
217+
ckan.datapusher.callback_url_base = http://ckan:5000/
218+
ckan.datapusher.assume_task_stale_after = 3600
219+
220+
# Resource Proxy settings
221+
# Preview size limit, default: 1MB
222+
#ckan.resource_proxy.max_file_size = 1048576
223+
# Size of chunks to read/write.
224+
#ckan.resource_proxy.chunk_size = 4096
225+
226+
## Activity Streams Settings
227+
228+
229+
230+
## Background Job Settings
231+
232+
# Additional CKAN settings for extensions, configurable via group_vars
233+
# CKAN
234+
ckan.resource_formats = /usr/lib/ckan/submodules/ckanext-unaids/ckanext/unaids/resource_formats.json
235+
# ckan.route_after_login = validate_user_affiliation.check_user_affiliation
236+
ckan.jobs.timeout = 500
237+
ckan.datasets_per_page = 70
238+
ckan.group_and_organization_list_all_fields_max = 1000
239+
ckan.group_and_organization_list_max = 1000
240+
241+
# Scheming
242+
scheming.dataset_schemas_directory = /usr/lib/ckan/submodules/unaids_data_specifications/package_schemas
243+
scheming.presets = ckanext.unaids:presets.json
244+
ckanext.scheming:presets.json
245+
ckanext.validation:presets.json
246+
247+
# Blob storage
248+
ckanext.blob_storage.use_scheming_file_uploader = True
249+
250+
# Validation
251+
ckanext.unaids.schema_directory = /usr/lib/ckan/submodules/unaids_data_specifications/table_schemas
252+
ckanext.validation.run_on_create_async = True
253+
ckanext.validation.run_on_update_async = True
254+
ckanext.validation.run_on_create_sync = False
255+
ckanext.validation.run_on_update_sync = False
256+
ckanext.validation.allow_invalid_data = True
257+
ckanext.validation.formats = csv xlsx xls geojson
258+
ckanext.validation.default_validation_options = {"limit_rows": 50000, "limit_errors": 100, "skip_errors": ["extra-header"], "schema_sync": true}
259+
260+
# Email as username
261+
emailasusername.search_by_username_and_email = True
262+
263+
# Pages/CMS
264+
ckanext.pages.editor = ckeditor
265+
ckanext.pages.allow_html = True
266+
ckanext.pages.about_menu = False
267+
ckanext.pages.group_menu = False
268+
ckanext.pages.blog = False
269+
270+
# Harvest
271+
ckan.harvest.mq.hostname = redis
272+
ckan.harvest.mq.type = redis
273+
ckan.harvest.mq.port = 6379
274+
ckan.harvest.mq.redis_db = 2
275+
276+
# Spatial
277+
ckanext.spatial.common_map.type = custom
278+
ckanext.spatial.common_map.custom.url = https://tile.openstreetmap.org/{z}/{x}/{y}.png
279+
ckanext.spatial.common_map.attribution = &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors
280+
281+
# SAML2.0 - Auth0 IDP
282+
ckanext.saml2auth.idp_metadata.location = remote
283+
ckanext.saml2auth.idp_metadata.remote_url = https://dev-udfgla0l.eu.auth0.com/samlp/metadata/txdzFtnQXamucc3PhJGIoqxoPnRxZY6K
284+
ckanext.saml2auth.idp_metadata.remote_cert = /tmp/saml_idp.crt
285+
ckanext.saml2auth.user_fullname = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/fullname
286+
ckanext.saml2auth.user_email = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
287+
ckanext.saml2auth.want_response_signed = False
288+
ckanext.saml2auth.want_assertions_signed = True
289+
ckanext.saml2auth.logout_requests_signed = False
290+
291+
# OAuth2
292+
ckanext.unaids.oauth2_required_scope = access:adr
293+
294+
# Recaptcha - DISABLED for staging
295+
# ckan.recaptcha.publickey = <SET_IN_SECRETS>
296+
# ckan.recaptcha.privatekey = <SET_IN_SECRETS>
297+
298+
## Logging configuration
299+
[loggers]
300+
keys = root, ckan, ckanext, werkzeug
301+
302+
[handlers]
303+
keys = console
304+
305+
[formatters]
306+
keys = generic
307+
308+
[logger_root]
309+
level = WARNING
310+
handlers = console
311+
312+
[logger_werkzeug]
313+
level = WARNING
314+
handlers = console
315+
qualname = werkzeug
316+
propagate = 0
317+
318+
[logger_ckan]
319+
level = INFO
320+
handlers = console
321+
qualname = ckan
322+
propagate = 0
323+
324+
[logger_ckanext]
325+
level = DEBUG
326+
handlers = console
327+
qualname = ckanext
328+
propagate = 0
329+
330+
[handler_console]
331+
class = StreamHandler
332+
args = (sys.stderr,)
333+
level = NOTSET
334+
formatter = generic
335+
336+
[formatter_generic]
337+
format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s

0 commit comments

Comments
 (0)