diff --git a/.gitignore b/.gitignore index 80bda74..dfe0c39 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ composer.phar .DS_Store *.cache db_username.txt +db_admin_username.txt db_password.txt +db_admin_password.txt redis_password.txt typesense_api_key.txt diff --git a/container-setup.sh b/container-setup.sh index 3814038..415a25a 100755 --- a/container-setup.sh +++ b/container-setup.sh @@ -3,7 +3,12 @@ _JIKAN_API_VERSION=v4.0.0 SUBSTITUTE_VERSION=$_JIKAN_API_VERSION if [ -x "$(command -v git)" ]; then - SUBSTITUTE_VERSION=$(git describe --tags | sed -e "s/-[a-z0-9]\{8\}/-$(git rev-parse --short HEAD)/g") + git symbolic-ref HEAD &> /dev/null + if [ $? -ne 0 ]; then + SUBSTITUTE_VERSION=$(git describe --tags) + else + SUBSTITUTE_VERSION=$(git describe --tags | sed -e "s/-[a-z0-9]\{8\}/-$(git rev-parse --short HEAD)/g") + fi fi export _JIKAN_API_VERSION=${JIKAN_API_VERSION:-$SUBSTITUTE_VERSION} @@ -76,7 +81,29 @@ build_image() { } ensure_secrets() { - declare -a secrets=("db_password" "db_username" "redis_password" "typesense_api_key") + declare -a secrets=("db_password" "db_admin_password" "redis_password" "typesense_api_key") + + if [ ! -f "db_username.txt" ]; then + echo "db_username.txt not found, please provide a db_username [default is jikan]:" + read -r db_username + if [ -z "$db_username" ]; then + db_username="jikan" + fi + echo -n "$db_username" > "db_username.txt" + else + echo -e "db_username.txt found, using it's value. \xE2\x9C\x94" + fi + + if [ ! -f "db_admin_username.txt" ]; then + echo "db_admin_username.txt not found, please provide a db_admin_username [default is jikan_admin]:" + read -r db_admin_username + if [ -z "$db_admin_username" ]; then + db_admin_username="jikan_admin" + fi + echo -n "$db_admin_username" > "db_admin_username.txt" + else + echo -e "db_admin_username.txt found, using it's value. \xE2\x9C\x94" + fi for secret_name in "${secrets[@]}" do @@ -84,7 +111,7 @@ ensure_secrets() { if [ "$secret_name" == "db_username" ]; then generated_secret="jikan" else - generated_secret=$(LC_ALL=c tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_{|}~' _' "$secret_name.txt" + echo -n "$secret_value" > "$secret_name.txt" else echo -e "$secret_name.txt found, using it's value. \xE2\x9C\x94" fi diff --git a/docker-compose.yml b/docker-compose.yml index 0eaa717..e1c0843 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,10 @@ secrets: file: db_username.txt db_password: file: db_password.txt + db_admin_username: + file: db_admin_username.txt + db_admin_password: + file: db_admin_password.txt redis_password: file: redis_password.txt typesense_api_key: @@ -40,9 +44,9 @@ services: interval: 2s timeout: 2s links: - - mongodb - - redis - - typesense + - mongodb:mongodb + - redis:redis + - typesense:typesense depends_on: mongodb: { condition: service_healthy } redis: { condition: service_healthy } @@ -53,17 +57,21 @@ services: hostname: mongodb volumes: - mongo-data:/data/db + - ./docker/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro ports: - - '27017/tcp' + - 27017/tcp command: "--wiredTigerCacheSizeGB ${MONGO_CACHE_SIZE_GB:-1.0}" networks: - jikan_network secrets: - db_username - db_password + - db_admin_username + - db_admin_password environment: - MONGO_INITDB_ROOT_USERNAME_FILE: /run/secrets/db_username - MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/db_password + MONGO_INITDB_ROOT_USERNAME_FILE: /run/secrets/db_admin_username + MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/db_admin_password + MONGO_INITDB_DATABASE: jikan_admin healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh mongodb://localhost:27017 --quiet interval: 30s diff --git a/docker-entrypoint.php b/docker-entrypoint.php index 6d69d07..8fd3fe7 100644 --- a/docker-entrypoint.php +++ b/docker-entrypoint.php @@ -19,6 +19,8 @@ $safe_defaults = [ "DB_PASSWORD" => "" ]; +// get a copy of the current env vars. +// these are the ones that are set during the container creation $current_env = $_ENV; if (!file_exists(".env")) { @@ -34,6 +36,8 @@ if (!file_exists(".env")) { // We'd like to support Container secrets. So we'll check if any of the env vars has a __FILE suffix // then we'll try to load the file and set the env var to the contents of the file. // https://docs.docker.com/engine/swarm/secrets/ +// Additionally we need to write the secrets to the .env file so the workers in roadrunner can access them. +// (it might just pass down the global env vars, but haven't tested that yet) $envWriter = new \MirazMac\DotEnv\Writer(__DIR__ . '/' . '.env'); $itemsWritten = 0; foreach (array_keys($current_env) as $env_key) { @@ -45,7 +49,8 @@ foreach (array_keys($current_env) as $env_key) { continue; } $originalKey = str_replace("__FILE", "", $env_key); - $envWriter->set($originalKey, file_get_contents($current_env[$env_key])); + $secretsFileContents = file_get_contents($current_env[$env_key]); + $envWriter->set($originalKey, str_replace(["\n", "\r"], "", $secretsFileContents)); $itemsWritten++; } diff --git a/docker/mongo-init.js b/docker/mongo-init.js new file mode 100644 index 0000000..01274f0 --- /dev/null +++ b/docker/mongo-init.js @@ -0,0 +1,17 @@ +const userToCreate = fs.readFileSync('/run/secrets/db_username', 'utf8'); +const userPassword = fs.readFileSync('/run/secrets/db_password', 'utf8'); +db = db.getSiblingDB("admin"); + +db.createUser({ + user: userToCreate, + pwd: userPassword, + roles: [{ role: "readWrite", db: "jikan" }], +}); + +db = db.getSiblingDB("jikan"); + +db.createUser({ + user: userToCreate, + pwd: userPassword, + roles: [{ role: "readWrite", db: "jikan" }], +});