diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index c1b7f390..64f1a450 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -24,11 +24,14 @@ services: service: profiles: - enketo - depends_on: !reset [] + depends_on: !override [secrets] network_mode: host environment: - DB_HOST=localhost - ENV=DEV + - XLSFORM_HOST=127.0.0.1 + - XLSFORM_PORT=5001 + - ENKETO_URL=http://localhost:8005/- nginx: profiles: - enketo @@ -45,7 +48,10 @@ services: network_mode: host secrets: profiles: - - none + - central + - enketo + environment: + - ENV=DEV enketo: profiles: - central diff --git a/docker-compose.yml b/docker-compose.yml index c237608f..212e1ee1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,6 +57,9 @@ services: - DB_PASSWORD=${DB_PASSWORD:-odk} - DB_NAME=${DB_NAME:-odk} - DB_SSL=${DB_SSL:-null} + - XLSFORM_HOST=${XLSFORM_HOST:-pyxform} + - XLSFORM_PORT=${XLSFORM_PORT:-80} + - ENKETO_URL=${ENKETO_URL:-http://enketo:8005/-} - EMAIL_FROM=${EMAIL_FROM:-no-reply@$DOMAIN} - EMAIL_HOST=${EMAIL_HOST:-mail} - EMAIL_PORT=${EMAIL_PORT:-25} diff --git a/enketo.dockerfile b/enketo.dockerfile index 3ccab02b..70a2430f 100644 --- a/enketo.dockerfile +++ b/enketo.dockerfile @@ -12,7 +12,6 @@ WORKDIR ${ENKETO_SRC_DIR} COPY files/enketo/config.json.template ${ENKETO_SRC_DIR}/config/config.json.template COPY files/enketo/config.json.template ${ENKETO_SRC_DIR}/config/config.json -COPY files/enketo/config.json.dev.template ${ENKETO_SRC_DIR}/config/config.json.dev.template COPY files/enketo/start-enketo.sh ${ENKETO_SRC_DIR}/start-enketo.sh RUN apt-get update && \ diff --git a/files/enketo/config.json.dev.template b/files/enketo/config.json.dev.template deleted file mode 100644 index 590d062f..00000000 --- a/files/enketo/config.json.dev.template +++ /dev/null @@ -1,45 +0,0 @@ -{ - "app name": "Enketo", - "base path": "-", - "encryption key": "s0m3v3rys3cr3tk3y", - "id length": 31, - "less secure encryption key": "this $3cr3t key is crackable", - "linked form and data server": { - "api key": "enketorules", - "authentication": { - "allow insecure transport": "true" - }, - "name": "ODK Central", - "server url": "localhost:8989" - }, - "ip filtering": { - "allowPrivateIPAddress": true, - "allowMetaIPAddress": false, - "allowIPAddressList": [], - "denyIPAddressList": [] - }, - "max processes": 1, - "logo": { - "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=", - "href": "" - }, - "offline enabled": true, - "payload limit": "1mb", - "port": "8005", - "query parameter to pass to submission": "st", - "redis": { - "main": { - "host": "localhost", - "port": "6379" - }, - "cache": { - "host": "localhost", - "port": "6379" - } - }, - "support": { - "email": "support@getodk.org" - }, - "text field character limit": 1000000, - "exclude non-relevant": true -} diff --git a/files/enketo/generate-secrets.sh b/files/enketo/generate-secrets.sh index 76c3f245..9cb624e4 100755 --- a/files/enketo/generate-secrets.sh +++ b/files/enketo/generate-secrets.sh @@ -12,3 +12,8 @@ if [ ! -f /etc/secrets/enketo-api-key ]; then LC_ALL=C tr -dc '[:alnum:]' < /dev/urandom | head -c128 > /etc/secrets/enketo-api-key fi +if [ "$ENV" = "DEV" ]; then + echo -n 's0m3v3rys3cr3tk3y' > /etc/secrets/enketo-secret + echo -n 'this $3cr3t key is crackable' > /etc/secrets/enketo-less-secret + echo -n 'enketorules' > /etc/secrets/enketo-api-key +fi \ No newline at end of file diff --git a/files/enketo/start-enketo.sh b/files/enketo/start-enketo.sh index fa94aa6d..101cd5f7 100755 --- a/files/enketo/start-enketo.sh +++ b/files/enketo/start-enketo.sh @@ -3,6 +3,12 @@ CONFIG_PATH=${ENKETO_SRC_DIR}/config/config.json echo "generating enketo configuration..." +if [ "$ENV" = "DEV" ]; then + sed -i 's/enketo_redis_main/localhost/g' "$CONFIG_PATH.template" + sed -i 's/enketo_redis_cache/localhost/g' "$CONFIG_PATH.template" + sed -i 's/6380/6379/g' "$CONFIG_PATH.template" +fi + BASE_URL=$( [ "${HTTPS_PORT}" = 443 ] && echo https://"${DOMAIN}" || echo https://"${DOMAIN}":"${HTTPS_PORT}" ) \ SECRET=$(cat /etc/secrets/enketo-secret) \ LESS_SECRET=$(cat /etc/secrets/enketo-less-secret) \ @@ -11,9 +17,5 @@ envsubst '$DOMAIN $BASE_URL $SECRET $LESS_SECRET $API_KEY $SUPPORT_EMAIL' \ < "$CONFIG_PATH.template" \ > "$CONFIG_PATH" -if [ "$ENV" = "DEV" ]; then - cp "$CONFIG_PATH.dev.template" "$CONFIG_PATH" -fi - echo "starting enketo..." exec yarn workspace enketo-express start diff --git a/files/nginx/odk.conf.dev.template b/files/nginx/odk.conf.dev.template deleted file mode 100644 index c693bf9f..00000000 --- a/files/nginx/odk.conf.dev.template +++ /dev/null @@ -1,64 +0,0 @@ -server { - listen 8989; - server_name localhost; - - server_tokens off; - - include /usr/share/odk/nginx/common-headers.conf; - - client_max_body_size 100m; - - gzip on; - gzip_vary on; - gzip_min_length 1280; - gzip_http_version 1.1; - gzip_types text/plain text/css application/json application/x-javascript text/xml text/csv; - - location /- { - proxy_pass http://localhost:8005; - proxy_redirect off; - proxy_set_header Host $host; - - # More lax CSP for enketo-express: - # Google Maps API: https://developers.google.com/maps/documentation/javascript/content-security-policy - add_header Content-Security-Policy-Report-Only "default-src 'none'; connect-src 'self' blob: https://maps.googleapis.com/maps/ https://maps.google.com/ https://maps.gstatic.com/mapfiles/ https://fonts.gstatic.com/ https://fonts.googleapis.com/; font-src 'self' https://fonts.gstatic.com/; frame-src 'none'; img-src data: blob: jr: 'self' https://maps.google.com/maps/ https://maps.gstatic.com/mapfiles/ https://maps.googleapis.com/maps/; manifest-src 'none'; media-src blob: jr: 'self'; object-src 'none'; script-src 'unsafe-inline' 'self' https://maps.googleapis.com/maps/api/js/ https://maps.google.com/maps/ https://maps.google.com/maps-api-v3/api/js/; style-src 'unsafe-inline' 'self' https://fonts.googleapis.com/css; style-src-attr 'none'; report-uri /csp-report"; - # - # Rules set to 'none' here would fallback to default-src if excluded. - # They are included here to ease interpretation of violation reports. - # - # Other security headers are identical to those in common-headers.conf; - # We can't just include that file here though, as it will set two Content-Security-Policy* headers - add_header Referrer-Policy same-origin; - add_header Strict-Transport-Security "max-age=63072000" always; - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options nosniff; - } - - location ~ ^/v\d { - proxy_set_header X-Forwarded-Proto https; - proxy_pass http://localhost:8383; - proxy_redirect off; - - # buffer requests, but not responses, so streaming out works. - proxy_request_buffering on; - proxy_buffering off; - proxy_read_timeout 2m; - } - - location / { - root /usr/share/nginx/html; - - location /version.txt { - include /usr/share/odk/nginx/common-headers.conf; - add_header Cache-Control no-cache; - } - location /index.html { - include /usr/share/odk/nginx/common-headers.conf; - add_header Cache-Control no-cache; - } - } - - location /csp-report { - proxy_pass https://${SENTRY_ORG_SUBDOMAIN}.ingest.sentry.io/api/${SENTRY_PROJECT}/security/?sentry_key=${SENTRY_KEY}; - } -} diff --git a/files/nginx/setup-odk.sh b/files/nginx/setup-odk.sh index 856e3044..21c3ecdd 100644 --- a/files/nginx/setup-odk.sh +++ b/files/nginx/setup-odk.sh @@ -16,9 +16,6 @@ if [ "$SSL_TYPE" = "selfsign" ] && [ ! -s "$SELFSIGN_PATH/privkey.pem" ]; then fi TEMPLATE_PATH=/usr/share/odk/nginx/odk.conf.template -if [ "$ENV" = "DEV" ]; then - TEMPLATE_PATH=/usr/share/odk/nginx/odk.conf.dev.template -fi # start from fresh templates in case ssl type has changed echo "writing fresh nginx templates..." @@ -35,19 +32,23 @@ else if [ "$SSL_TYPE" = "upstream" ]; then # no need for letsencrypt challenge reply or 80 to 443 redirection rm -f /etc/nginx/conf.d/redirector.conf - # strip out all ssl_* directives - perl -i -ne 's/listen 443.*/listen 80;/; print if ! /ssl_/' /etc/nginx/conf.d/odk.conf - # force https because we expect SSL upstream - perl -i -pe 's/X-Forwarded-Proto \$scheme/X-Forwarded-Proto https/;' /etc/nginx/conf.d/odk.conf + + # in DEV we run Central on http + if [ "$ENV" = "DEV" ]; then + perl -i -ne 's/listen 443.*/listen 8989;/; print if ! /ssl_/' /etc/nginx/conf.d/odk.conf + perl -i -pe 's/enketo:8005;/localhost:8005;/;' /etc/nginx/conf.d/odk.conf + perl -i -pe 's/service:8383;/localhost:8383;/;' /etc/nginx/conf.d/odk.conf + else + # strip out all ssl_* directives + perl -i -ne 's/listen 443.*/listen 80;/; print if ! /ssl_/' /etc/nginx/conf.d/odk.conf + # force https because we expect SSL upstream + perl -i -pe 's/X-Forwarded-Proto \$scheme/X-Forwarded-Proto https/;' /etc/nginx/conf.d/odk.conf + fi + echo "starting nginx for upstream ssl..." else # remove letsencrypt challenge reply, but keep 80 to 443 redirection perl -i -ne 'print if $. < 7 || $. > 14' /etc/nginx/conf.d/redirector.conf - - if [ "$ENV" = "DEV" ]; then - rm -f /etc/nginx/conf.d/redirector.conf - fi - echo "starting nginx for custom ssl and self-signed certs..." fi exec nginx -g "daemon off;" diff --git a/files/postgres14/start-postgres.sh b/files/postgres14/start-postgres.sh index 73ef8715..978f6c4c 100755 --- a/files/postgres14/start-postgres.sh +++ b/files/postgres14/start-postgres.sh @@ -1,7 +1,7 @@ #!/bin/bash -eu set -o pipefail -flag_upgradeCompletedOk=$(readlink -f -m $PGDATA/../.postgres14-upgrade-successful) +flag_upgradeCompletedOk=$(readlink -f -m "$PGDATA/../.postgres14-upgrade-successful") logPrefix="$(basename "$0")" log() { diff --git a/files/service/config.json.dev.template b/files/service/config.json.dev.template deleted file mode 100644 index 6c08925e..00000000 --- a/files/service/config.json.dev.template +++ /dev/null @@ -1,50 +0,0 @@ -{ - "default": { - "database": { - "host": "${DB_HOST}", - "user": "${DB_USER}", - "password": "${DB_PASSWORD}", - "database": "${DB_NAME}", - "ssl": ${DB_SSL} - }, - "email": { - "serviceAccount": "${EMAIL_FROM}", - "transport": "smtp", - "transportOpts": { - "host": "${EMAIL_HOST}", - "port": ${EMAIL_PORT}, - "secure": ${EMAIL_SECURE}, - "ignoreTLS": ${EMAIL_IGNORE_TLS}, - "auth": { - "user": "${EMAIL_USER}", - "pass": "${EMAIL_PASSWORD}" - } - } - }, - "xlsform": { - "host": "127.0.0.1", // localhost doesn't work here - don't know why (shrug) - "port": 5001 - }, - "enketo": { - "url": "http://localhost:8005/-", - "apiKey": "enketorules" - }, - "env": { - "domain": "http://localhost:8989", - "sysadminAccount": "${SYSADMIN_EMAIL}" - }, - "oidc": { - "enabled": ${OIDC_ENABLED}, - "issuerUrl": "${OIDC_ISSUER_URL}", - "clientId": "${OIDC_CLIENT_ID}", - "clientSecret": "${OIDC_CLIENT_SECRET}" - }, - "external": { - "sentry": { - "orgSubdomain": "${SENTRY_ORG_SUBDOMAIN}", - "key": "${SENTRY_KEY}", - "project": "${SENTRY_PROJECT}" - } - } - } -} diff --git a/files/service/config.json.template b/files/service/config.json.template index c4500224..e5c37835 100644 --- a/files/service/config.json.template +++ b/files/service/config.json.template @@ -22,11 +22,11 @@ } }, "xlsform": { - "host": "pyxform", - "port": 80 + "host": "${XLSFORM_HOST}", + "port": ${XLSFORM_PORT} }, "enketo": { - "url": "http://enketo:8005/-", + "url": "${ENKETO_URL}", "apiKey": "${ENKETO_API_KEY}" }, "env": { diff --git a/files/service/scripts/start-odk.sh b/files/service/scripts/start-odk.sh index 575aed95..de0b9bb4 100755 --- a/files/service/scripts/start-odk.sh +++ b/files/service/scripts/start-odk.sh @@ -4,13 +4,16 @@ echo "generating local service configuration.." TEMPLATE_PATH=/usr/share/odk/config.json.template +BASE_URL=$( [ "${HTTPS_PORT}" = 443 ] && echo https://"${DOMAIN}" || echo https://"${DOMAIN}":"${HTTPS_PORT}" ) + if [ "$ENV" = "DEV" ]; then - TEMPLATE_PATH=/usr/share/odk/config.json.dev.template + BASE_URL="http://localhost:8989" fi +export BASE_URL + ENKETO_API_KEY=$(cat /etc/secrets/enketo-api-key) \ -BASE_URL=$( [ "${HTTPS_PORT}" = 443 ] && echo https://"${DOMAIN}" || echo https://"${DOMAIN}":"${HTTPS_PORT}" ) \ -envsubst '$DOMAIN $BASE_URL $SYSADMIN_EMAIL $ENKETO_API_KEY $DB_HOST $DB_USER $DB_PASSWORD $DB_NAME $DB_SSL $EMAIL_FROM $EMAIL_HOST $EMAIL_PORT $EMAIL_SECURE $EMAIL_IGNORE_TLS $EMAIL_USER $EMAIL_PASSWORD $OIDC_ENABLED $OIDC_ISSUER_URL $OIDC_CLIENT_ID $OIDC_CLIENT_SECRET $SENTRY_ORG_SUBDOMAIN $SENTRY_KEY $SENTRY_PROJECT' \ +envsubst '$DOMAIN $BASE_URL $SYSADMIN_EMAIL $ENKETO_API_KEY $DB_HOST $DB_USER $DB_PASSWORD $DB_NAME $DB_SSL $EMAIL_FROM $EMAIL_HOST $EMAIL_PORT $EMAIL_SECURE $EMAIL_IGNORE_TLS $EMAIL_USER $EMAIL_PASSWORD $OIDC_ENABLED $OIDC_ISSUER_URL $OIDC_CLIENT_ID $OIDC_CLIENT_SECRET $SENTRY_ORG_SUBDOMAIN $SENTRY_KEY $SENTRY_PROJECT $XLSFORM_HOST $XLSFORM_PORT $ENKETO_URL' \ < $TEMPLATE_PATH \ > /usr/odk/config/local.json diff --git a/service.dockerfile b/service.dockerfile index 5e6be374..8c47e998 100644 --- a/service.dockerfile +++ b/service.dockerfile @@ -61,7 +61,6 @@ COPY server/ ./ COPY files/service/scripts/ ./ COPY files/service/config.json.template /usr/share/odk/ -COPY files/service/config.json.dev.template /usr/share/odk/ COPY files/service/crontab /etc/cron.d/odk COPY files/service/odk-cmd /usr/bin/