Примеры
Названия всех команд лишь для примера у вас вероятнее всего будет свой вариант.
Локальная разработка
🍪 JavaScript (Vue, React, Angular и др.)
Практически любой web проект содержит package.json и в нём есть scripts, где описаны разные команды, для сборки, для запуска и отладки локально. Выглядит примерно так:
...
"scripts": {
"serve": "vite",
...
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Установите конфигурацию для проекта
tuna secrets setup. - Отредактируйте
package.jsonи добавите обёрткуtuna secrets run, должно получиться примерно так:
...
"scripts": {
"serve": "tuna secrets run --watch -- vite",
...
- Запустите приложение как обычно
yarn serveилиnpm run serve
🐹 Go (Golang)
Go-проекты обычно запускаются через go run или make:
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Выполните
tuna secrets setup. - Запустите приложение с обёрткой:
tuna secrets run --watch -- go run ./cmd/server
Пример Makefile:
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
@tuna secrets run --watch -- go run ./cmd/server
🦀 Rust (Rocket, Actix и др.)
Rust-проекты чаще всего используют cargo:
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Выполните
tuna secrets setup. - Запустите приложение с обёрткой:
tuna secrets run --watch -- cargo run
Пример Makefile:
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
@tuna secrets run --watch -- cargo run
🥠 Node.js серверный проект (Express, Fastify и др.)
Node.js backend обычно также использует package.json, например:
...
"scripts": {
"dev": "node server.js",
...
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Установите конфигурацию для проекта
tuna secrets setup. - Отредактируйте
package.json, добавив обёртку:
...
"scripts": {
"dev": "tuna secrets run --watch -- node server.js",
...
- Запустите приложение
yarn devилиnpm run dev.
🐍 Python (Flask, Django и др.)
Python-проекты часто запускаются через python, manage.py или Makefile.
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Установите конфигурацию для проекта добавив обёртку
tuna secrets setup. - Оберните команду запуска:
tuna secrets run --watch -- python app.py
Если у вас Django:
tuna secrets run --watch -- python manage.py runserver
Если у вас Makefile:
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
@tuna secrets run --watch -- python manage.py runserver
- Запустите приложение этой командой.
🐘 PHP (Laravel, Symfony и др.)
Обычно используется встроенный веб-сервер PHP:
php -S localhost:8000 -t public
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Установите конфигурацию для проекта
tuna secrets setup. - Запустите сервер через обёртку
tuna secrets run:
tuna secrets run --watch -- php -S localhost:8000 -t public
Если у вас Laravel:
tuna secrets run --watch -- php artisan serve
Пример Makefile:
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
@tuna secrets run --watch -- php artisan serve
☕ Java/Kotlin (Spring Boot, Micronaut и др.)
Такие проекты часто используют Gradle или Maven:
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Установите конфигурацию для проекта
tuna secrets setup. - Оберните команду запуска:
Для Gradle:
tuna secrets run --watch -- ./gradlew bootRun
Для Maven:
tuna secrets run --watch -- mvn spring-boot:run
Пример Makefile:
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
@tuna secrets run --watch -- mvn spring-boot:run
- Запустите приложение как обычно.
🪟 C#/.NET (ASP.NET Core и др.)
Проекты на .NET запускаются через dotnet run:
- Перейдите в каталог с проектом
cd ~/path/to/your/project. - Выполните
tuna secrets setup. - Запустите приложение с обёрткой:
tuna secrets run --watch -- dotnet run
Пример Makefile (на Linux/macOS):
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
@tuna secrets run --watch -- dotnet run
CI/CD
🦊 Gitlab CI
Создайте сервисные ключи для нужных конфигураций и сохраните ключ в Gitlab ci variables.
Предположим, у вас есть проект myproj в нём есть окружение prod, создайте сервисный ключ и сохраните его в переменную TUNA_API_KEY_MYPROJ_PROD в Gitlab variables. Ниже пример того как это может выглядеть в Job:
- Переменные окружения
- Флаги
- Обёртка run
production:
extends: [.base]
environment:
name: prod
variables:
TUNA_API_KEY: $TUNA_API_KEY_MYPROJ_PROD
TUNA_SECRETS_PROJECT: $CI_PROJECT_NAME
TUNA_SECRETS_CONFIG: $CI_ENVIRONMENT_NAME
TUNA_SECRETS_FORMAT: env
TUNA_SECRETS_NO_FILE: true
before_script:
- source <(tuna secrets download)
script:
- goreleaser release
production:
extends: [.base]
environment:
name: prod
before_script:
- source <(tuna --api-key=${TUNA_API_KEY_MYPROJ_PROD} secrets download --project=${CI_PROJECT_NAME} --config=${CI_ENVIRONMENT_NAME} --format=env --no-file)
script:
- goreleaser release
production:
extends: [.base]
environment:
name: prod
variables:
TUNA_API_KEY: $TUNA_API_KEY_MYPROJ_PROD
TUNA_SECRETS_PROJECT: $CI_PROJECT_NAME
TUNA_SECRETS_CONFIG: $CI_ENVIRONMENT_NAME
script:
- tuna secrets run -- goreleaser release
Секреты попадают только в окружение процесса: ни файла в рабочем каталоге, ни source в истории джобы. Код выхода goreleaser становится кодом выхода джобы.
Заметьте, что project и config мы получаем прямо из окружения, это возможно, если имя проекта в Gitlab и Tuna Secrets совпадают, а также environment.name в Gitlab Job соответствует алиасу конфигурации.
🐱 GitHub Actions
Создайте сервисные ключи для нужных конфигураций и сохраните ключ в GitHub Secrets.
Предположим, у вас есть проект myproj в нём есть окружение prod, создайте сервисный ключ и сохраните его в переменную TUNA_API_KEY_MYPROJ_PROD в GitHub Secrets. Ниже пример того как это может выглядеть в Job:
- Переменные окружения
- Флаги
- Обёртка run
name: Release
on:
push:
tags:
- "v*"
jobs:
production:
runs-on: ubuntu-latest
env:
TUNA_API_KEY: ${{ secrets.TUNA_API_KEY_MYPROJ_PROD }}
TUNA_SECRETS_PROJECT: ${{ github.event.repository.name }}
TUNA_SECRETS_CONFIG: prod
TUNA_SECRETS_FORMAT: env
TUNA_SECRETS_NO_FILE: true
steps:
- uses: actions/checkout@v4
- run: |
source <(tuna secrets download)
goreleaser release
name: Release
on:
push:
tags:
- "v*"
jobs:
production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
source <(tuna --api-key=${{ secrets.TUNA_API_KEY_MYPROJ_PROD }} secrets download --project=${{ github.event.repository.name }} --config=prod --format=env --no-file)
goreleaser release
name: Release
on:
push:
tags:
- "v*"
jobs:
production:
runs-on: ubuntu-latest
env:
TUNA_API_KEY: ${{ secrets.TUNA_API_KEY_MYPROJ_PROD }}
TUNA_SECRETS_PROJECT: ${{ github.event.repository.name }}
TUNA_SECRETS_CONFIG: prod
steps:
- uses: actions/checkout@v4
- run: tuna secrets run -- goreleaser release
Заметьте, что project = github.event.repository.name мы получаем прямо из окружения, это возможно, если имя проекта в GitHub и Tuna Secrets совпадают, config - задаётся явно.
🧰 Отдельные секреты в скриптах
Когда джобе нужен один секрет, выгружать всю конфигурацию незачем. Флаг --plain печатает значение без перевода строки в конце, поэтому его удобно подставлять прямо в команду:
publish:
script:
- docker login -u "$CI_REGISTRY_USER" -p "$(tuna secrets get REGISTRY_PASSWORD --plain)" "$CI_REGISTRY"
Флаг -o json есть у всех команд, включая запись, — это то, что нужно скриптам:
rotate-token:
script:
- openssl rand -hex 32 | tuna secrets set API_TOKEN
- tuna secrets get API_TOKEN -o json | jq -r '.API_TOKEN.updated_at'
Ротация требует сервисного ключа с доступом write.
А вот проверка, что в stage и prod не оказалось одинаковых паролей. Она работает с отпечатками, а не со значениями, поэтому результат не страшно оставить в логе джобы:
check-secrets:
script:
- tuna secrets list -c stage -o json | jq -r 'to_entries[] | "\(.key) \(.value.fingerprint)"' > stage.txt
- tuna secrets list -c prod -o json | jq -r 'to_entries[] | "\(.key) \(.value.fingerprint)"' > prod.txt
- comm -12 stage.txt prod.txt
🧵 Bitbucket Pipelines
Создайте сервисные ключи для нужных конфигураций и сохраните ключ в Bitbucket Pipelines variables.
Предположим, у вас есть проект myproj в нём есть окружение prod, создайте сервисный ключ и сохраните его в переменную TUNA_API_KEY_MYPROJ_PROD в Bitbucket Pipelines variables. Ниже пример того как это может выглядеть в Job:
- Переменные окружения
- Флаги
pipelines:
tags:
"v*":
- step:
name: Production Build
deployment: prod
script:
- export TUNA_API_KEY=$TUNA_API_KEY_MYPROJ_PROD
- export TUNA_SECRETS_PROJECT=$BITBUCKET_REPO_SLUG
- export TUNA_SECRETS_CONFIG=prod
- export TUNA_SECRETS_FORMAT=env
- export TUNA_SECRETS_NO_FILE=true
- source <(tuna secrets download)
- goreleaser release
pipelines:
tags:
"v*":
- step:
name: Release
deployment: prod
script:
- source <(tuna --api-key=$TUNA_API_KEY_MYPROJ_PROD secrets download --project=$BITBUCKET_REPO_SLUG --config=prod) --format=env --no-file)
- goreleaser release
Заметьте, что project = $BITBUCKET_REPO_SLUG мы получаем прямо из окружения, это возможно, если имя проекта в BITBUCKET_REPO_SLUG и Tuna Secrets совпадают, config - задаётся явно.