4.3 KiB
You are absolutely right. My previous example was "Tutorial Mode" (easy to start), not "Professional/Solid Mode".
For a "Solid Practice" workflow, you should never commit credentials to reshape.toml. Since you are already using SOPS, we should leverage it to inject the credentials at runtime.
Here is the Professional "Rustacean" Workflow using sops, just, and environment variables.
1. The Strategy
.env.enc(Encrypted): Holds thePOSTGRES_PASSWORDandPOSTGRES_USER.reshape.toml(Generic): Contains only structure (host, port, db name), no secrets.Justfile(The Glue): Unwraps the secrets from SOPS and injects them as environment variables (PGPASSWORD) which the underlying Rust Postgres driver (used by Reshape) should respect.
2. Implementation
Step A: Configure .env and Encrypt it
Create your .env (or edit your existing one) to include the standard Postgres environment variables.
# .env (Local unencrypted version for setup)
POSTGRES_USER=bootcamp
POSTGRES_PASSWORD=my_super_secure_password
POSTGRES_DB=pizzeria
# Standard env var that libpq/rust-postgres clients read automatically
PGPASSWORD=my_super_secure_password
PGUSER=bootcamp
PGHOST=localhost
Encrypt it with SOPS:
(Assuming you ran just setup-secrets from my previous answer)
sops --encrypt --age $(grep -oP "public key: \K.*" .config/keys.txt) --input-type
dotenv --output-type dotenv .env > .env.enc
Add .env to .gitignore. Commit .env.enc.
Step B: Clean reshape.toml
Remove the credentials from the configuration file.
# reshape.toml
[database]
host = "localhost"
port = 5432
name = "pizzeria"
# username = ... <-- REMOVE THESE
# password = ... <-- REMOVE THESE
[migrations]
directory = "migrations"
Step C: Update Justfile (The Magic)
We will use sops exec-env to inject the PGPASSWORD variable into the environment before reshape starts.
How this works:
Most Rust database tools (including those using tokio-postgres which Reshape likely uses) will look for standard environment variables like PGPASSWORD or PGUSER if they are missing from the explicit config.
set dotenv-load
# Wrapper to run commands with decrypted secrets
with-secrets cmd:
sops exec-env .env.enc "{{cmd}}"
# ---------------------------------------------------------
# DATABASE MIGRATION COMMANDS (Using Sops)
# ---------------------------------------------------------
# Init: Starts DB and runs migrations securely
init: up
@echo "Waiting for Postgres..."
@sleep 2
just migrate
# Migrate: Injects PGPASSWORD/PGUSER from .env.enc -> reshape
migrate:
@echo "Applying migrations..."
# We explicitly export PGUSER/PGPASSWORD from the Sops env for Reshape
sops exec-env .env.enc -- reshape migrate
# Create new migration
add name:
reshape migration create {{name}}
# Undo/Abort
undo:
sops exec-env .env.enc -- reshape migration abort
# ---------------------------------------------------------
# INFRASTRUCTURE
# ---------------------------------------------------------
up:
# Docker also needs the secrets to start the container
just with-secrets "docker-compose up -d"
down:
docker-compose down
tui:
# Gobang also needs secrets
just with-secrets "gobang -h localhost -p 5432 -d ${POSTGRES_DB}"
3. The "Paranoid" Alternative (Template Rendering)
If reshape (in some specific version) decides to ignore environment variables and strictly demands a password in reshape.toml, the "Solid" pattern is Config Generation.
You would treat reshape.toml as a template.
- Create
reshape.toml.tmpl(with placeholders like${POSTGRES_PASSWORD}). - Add
reshape.tomlto.gitignore. - Update
Justfileto render it on the fly:
# Justfile (Alternative "Template" approach)
migrate:
# 1. Decrypt env
# 2. Use envsubst to replace vars in template -> create real toml
# 3. Run reshape
# 4. Delete real toml (cleanup)
sops exec-env .env.enc -- bash -c "envsubst < reshape.toml.tmpl > reshape.toml && reshape migrate && rm reshape.toml"
My Recommendation: Try the Environment Variable (Step C) method first. It is cleaner, standard for "Cloud Native" apps, and doesn't involve creating/deleting temporary files. Only use the Template method if the tool forces you to.