0

我正在努力用 docker、symfony、教义和 swarm secrets 来成为工作主管。

在我的 Dockerfile 中,我正在这样做:

FROM php:${PHP_VERSION}-fpm-alpine
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisor.conf"]

所以我启动了如下所示的主管:

我的主要程序:

[program:php]
command=docker-entrypoint.sh "php-fpm"
autostart=true
autorestart=true

它以入口点启动 PHP。在这个入口点,我只在 prod 中使用 swarm secret:

 if [ "$APP_ENV" = 'prod' ]; then
    file_env DATABASE_URL
    file_env MESSENGER_TRANSPORT_DSN
  fi

  php bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration

在入口点内,命令 bin/console 运行良好。如果我处于开发模式,它会使用我的 .env 文件中的本地 database_url,如果我处于生产模式,它会使用 docker compose 中定义的秘密。

当我在主管中有第二个程序时会出现问题,如下所示:

[program:messenger-consume]
command=bash -c "export APP_ENV=%(ENV_APP_ENV)s && /usr/local/bin/launch.sh"
user=root

和 launch.sh :

if [ "$APP_ENV" = "prod" ]; then
  php /srv/app/bin/console messenger:consume async --time-limit=3600 --memory-limit=128M -vv
fi

在这里它失败了一个看起来像这样的 Doctrine 错误:

Access denied for user 'myname'@'10.0.1.4' (using password: YES)

实际上,'myname' 是我的 database_url dsn(用于学说)的 .env(用于开发环境)中的默认值。

这个主管问题与我不能自己执行教条命令的事实有关。我的意思是当我跑步时:

docker exec -i $(docker ps -q -f name="php*") sh

连接到我的容器,在容器内部之后我想执行如下操作:

./bin/console doctrine:migrations:migrate

它也不起作用(与主管相同的错误)。

总而言之, docker swarm secrets 在我自己或主管执行时不会“计算”,他们正在读取 .env 中的默认值,而不是读取 swarm secret 中的值......我不知道如何解决这个问题。我试图添加到 docker exec -e DATABASE_URL=/run/secrets/doctrine_dsn 但它也不起作用(除非我给出秘密原则 dsn 的真实值)。

任何帮助都会非常感谢

4

2 回答 2

0

我终于自己找到了答案。

我需要在需要 env var 的每个脚本中添加此函数:

file_env() {
    local var="$1"
    local fileVar="${var}_FILE"
    local def="${2:-}"
    if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
        echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
        exit 1
    fi
    local val="$def"
    if [ "${!var:-}" ]; then
        val="${!var}"
    elif [ "${!fileVar:-}" ]; then
        val="$(< "${!fileVar}")"
    fi
    export "$var"="$val"
    unset "$fileVar"
}

在Supervisor中,我需要导出原始的env var名称才能通过在命令中执行以下操作来“重新计算”:

bash -c "export DATABASE_URL_FILE=%(ENV_DATABASE_URL_FILE)s && /usr/local/bin/launch.sh"

我什么都不懂,但我认为该函数正在导出 env var,但暂时只能在脚本中使用。所以每次我需要自己使用一个 swarm secret(在 docker compose 中这样声明:DATABASE_URL_FILE=/run/secrets/doctrine_dsn)我需要将该函数应用于相对环境变量。我希望它很清楚:)

于 2020-10-29T08:21:01.443 回答
0

看起来最初的答案来自早期的 WordPress 解决方案,不幸的是,它只是将秘密转换为环境变量。这违背了使用 Docker Secrets 的目的:防止秘密意外泄露。环境变量通常会在调试转储、日志记录和监控系统以及子进程中泄露。最好避免将秘密放入环境变量中。

WordPress 的当前方法提供了更安全的解决方案:

function getenv_docker($env, $default) {
    if ($fileEnv = getenv($env . '_FILE')) {
        return rtrim(file_get_contents($fileEnv), "\r\n");
    }
    else if (($val = getenv($env)) !== false) {
        return $val;
    }
    else {
        return $default;
    }
}
于 2022-02-27T04:17:46.207 回答