2 changed files with 229 additions and 0 deletions
@ -0,0 +1,8 @@ |
|||||||
|
# Copy this file to .env and fill in values, then run: source .env |
||||||
|
# The defaults below match the Docker container started by setup.sh. |
||||||
|
|
||||||
|
export POSTGRES_HOST=localhost |
||||||
|
export POSTGRES_PORT=5455 |
||||||
|
export POSTGRES_USER=postgres |
||||||
|
export POSTGRES_PASSWORD=postgres |
||||||
|
export POSTGRES_DB=gc_index_relay_dev |
||||||
@ -0,0 +1,221 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
# Local development setup for gc_index_relay. |
||||||
|
# Safe to run multiple times — all steps are idempotent. |
||||||
|
# |
||||||
|
# Requirements: |
||||||
|
# - Docker must already be installed (https://docs.docker.com/engine/install/) |
||||||
|
# - sudo access for apt-get |
||||||
|
# |
||||||
|
# Usage: |
||||||
|
# chmod +x setup.sh |
||||||
|
# ./setup.sh |
||||||
|
|
||||||
|
set -euo pipefail |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# Configuration |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
ERLANG_VERSION="28.4.1" |
||||||
|
ELIXIR_VERSION="1.19.5-otp-28" |
||||||
|
|
||||||
|
POSTGRES_HOST="localhost" |
||||||
|
POSTGRES_PORT="5455" |
||||||
|
POSTGRES_USER="postgres" |
||||||
|
POSTGRES_PASSWORD="postgres" |
||||||
|
POSTGRES_DB="gc_index_relay_dev" |
||||||
|
|
||||||
|
DOCKER_CONTAINER_NAME="gc_age_db" |
||||||
|
AGE_IMAGE="apache/age:release_PG17_1.6.0" |
||||||
|
|
||||||
|
ASDF_DIR="$HOME/.asdf" |
||||||
|
ASDF_VERSION="v0.15.0" |
||||||
|
|
||||||
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# Helpers |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
GREEN='\033[0;32m' |
||||||
|
YELLOW='\033[1;33m' |
||||||
|
RED='\033[0;31m' |
||||||
|
NC='\033[0m' |
||||||
|
|
||||||
|
log() { echo -e "${GREEN}[setup]${NC} $*"; } |
||||||
|
warn() { echo -e "${YELLOW}[ warn]${NC} $*"; } |
||||||
|
err() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; } |
||||||
|
|
||||||
|
require_cmd() { |
||||||
|
command -v "$1" &>/dev/null || err "'$1' is not installed or not on PATH. $2" |
||||||
|
} |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 1. Pre-flight checks |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
log "Starting gc_index_relay local setup..." |
||||||
|
echo |
||||||
|
|
||||||
|
require_cmd docker "Install Docker first: https://docs.docker.com/engine/install/" |
||||||
|
docker info &>/dev/null || err "Docker daemon is not running. Start it and try again." |
||||||
|
log "Docker: $(docker --version)" |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 2. System build dependencies (Debian/Ubuntu/Mint) |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
if command -v apt-get &>/dev/null; then |
||||||
|
log "Installing system build dependencies via apt-get..." |
||||||
|
sudo apt-get update -qq |
||||||
|
sudo apt-get install -y \ |
||||||
|
build-essential \ |
||||||
|
autoconf \ |
||||||
|
libtool \ |
||||||
|
inotify-tools \ |
||||||
|
git \ |
||||||
|
curl |
||||||
|
else |
||||||
|
warn "apt-get not found — skipping system package install." |
||||||
|
warn "Make sure these are installed manually: build-essential autoconf libtool inotify-tools git curl" |
||||||
|
fi |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 3. asdf version manager |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
if [ ! -d "$ASDF_DIR" ]; then |
||||||
|
log "Installing asdf $ASDF_VERSION..." |
||||||
|
git clone https://github.com/asdf-vm/asdf.git "$ASDF_DIR" --branch "$ASDF_VERSION" |
||||||
|
else |
||||||
|
log "asdf already installed at $ASDF_DIR" |
||||||
|
fi |
||||||
|
|
||||||
|
# Source asdf for this script session |
||||||
|
# shellcheck source=/dev/null |
||||||
|
source "$ASDF_DIR/asdf.sh" |
||||||
|
|
||||||
|
# Persist asdf sourcing to the user's shell rc (idempotent) |
||||||
|
add_asdf_to_rc() { |
||||||
|
local rc="$1" |
||||||
|
local line='. "$HOME/.asdf/asdf.sh"' |
||||||
|
if [ -f "$rc" ] && ! grep -qF 'asdf/asdf.sh' "$rc"; then |
||||||
|
echo "" >> "$rc" |
||||||
|
echo "# asdf version manager" >> "$rc" |
||||||
|
echo "$line" >> "$rc" |
||||||
|
log "Added asdf to $rc (will take effect in new shells)" |
||||||
|
fi |
||||||
|
} |
||||||
|
add_asdf_to_rc "$HOME/.bashrc" |
||||||
|
add_asdf_to_rc "$HOME/.zshrc" 2>/dev/null || true |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 4. Erlang |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
asdf plugin add erlang 2>/dev/null || true |
||||||
|
|
||||||
|
if asdf list erlang 2>/dev/null | grep -qF "$ERLANG_VERSION"; then |
||||||
|
log "Erlang $ERLANG_VERSION already installed" |
||||||
|
else |
||||||
|
log "Installing Erlang $ERLANG_VERSION (compiles from source — takes a few minutes)..." |
||||||
|
asdf install erlang "$ERLANG_VERSION" |
||||||
|
fi |
||||||
|
|
||||||
|
asdf global erlang "$ERLANG_VERSION" |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 5. Elixir |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
asdf plugin add elixir 2>/dev/null || true |
||||||
|
|
||||||
|
if asdf list elixir 2>/dev/null | grep -qF "$ELIXIR_VERSION"; then |
||||||
|
log "Elixir $ELIXIR_VERSION already installed" |
||||||
|
else |
||||||
|
log "Installing Elixir $ELIXIR_VERSION..." |
||||||
|
asdf install elixir "$ELIXIR_VERSION" |
||||||
|
fi |
||||||
|
|
||||||
|
asdf global elixir "$ELIXIR_VERSION" |
||||||
|
log "$(elixir --version | grep 'Elixir')" |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 6. Apache AGE database (Docker) |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
if docker ps -q --filter "name=^${DOCKER_CONTAINER_NAME}$" | grep -q .; then |
||||||
|
log "Database container '$DOCKER_CONTAINER_NAME' is already running" |
||||||
|
elif docker ps -aq --filter "name=^${DOCKER_CONTAINER_NAME}$" | grep -q .; then |
||||||
|
log "Restarting existing database container '$DOCKER_CONTAINER_NAME'..." |
||||||
|
docker start "$DOCKER_CONTAINER_NAME" |
||||||
|
else |
||||||
|
log "Starting Apache AGE database container..." |
||||||
|
docker run -d \ |
||||||
|
--name "$DOCKER_CONTAINER_NAME" \ |
||||||
|
-p "${POSTGRES_PORT}:5432" \ |
||||||
|
-e POSTGRES_USER="$POSTGRES_USER" \ |
||||||
|
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ |
||||||
|
-e POSTGRES_DB="$POSTGRES_DB" \ |
||||||
|
"$AGE_IMAGE" |
||||||
|
fi |
||||||
|
|
||||||
|
log "Waiting for database to accept connections..." |
||||||
|
until docker exec "$DOCKER_CONTAINER_NAME" pg_isready -U "$POSTGRES_USER" &>/dev/null; do |
||||||
|
sleep 1 |
||||||
|
done |
||||||
|
log "Database is ready" |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 7. .env file |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
ENV_FILE="$PROJECT_DIR/.env" |
||||||
|
|
||||||
|
if [ ! -f "$ENV_FILE" ]; then |
||||||
|
log "Writing .env with database credentials..." |
||||||
|
cat > "$ENV_FILE" <<EOF |
||||||
|
export POSTGRES_HOST=$POSTGRES_HOST |
||||||
|
export POSTGRES_PORT=$POSTGRES_PORT |
||||||
|
export POSTGRES_USER=$POSTGRES_USER |
||||||
|
export POSTGRES_PASSWORD=$POSTGRES_PASSWORD |
||||||
|
export POSTGRES_DB=$POSTGRES_DB |
||||||
|
EOF |
||||||
|
else |
||||||
|
log ".env already exists — skipping (delete it to regenerate)" |
||||||
|
fi |
||||||
|
|
||||||
|
# Export for the current session so mix setup can connect |
||||||
|
export POSTGRES_HOST POSTGRES_PORT POSTGRES_USER POSTGRES_PASSWORD POSTGRES_DB |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# 8. Mix setup (deps + database) |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
cd "$PROJECT_DIR" |
||||||
|
|
||||||
|
log "Installing Hex and Rebar (if needed)..." |
||||||
|
mix local.hex --force --if-missing |
||||||
|
mix local.rebar --force --if-missing |
||||||
|
|
||||||
|
log "Fetching dependencies..." |
||||||
|
mix deps.get |
||||||
|
|
||||||
|
log "Running mix setup (compile + create DB + migrate)..." |
||||||
|
mix setup |
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
# Done |
||||||
|
# --------------------------------------------------------------------------- |
||||||
|
|
||||||
|
echo |
||||||
|
log "Setup complete!" |
||||||
|
echo |
||||||
|
echo " To start the server:" |
||||||
|
echo " source .env" |
||||||
|
echo " mix phx.server" |
||||||
|
echo |
||||||
|
echo " Then open: http://localhost:4000" |
||||||
|
echo " REST API: http://localhost:4000/api/events" |
||||||
|
echo |
||||||
|
warn "Open a new terminal (or run 'source ~/.bashrc') for asdf to work in future sessions." |
||||||
Loading…
Reference in new issue