A secret in an environment variable is visible in docker inspect, in the process environment and in any crash dump that prints the environment.
services:
php:
secrets: [db_password]
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true
# $password = trim(file_get_contents(getenv('DB_PASSWORD_FILE')));
The _FILE convention is what several official images already use, so the pattern is familiar even if the application grows a helper for it. Secrets are mounted in a tmpfs and never touch the host disk, which is the property environment variables cannot offer. On a single host without swarm the same discipline works with a bind-mounted file and restrictive permissions, which makes the eventual migration nothing.