Как передать переменные окружения GitHub Actions Secrets на удаленный сервер для docker-compose?
Иногда самые сложные вопросы имеют самые легкие ответы. Когда мы работаем на локальной машине, нам проще всего взять наши переменные окружения (environment variables) из файла .env при работе с docker-compose. Но ведь в таком виде секреты передавать в репозиторий нельзя! Значит, мы в лучшем случае запишем туда .env.template, где перечислим переменные и, возможно, дадим им некоторые значения по умолчанию для примера.
Очевидно, что сами секреты мы заведем в настройках репозитория, в разделе GitHub Secrets:
Но как их дальше передать на сервер? Первое, что хочется сделать — сформировать на сервере .env файл неким скриптом, но есть путь гораздо проще и чище, давайте используем стандартную команду export, которая в командной среде может присваивать переменную окружения и хранить ее прямо в системе, без каких-либо файлов! Добавим GitHub Action следующего вида:
runs-on: ubuntu-latest
needs: set_up_env
steps:
- name: executing remote ssh commands to set env
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
key: ${{ secrets.SSH_KEY }}
script: |
export DB_ENGINE=${{ secrets.DB_ENGINE }}
export DB_NAME=${{ secrets.DB_NAME }}
export POSTGRES_USER=${{ secrets.POSTGRES_USER }}
export POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}
export DB_HOST=${{ secrets.DB_HOST }}
export DB_PORT=${{ secrets.DB_PORT }}
export SECRET_KEY=${{ secrets.SECRET_KEY }}
export DJANGO_SUPERUSER_PASSWORD=${{ secrets.DJANGO_SUPERUSER_PASSWORD }}
export DJANGO_SUPERUSER_EMAIL=${{ secrets.DJANGO_SUPERUSER_EMAIL }}
export DJANGO_SUPERUSER_USERNAME=${{ secrets.DJANGO_SUPERUSER_USERNAME }}
Также можно на лету генерировать .env файл, если это то, к чему вы больше привыкли:
echo DB_ENGINE=${{ secrets.DB_ENGINE }} > .env
echo DB_NAME=${{ secrets.DB_NAME }} >> .env
echo POSTGRES_USER=${{ secrets.POSTGRES_USER }} >> .env
echo POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} >> .env
echo DB_HOST=${{ secrets.DB_HOST }} >> .env
echo DB_PORT=${{ secrets.DB_PORT }} >> .env
echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
echo DJANGO_SUPERUSER_PASSWORD=${{ secrets.DJANGO_SUPERUSER_PASSWORD }} >> .env
echo DJANGO_SUPERUSER_EMAIL=${{ secrets.DJANGO_SUPERUSER_EMAIL }} >> .env
echo DJANGO_SUPERUSER_USERNAME=${{ secrets.DJANGO_SUPERUSER_USERNAME }} >> .env
Возможно, здесь много повторяющего кода, и хотелось бы записать это одной строкой с одним экспортом, но так, на мой взгляд, проще и понятнее. А также небольшая формула в экселе позволяет это довольно быстро сгенерировать:
Теперь все переменные будут автоматически подставляться в docker-compose.
env_file:
- ./.env
Которая, как известно, сканирует файл .env в поиске переменных. А все можно прочитать в документации:
When you set the same environment variable in multiple files, here’s the priority used by Compose to choose which value to use:
1) Compose file
2) Shell environment variables
3) Environment file
4) Dockerfile
5) Variable is not defined
Сначала env файл, а затем уже переменные Shell. Это позволяет нам на компьютере для тестирования использовать один набор переменных, а для деплоя — другой.