diff --git a/desuto-couchdb/10-docker-default.ini b/desuto-couchdb/10-docker-default.ini index 5059f64..e87ba8e 100755 --- a/desuto-couchdb/10-docker-default.ini +++ b/desuto-couchdb/10-docker-default.ini @@ -1,24 +1,25 @@ ; CouchDB Configuration Settings ; Custom settings should be made in this file. They will override settings ; in default.ini, but unlike changes made to default.ini, this file won't be ; overwritten on server upgrade. [chttpd] bind_address = any [httpd] +bind_address = any enable_cors = true [cors] origins = * credentials = true methods = GET, PUT, POST, HEAD, DELETE headers = accept, authorization, content-type, origin, referer, x-csrf-token [ssl] verify_ssl_certificates = false ssl_certificate_max_depth = 1 [admins] admin = $TH3C0uch---4Dmin! diff --git a/desuto-couchdb/docker-entrypoint.sh b/desuto-couchdb/docker-entrypoint.sh index 380944a..056766e 100755 --- a/desuto-couchdb/docker-entrypoint.sh +++ b/desuto-couchdb/docker-entrypoint.sh @@ -1,109 +1,147 @@ #!/bin/bash # 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 # # 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. -set -m +set -e -if [ "$1" = '/opt/couchdb/bin/couchdb' ]; then - # we need to set the permissions here because docker mounts volumes as root - chown -R couchdb:couchdb /opt/couchdb +# first arg is `-something` or `+something` +if [ "${1#-}" != "$1" ] || [ "${1#+}" != "$1" ]; then + set -- /opt/couchdb/bin/couchdb "$@" +fi - chmod -R 0770 /opt/couchdb/data +# first arg is the bare word `couchdb` +if [ "$1" = 'couchdb' ]; then + shift + set -- /opt/couchdb/bin/couchdb "$@" +fi - chmod 664 /opt/couchdb/etc/*.ini - chmod 664 /opt/couchdb/etc/local.d/*.ini - chmod 775 /opt/couchdb/etc/*.d +if [ "$1" = '/opt/couchdb/bin/couchdb' ]; then + # Check that we own everything in /opt/couchdb and fix if necessary. We also + # add the `-f` flag in all the following invocations because there may be + # cases where some of these ownership and permissions issues are non-fatal + # (e.g. a config file owned by root with o+r is actually fine), and we don't + # to be too aggressive about crashing here ... + find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' + + + # Ensure that data files have the correct permissions. We were previously + # preventing any access to these files outside of couchdb:couchdb, but it + # turns out that CouchDB itself does not set such restrictive permissions + # when it creates the files. The approach taken here ensures that the + # contents of the datadir have the same permissions as they had when they + # were initially created. This should minimize any startup delay. + find /opt/couchdb/data -type d ! -perm 0755 -exec chmod -f 0755 '{}' + + find /opt/couchdb/data -type f ! -perm 0644 -exec chmod -f 0644 '{}' + + + # Do the same thing for configuration files and directories. Technically + # CouchDB only needs read access to the configuration files as all online + # changes will be applied to the "docker.ini" file below, but we set 644 + # for the sake of consistency. + find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' + + find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' + if [ ! -z "$NODENAME" ] && ! grep "couchdb@" /opt/couchdb/etc/vm.args; then echo "-name couchdb@$NODENAME" >> /opt/couchdb/etc/vm.args fi + # Ensure that CouchDB will write custom settings in this file + touch /opt/couchdb/etc/local.d/docker.ini + if [ "$COUCHDB_USER" ] && [ "$COUCHDB_PASSWORD" ]; then - # Create admin - printf "[admins]\n%s = %s\n" "$COUCHDB_USER" "$COUCHDB_PASSWORD" > /opt/couchdb/etc/local.d/docker.ini - chown couchdb:couchdb /opt/couchdb/etc/local.d/docker.ini + # Create admin only if not already present + if ! grep -Pzoqr "\[admins\]\n$COUCHDB_USER =" /opt/couchdb/etc/local.d/*.ini; then + printf "\n[admins]\n%s = %s\n" "$COUCHDB_USER" "$COUCHDB_PASSWORD" >> /opt/couchdb/etc/local.d/docker.ini + fi + fi + + if [ "$COUCHDB_SECRET" ]; then + # Set secret only if not already present + if ! grep -Pzoqr "\[couch_httpd_auth\]\nsecret =" /opt/couchdb/etc/local.d/*.ini; then + printf "\n[couch_httpd_auth]\nsecret = %s\n" "$COUCHDB_SECRET" >> /opt/couchdb/etc/local.d/docker.ini + fi fi + chown -f couchdb:couchdb /opt/couchdb/etc/local.d/docker.ini || true + # if we don't find an [admins] section followed by a non-comment, display a warning if ! grep -Pzoqr '\[admins\]\n[^;]\w+' /opt/couchdb/etc/local.d/*.ini; then # The - option suppresses leading tabs but *not* spaces. :) cat >&2 <<-'EOWARN' **************************************************** WARNING: CouchDB is running in Admin Party mode. This will allow anyone with access to the CouchDB port to access your database. In Docker's default configuration, this is effectively any other container on the same system. Use "-e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password" to set it in "docker run". **************************************************** EOWARN fi #exec gosu couchdb "$@" # Run CouchdB in background gosu couchdb "$@" & # Wait for the server to be up sleep 10 # Variables (set your own) user=$COUCHDB_USER pass=$COUCHDB_PASSWORD host=$COUCHDB_HOST port=$COUCHDB_PORT protocol=$COUCHDB_PROTOCOL dbname=$COUCHDB_DB_NAME permdbname=$COUCHDB_PERM_DB_NAME echo "Base URL for configuring the DB : $protocol://$user:$pass"'@'"$host:$port/" #################### ### Configure DB ### #################### # Set timeout of cookies to 24h curl -H "Content-Type: application/json" -X PUT -d '86400' "$protocol://$user:$pass"'@'"$host:$port/$dbname" # Create system DBs curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users" curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/_replicator" curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/_global_changes" # Create annotation DB curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/$dbname" # Create permissions DB curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/$permdbname" # Make permissions DB read-only for non-annotation admins curl -X PUT "$protocol://$user:$pass@$host:$port/$permdbname/_design/auth" -d "{ \"language\": \"javascript\", \"validate_doc_update\": \"function(newDoc, oldDoc, userCtx) { if (userCtx.roles.indexOf('annotationadmins') !== -1 || userCtx.name === 'admin') { return; } else { throw ({ forbidden: 'Only annotation admins may edit the database' }); } }\"}" # Setup DB security roles curl -H "Content-Type: application/json" -X PUT -d '{"admins":{"names":["admin"],"roles":["admins"]},"members":{"names":[],"roles":["users","pathologists","annotationadmins"]}}' "$protocol://$user:$pass"'@'"$host:$port/$dbname/_security" # Setup permissions DB security roles curl -H "Content-Type: application/json" -X PUT -d '{"admins":{"names":["admin"],"roles":["admins"]},"members":{"names":[],"roles":["users","pathologists","annotationadmins"]}}' "$protocol://$user:$pass"'@'"$host:$port/$permdbname/_security" # Setup users in DB curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:user" --data-binary '{"_id": "org.couchdb.user:user","name": "user","roles": ["users"],"type": "user","password": "userpass"}' curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:pathologist1" --data-binary '{"_id": "org.couchdb.user:pathologist1","name": "pathologist1","roles": ["users", "pathologists"],"type": "user","password": "pathologistpass"}' curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:pathologist2" --data-binary '{"_id": "org.couchdb.user:pathologist2","name": "pathologist2","roles": ["users", "pathologists"],"type": "user","password": "pathologistpass"}' curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:annotationadmin" --data-binary '{"_id": "org.couchdb.user:annotationadmin","name": "annotationadmin","roles": ["users", "pathologists", "annotationadmins"],"type": "user","password": "annotationpassw"}' # Bring CouchDB to foreground fg fi -exec "$@" +exec "$@" \ No newline at end of file