Previously, the deployment timestamp was set to DateTime.utc_now() when
the application started, which meant it would always show as recent in
k8s environments where pods are recreated on each deployment.
This commit:
- Updates Release.init() to check for DEPLOYED_AT environment variable
- Falls back to current time if env var is not set (backwards compatible)
- Adds proper ISO8601 timestamp parsing with error handling
- Updates GitHub Actions deploy workflow to set DEPLOYED_AT during deployment
- Creates k8s patch file for future manual deployments
The deployment timestamp will now persist across pod restarts in k8s,
showing the actual deployment time rather than pod startup time.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add MigrationLock module using PostgreSQL advisory locks
- Prevent concurrent migrations across multiple nodes
- Update Release.migrate to use distributed lock when cluster enabled
- Disable auto-migrations in cluster mode to avoid race conditions
- Add init container configuration for Kubernetes deployments
- Document migration strategies in k8s/README-migrations.md
This ensures only one node runs database migrations at a time, preventing
conflicts and race conditions in distributed deployments.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move Redis connection settings to runtime.exs only
- Remove localhost:6379 hardcoded values that were overriding runtime config
- Keep only non-environment-dependent Exq settings in compile-time config
- Fixes Exq trying to connect to localhost instead of Kubernetes Redis service
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed kubectl deployment command to use :latest tag
- Updated k8s deployment manifests to use ghcr.io/aprsme/aprs.me:latest
- This ensures k3s always pulls the most recent image from GitHub Container Registry
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit introduces a complete setup for deploying the Phoenix application
to a K3s Kubernetes cluster, along with a GitHub Actions workflow for
automated builds and deployments.
Key changes include:
- **Kubernetes Manifests (`k8s/`)**:
- Namespace (`aprs-app`) for isolating application resources.
- PostgreSQL setup: PersistentVolumeClaim, Deployment, and Service.
- Application setup: Deployment (with init container for migrations) and
Service (NodePort).
- An example secrets file (`k8s/secrets.yaml.example`) for configuration.
- `.gitignore` updated to exclude `k8s/secrets.yaml`.
- **GitHub Actions Workflow (`.github/workflows/deploy-k3s.yaml`)**:
- Builds the Docker image on pushes to the main branch.
- Pushes the image to GitHub Container Registry (GHCR).
- Deploys the application to K3s by applying the manifests.
- Dynamically updates the application deployment with the correct image tag.
- Requires `KUBE_CONFIG_DATA` GitHub secret for K3s authentication.
- **Application Configuration (`config/runtime.exs`)**:
- Commented out `libcluster` configuration specific to Fly.io to prevent
issues in a standard K3s environment.
- **Documentation (`README.md`)**:
- Added a new "Kubernetes (K3s) Deployment" section detailing:
- Prerequisites and initial setup (GitHub & K8s secrets).
- Workflow overview.
- Application configuration notes (health checks, migrations).
- Instructions for accessing the application.
This setup provides a robust foundation for CI/CD and running the
application in a self-hosted K3s environment.