В тази поредица за Makefiles разгледахме „как да използваме заместващи символи“ и „използване на предварително зададени настройки на приложения“, вместо да се налага да предаваме стойности.

Има още една техника, която използваме за контролиране на Makefiles:

Dotenv (.env файлове)

Ние обичаме любовта, любовта използваме .env файлове, за да конфигурираме нашите приложения. Ако не сте запознати с тях, същността е, че те указват ключове и стойности на променливи на средата в много прост файлов формат. Например, за да контролирате LOG_LEVEL var, можете да използвате:

LOG_LEVEL=info

И след това заредете това при стартиране на приложението (повечето езици имат някакъв пакет dotenv за това).

Въпреки че нашите практики за пълна конфигурация са тема за друг ден, ние имаме няколко правила, които използваме във всички наши проекти:

  • Цялата конфигурация чрез променливи на средата (не зареждайте файлове, не говорете с външни магазини)
  • Винаги използвайте .env файлове.
  • Никога не проверявайте .env файлове.
  • Имайте само един .env файл (без каскадни файлове въз основа на средата).
  • .env има предимство пред стойностите в средата.

Някои от тези решения без съмнение са спорни, но целта е .env файловете да осигурят недвусмислено, канонично съхранение на променливи на локалната среда, а нелокалните среди да използват каквито и да е собствени механизми за инжектиране на променливи на средата, преди да започнат процеса (Heroku Config Vars, AWS параметър Магазин, свързан към ECS и т.н.).

Направете и .env

Това „.env е каноничното хранилище на локалната среда“ е толкова лесно и стандартно, че дори можем да настроим Make да го използва!

Поставяме този блок в горната част на Makefile - той търси .env файл и ако има такъв, ще зададе Make променливи от него:

ifneq (,$(wildcard ./.env))
    include .env
    export
endif

Къде е полезно това? Е, да приемем, че искате да се свържете с базата данни на вашето локално приложение. Можем да поставим този URL адрес на базата данни във файла .env:

DATABASE_URL=postgres://appuser:pass@localhost:13005/myapp

(Винаги управляваме базите си данни през docker-compose и използваме различни портове за различни проекти - никога няма да се върнете към :5432, след като започнете да го правите по този начин)

Сега в нашия Makefile можем да настроим цел за свързване чрез psql. Обърнете внимание на целта cmd-exists-% от миналата седмица

ifneq (,$(wildcard ./.env))
    include .env
    export
endif
cmd-exists-%:
    @hash $(*) > /dev/null 2>&1 || \
        (echo "ERROR: '$(*)' must be installed and available on your PATH."; exit 1)
psql: cmd-exists-psql
    psql "${DATABASE_URL}"

Сега го стартирайте от командния ред:

$ make psql
 psql "postgres://appuser:pass@localhost:13005/myapp"
 psql (12.2, server 11.4 (Debian 11.4-1.pgdg90+1))
 Type "help" for help.

Докер също!

Още едно хубаво нещо за този супер-гъвкав файл .env! Docker и docker-compose могат да приемат параметър --env-file и като запазите всичко в един .env, можете да споделяте една и съща конфигурация между вашето локално приложение, Make и Docker build.

Ето коригиран фрагмент от Makefile и примерна Docker команда:

ifneq (,$(wildcard ./.env))
    include .env
    export
    ENV_FILE_PARAM = --env-file .env
endif
docker-server:
    docker run --rm -it -p $(PORT):$(PORT) $(ENV_FILE_PARAM)

$PORT, разбира се, е дефиниран във файла .env :)

Повече следващия път

По-късно тази седмица ще говорим за още едно хубаво нещо, което правим с Make, за да стандартизираме още повече. Ако пишете някакъв JavaScript в частност, той променя живота ви.

И накрая, ще приключим тази поредица след една седмица, като говорим за защо сме ол-ин в Make като task runner (ако се опитахме да ви продадем в това в първата публикация, вие вероятно бихте са ни игнорирали).