Skip to content

Instantly share code, notes, and snippets.

@claytongentry
Last active July 7, 2025 10:55
Show Gist options
  • Select an option

  • Save claytongentry/fa714a7bd11432e96c71e0e71f383386 to your computer and use it in GitHub Desktop.

Select an option

Save claytongentry/fa714a7bd11432e96c71e0e71f383386 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# bootstrap_asdf_prebuilt.sh – pulls binary OTP builds, so no C tool-chain needed
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
PG_VERSION="17"
PG_CLUSTER="main"
PG_SUPERUSER="postgres" # Default superuser name
PG_PASSWORD="postgres" # Custom password for superuser
# 1. Runtime-only libs (<< 10 MB total)
apt-get update -qq
apt-get install -y --no-install-recommends libssl3 zlib1g libncurses6
rm -rf /var/lib/apt/lists/*
# 2. asdf (same as before, but no gcc/make)
git clone -q https://github.com/asdf-vm/asdf.git /opt/asdf --branch v0.14.1
echo '. /opt/asdf/asdf.sh' >> /etc/bash.bashrc
. /opt/asdf/asdf.sh
# 3. **Pre-built** plugin for Erlang
asdf plugin add erlang https://github.com/michallepicki/asdf-erlang-prebuilt-ubuntu-24.04.git || true
asdf plugin add elixir
asdf plugin add node https://github.com/asdf-vm/asdf-nodejs.git
# 4. Honour your .tool-versions file
asdf install
asdf reshim
echo "🔥 OTP and Elixir installed"
mix archive.install github hexpm/hex branch latest --force
mix local.rebar rebar3 deps/rebar3/rebar3 --force
log() {
local level="$1"
local message="$2"
case "$level" in
info) echo -e "\033[1;34m▶\033[0m $message" ;;
error) echo -e "\033[1;31m✖\033[0m $message" ;;
success) echo -e "\033[1;32m✓\033[0m $message" ;;
*) echo -e "\033[1;34m▶\033[0m $message" ;;
esac
}
# Helper functions
is_systemd() {
[ "$(ps -o comm= -p 1)" = "systemd" ]
}
wait_for_service() {
local service="$1"
local check_command="$2"
local max_attempts=${3:-60}
local attempt=1
log info "Waiting for $service to become ready..."
while ! eval "$check_command" >/dev/null 2>&1; do
if [ "$attempt" -ge "$max_attempts" ]; then
log error "$service failed to start after $max_attempts attempts"
return 1
fi
sleep 1
attempt=$((attempt+1))
done
log success "$service is ready"
}
# -------------------------------------------------
# Install PostgreSQL
# -------------------------------------------------
log info "Installing PostgreSQL ${PG_VERSION}"
sudo apt-get update -qq
## bs
sudo apt install curl ca-certificates
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
sudo apt update
# end bs
sudo DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
"postgresql-$PG_VERSION" \
"postgresql-client-$PG_VERSION" \
"postgresql-$PG_VERSION-pgvector"
# Create or start PostgreSQL cluster
if ! sudo pg_lsclusters | grep -q "^$PG_VERSION\s\+$PG_CLUSTER"; then
log info "Creating cluster ${PG_VERSION}/${PG_CLUSTER}"
sudo pg_createcluster "$PG_VERSION" "$PG_CLUSTER" --start
else
log info "Starting PostgreSQL service"
if is_systemd && command -v systemctl >/dev/null; then
log info "Using systemctl to start PostgreSQL"
sudo systemctl enable --now "postgresql@$PG_VERSION-$PG_CLUSTER.service" \
|| sudo systemctl enable --now postgresql.service
elif command -v service >/dev/null; then
log info "Using service command to start PostgreSQL"
sudo service postgresql start
else
log info "Using pg_ctlcluster to start PostgreSQL"
sudo pg_ctlcluster "$PG_VERSION" "$PG_CLUSTER" start
fi
fi
# Reload PostgreSQL to apply any config changes
sudo pg_ctlcluster "$PG_VERSION" "$PG_CLUSTER" reload
# Configure PostgreSQL superuser password and authentication
log info "Configuring PostgreSQL superuser"
# Run psql commands through a sudo to the postgres user to bypass password authentication
# Note: This works because PostgreSQL's default trust model allows the postgres system user
# to connect as the postgres database user without a password
sudo -u postgres bash -c "psql -c \"ALTER USER $PG_SUPERUSER WITH PASSWORD '$PG_PASSWORD';\""
sudo -u postgres bash -c "psql -c \"CREATE ROLE podstock WITH LOGIN SUPERUSER CREATEDB PASSWORD 'postgres';\""
# Get the pg_hba.conf path using the same method
PG_HBA_FILE=$(sudo -u postgres bash -c "psql -qtAc 'SHOW hba_file;'")
log info "Updating PostgreSQL authentication methods in $PG_HBA_FILE"
# Change local authentication method for superuser from peer/ident to md5
sudo sed -i "s/^local\s\+all\s\+$PG_SUPERUSER\s\+\(peer\|ident\|trust\)/local all $PG_SUPERUSER md5/" "$PG_HBA_FILE"
# Make sure we have md5 authentication for all users
if ! grep -q "^local\s\+all\s\+all\s\+md5" "$PG_HBA_FILE"; then
echo "local all all md5" | sudo tee -a "$PG_HBA_FILE" >/dev/null
fi
# Apply configuration changes
sudo pg_ctlcluster "$PG_VERSION" "$PG_CLUSTER" reload
# Wait for PostgreSQL to be ready
wait_for_service "PostgreSQL" "pg_isready -h localhost -U postgres -q"
mix compile --force
MIX_ENV=test mix ecto.setup
@claytongentry
Copy link
Author

claytongentry commented Jul 7, 2025

Expectations:

  1. A .tool-versions like
erlang 28.0.1
elixir 1.18.4-otp-28
node 24.0.1
  1. A copy of rebar3
mkdir deps/rebar3 # Just need a place to put it.
curl https://s3.amazonaws.com/rebar3/rebar3 > deps/rebar3/rebar3 && chmod +x deps/rebar3/rebar3
  1. All your dependencies in the repo 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment