[GH-ISSUE #1184] Support for docker compose _FILE secrets #808

Closed
opened 2026-02-25 23:43:39 +03:00 by kerem · 7 comments
Owner

Originally created by @ionesculiviucristian on GitHub (Jul 6, 2025).
Original GitHub issue: https://github.com/healthchecks/healthchecks/issues/1184

Hi. Is there any support for docker compose secrets now or in the future? Thanks.

Originally created by @ionesculiviucristian on GitHub (Jul 6, 2025). Original GitHub issue: https://github.com/healthchecks/healthchecks/issues/1184 Hi. Is there any support for docker compose secrets now or in the future? Thanks.
kerem closed this issue 2026-02-25 23:43:39 +03:00
Author
Owner

@cuu508 commented on GitHub (Jul 8, 2025):

IIUC docker compose mounts secrets as files inside the container, and the convention is to use _FILE env variables pointing to the secrets files. For example, instead of:

DB_PASSWORD=hunter2

one might have

DB_PASSWORD_FILE=/run/secrets/db_password.txt

(with the text file containing "hunter2"). And it would be nice if Healthchecks understood and used these _FILE env variables.

I'm thinking it makes sense to use secrets only for sensitive settings (keys, tokens, passwords), not every configuration setting. And it would make sense to support both DB_PASSWORD and DB_PASSWORD_FILE variants – so instance operators can use either one depending on their needs and preferences. Going through the existing settings, we would be adding the following new settings:

DB_PASSWORD_FILE
DISCORD_CLIENT_SECRET_FILE
EMAIL_HOST_PASSWORD_FILE
LINENOTIFY_CLIENT_SECRET_FILE
MATRIX_ACCESS_TOKEN_FILE
PUSHBULLET_CLIENT_SECRET_FILE
PUSHOVER_API_TOKEN_FILE
S3_SECRET_KEY_FILE
SECRET_KEY_FILE
SLACK_CLIENT_SECRET_FILE
TELEGRAM_TOKEN_FILE
TRELLO_APP_KEY_FILE
TWILIO_AUTH_FILE
GITHUB_CLIENT_SECRET_FILE
GITHUB_PRIVATE_KEY_FILE
NTFY_SH_TOKEN_FILE

I think this makes sense to do. I'm currently in the middle of something and will need at least a month before I can work on this.

<!-- gh-comment-id:3047975424 --> @cuu508 commented on GitHub (Jul 8, 2025): IIUC docker compose mounts secrets as files inside the container, and the convention is to use `_FILE` env variables pointing to the secrets files. For example, instead of: ``` DB_PASSWORD=hunter2 ``` one might have ``` DB_PASSWORD_FILE=/run/secrets/db_password.txt ``` (with the text file containing "hunter2"). And it would be nice if Healthchecks understood and used these `_FILE` env variables. I'm thinking it makes sense to use secrets only for sensitive settings (keys, tokens, passwords), not every configuration setting. And it would make sense to support both DB_PASSWORD and DB_PASSWORD_FILE variants – so instance operators can use either one depending on their needs and preferences. Going through the existing settings, we would be adding the following new settings: ``` DB_PASSWORD_FILE DISCORD_CLIENT_SECRET_FILE EMAIL_HOST_PASSWORD_FILE LINENOTIFY_CLIENT_SECRET_FILE MATRIX_ACCESS_TOKEN_FILE PUSHBULLET_CLIENT_SECRET_FILE PUSHOVER_API_TOKEN_FILE S3_SECRET_KEY_FILE SECRET_KEY_FILE SLACK_CLIENT_SECRET_FILE TELEGRAM_TOKEN_FILE TRELLO_APP_KEY_FILE TWILIO_AUTH_FILE GITHUB_CLIENT_SECRET_FILE GITHUB_PRIVATE_KEY_FILE NTFY_SH_TOKEN_FILE ``` I think this makes sense to do. I'm currently in the middle of something and will need at least a month before I can work on this.
Author
Owner

@ionesculiviucristian commented on GitHub (Jul 9, 2025):

Unfortunately this is not the standard in many docker images so I switched to env secrets until something changes. Regarding on what should be put in files, I'll go with all because it's an easy implementation and different users have different requirements. Issue can be closed if considered irrelevant.

<!-- gh-comment-id:3053142029 --> @ionesculiviucristian commented on GitHub (Jul 9, 2025): Unfortunately this is not the standard in many docker images so I switched to env secrets until something changes. Regarding on what should be put in files, I'll go with all because it's an easy implementation and different users have different requirements. Issue can be closed if considered irrelevant.
Author
Owner

@cuu508 commented on GitHub (Jul 10, 2025):

Unfortunately this is not the standard in many docker images

Sorry, can you please clarify – is (1) the current state of putting secrets directly in env variables or (2) what I proposed not standard?

<!-- gh-comment-id:3056410428 --> @cuu508 commented on GitHub (Jul 10, 2025): > Unfortunately this is not the standard in many docker images Sorry, can you please clarify – is (1) the current state of putting secrets directly in env variables or (2) [what I proposed](https://github.com/healthchecks/healthchecks/issues/1184#issuecomment-3047975424) not standard?
Author
Owner

@ionesculiviucristian commented on GitHub (Jul 13, 2025):

I'm saying than not everybody implements _FILE in their docker images and there is no other workaround to that. It's either supported or not.

<!-- gh-comment-id:3066981936 --> @ionesculiviucristian commented on GitHub (Jul 13, 2025): I'm saying than not everybody implements ```_FILE``` in their docker images and there is no other workaround to that. It's either supported or not.
Author
Owner

@Cheezzhead commented on GitHub (Oct 24, 2025):

In the meantime, this functionality can be achieved with a custom script loaded as the entrypoint. I use this for all of my services that don't have built-in _FILE secrets support; the only downside (and the reason why I still prefer images to have this functionality built-in) is that you have to manually re-set the service command from whatever the image originally had, as setting a custom entrypoint invalidates the image's default CMD instruction.

(Note this script looks for FILE__<name> environment variables)

#!/usr/bin/env sh

for env_var in $(env | cut -d= -f1); do
    case "$env_var" in
        FILE__*)
            var_name="${env_var#FILE__}"
            
            # Evaluate value of environment variable
            eval "file_path=\$$env_var"
            
            # shellcheck disable=SC2154
            if file_content=$(tr -d '\r\n' < "$file_path" 2>/dev/null); then
                export "$var_name"="$file_content"
                printf "[bootstr-secrets] [%s] set from [%s]\n" "$var_name" "$env_var"
            else
                printf "[bootstr-secrets] Error reading file [%s]\n" "$file_path" >&2
            fi
            ;;
    esac
done

exec "$@"

Example usage in a compose service definition:

services:
  core:
    image: healthchecks/healthchecks:v3.11.2
    container_name: healthchecks
    # ....
    # Mount custom script
    volumes:
      - ./bootstrap_secrets.sh:/bootstrap_secrets.sh:ro
    # Overwrite entrypoint
    entrypoint: /bootstrap_secrets.sh
    # Manually set the command to whatever the image originally had
    command: ["uwsgi", "/opt/healthchecks/docker/uwsgi.ini"]
    # Use secrets
    secrets: [superuser_pass, secret_key, mail_pass, database_pass]
    environment:
      FILE__SUPERUSER_PASSWORD: /run/secrets/superuser_pass
      FILE__SECRET_KEY: /run/secrets/secret_key
      FILE__EMAIL_HOST_PASSWORD: /run/secrets/mail_pass
      FILE__DB_PASSWORD: /run/secrets/database_pass
<!-- gh-comment-id:3443535210 --> @Cheezzhead commented on GitHub (Oct 24, 2025): In the meantime, this functionality can be achieved with a custom script loaded as the entrypoint. I use this for all of my services that don't have built-in `_FILE` secrets support; the only downside (and the reason why I still prefer images to have this functionality built-in) is that you have to manually re-set the service `command` from whatever the image originally had, as setting a custom `entrypoint` invalidates the image's default `CMD` instruction. (Note this script looks for `FILE__<name>` environment variables) ```bootstrap_secrets.sh #!/usr/bin/env sh for env_var in $(env | cut -d= -f1); do case "$env_var" in FILE__*) var_name="${env_var#FILE__}" # Evaluate value of environment variable eval "file_path=\$$env_var" # shellcheck disable=SC2154 if file_content=$(tr -d '\r\n' < "$file_path" 2>/dev/null); then export "$var_name"="$file_content" printf "[bootstr-secrets] [%s] set from [%s]\n" "$var_name" "$env_var" else printf "[bootstr-secrets] Error reading file [%s]\n" "$file_path" >&2 fi ;; esac done exec "$@" ``` Example usage in a compose service definition: ```compose.yaml services: core: image: healthchecks/healthchecks:v3.11.2 container_name: healthchecks # .... # Mount custom script volumes: - ./bootstrap_secrets.sh:/bootstrap_secrets.sh:ro # Overwrite entrypoint entrypoint: /bootstrap_secrets.sh # Manually set the command to whatever the image originally had command: ["uwsgi", "/opt/healthchecks/docker/uwsgi.ini"] # Use secrets secrets: [superuser_pass, secret_key, mail_pass, database_pass] environment: FILE__SUPERUSER_PASSWORD: /run/secrets/superuser_pass FILE__SECRET_KEY: /run/secrets/secret_key FILE__EMAIL_HOST_PASSWORD: /run/secrets/mail_pass FILE__DB_PASSWORD: /run/secrets/database_pass ```
Author
Owner

@techsolo12 commented on GitHub (Nov 26, 2025):

@cuu508: Is there an update to this topic? I would appreciate it if we could get this feature in the future.

<!-- gh-comment-id:3581457218 --> @techsolo12 commented on GitHub (Nov 26, 2025): @cuu508: Is there an update to this topic? I would appreciate it if we could get this feature in the future.
Author
Owner

@techsolo12 commented on GitHub (Dec 1, 2025):

Quick feedback: The new security feature is working fine for me. @cuu508: Thank you for implementing it so quickly!

<!-- gh-comment-id:3598255422 --> @techsolo12 commented on GitHub (Dec 1, 2025): Quick feedback: The new security feature is working fine for me. @cuu508: Thank you for implementing it so quickly!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/healthchecks#808
No description provided.