Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ _build/prod/rel/flick/bin/flick remote

In that shell, run `:observer_cli.start()`. Press `q` and then Enter to quit observer_cli. Quitting leaves the node running. Never run `System.stop/0` or `:init.stop/0` in the remote shell, because they stop production. Leave the shell with Ctrl+C and then `a`, which closes only the remote shell. The release also includes `:recon` for one-off queries such as `:recon.proc_count(:memory, 10)`.

Phoenix LiveDashboard runs at `/admin/dashboard`, behind the same basic auth as `/admin/ballots`. In development, the credentials are `flick-admin` / `unsafe-password`. In production, they come from `BASIC_AUTH_ADMIN_USERNAME` and `BASIC_AUTH_ADMIN_PASSWORD`. Its Processes page shows each process's dictionary and stack trace, but not its state. It still exposes the node's internals, so never move it out of the `/admin` scope. Its Ecto Stats page reads table sizes, index usage, and locks through `ecto_psql_extras` over the private network. It needs no remote shell and starts no second VM, so try it before observer_cli. Use observer_cli when the web endpoint cannot serve a LiveView.
Phoenix LiveDashboard runs at `/admin/dashboard`, behind the same basic auth as `/admin/ballots`. In development, the credentials are `flick-admin` / `unsafe-password`. In production, they come from `BASIC_AUTH_ADMIN_USERNAME` and `BASIC_AUTH_ADMIN_PASSWORD`. Its Processes page shows each process's dictionary and stack trace, but not its state. It still exposes the node's internals, so never move it out of the `/admin` scope. Its Ecto Stats page reads table sizes, index usage, and locks through `ecto_psql_extras` over the private network. It needs no remote shell and starts no second VM, so try it before observer_cli. Its "outliers" and "calls" tabs need `pg_stat_statements`, so they work only on a server that preloads the library. Local and CI Postgres do not, and their migration skips the extension with a notice. Use observer_cli when the web endpoint cannot serve a LiveView.

`rel/env.sh.eex` binds EPMD and Erlang distribution to loopback and names the node `flick@localhost`, so only a shell inside the container can reach it. Keep it that way. Never expose distribution on Render's network, and never set a custom release cookie. The default cookie never leaves the container. A custom cookie would sit in Render's environment variables, and its only use is connecting from outside, where a cookie grants full code execution on the node.

Expand Down
27 changes: 27 additions & 0 deletions priv/repo/migrations/20261020164842_enable_pg_stat_statements.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule Flick.Repo.Migrations.EnablePgStatStatements do
use Ecto.Migration

# LiveDashboard's Ecto Stats needs this extension for its "outliers" and
# "calls" tabs. The extension's view raises an error unless the server
# preloads the library. Local and CI Postgres do not preload it.
#
# Only a superuser can read `shared_preload_libraries`, so the block creates
# the extension and reads the view once. On an error, the block rolls back
# and leaves no extension. A diagnostics extension must never block a deploy.
def change do
# The raw SQL touches no table. The down step reverses it.
# excellent_migrations:safety-assured-for-next-line raw_sql_executed
execute """
DO $$
BEGIN
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
PERFORM 1 FROM pg_stat_statements LIMIT 1;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'pg_stat_statements skipped: %', SQLERRM;
END
$$
""",
"DROP EXTENSION IF EXISTS pg_stat_statements"
end
end
Loading