This commit includes several critical fixes and optimizations: ## Production Buffer Overflow Fix - Fixed telemetry_vals data type conversion from strings to integers - Enhanced put_telemetry_fields() with robust type conversion logic - Handles mixed data types (string, integer, float) gracefully - Prevents PacketConsumer GenServer crashes that caused buffer overflow - Processes telemetry from both data_extended and top-level attrs ## Test Suite Performance Optimization - Improved test execution speed by 48% (43.2s → 24.1s) - Increased parallelization: max_cases from 16 to 48 - Optimized database connections and reduced timeouts - Tagged slow tests and exclude them by default for fast development - Fixed device seeding to only run when needed - Enhanced log capture for packet consumer tests ## Code Quality Improvements - Fixed handle_info clause grouping in LeaderElection - Ensures mix compile --warnings-as-errors passes - Added comprehensive telemetry conversion tests - Improved test reliability and reduced flakiness ## Infrastructure Updates - Added migration init container to StatefulSet for automatic schema updates - Disabled AUTO_MIGRATE in main container (handled by init container) - Created .test-commands with helpful test aliases This resolves production stability issues and significantly improves development workflow. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|---|---|---|
| .cursor/rules | ||
| .github/workflows | ||
| .kiro/steering | ||
| assets | ||
| config | ||
| docs | ||
| lib | ||
| priv | ||
| rel | ||
| scripts | ||
| test | ||
| vendor | ||
| .credo.exs | ||
| .dialyzer_ignore.exs | ||
| .dockerignore | ||
| .formatter.exs | ||
| .gitignore | ||
| .gitmodules | ||
| .test-commands | ||
| .tool-versions | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| Dockerfile | ||
| fly.toml | ||
| horusec-config.json | ||
| LICENSE | ||
| mix.exs | ||
| mix.lock | ||
| README.md | ||
| security-policy.json | ||
| test-docker-build.sh | ||
| tsconfig.json | ||
Aprs
Prerequisites
Before setting up the project, ensure you have the following installed:
- Elixir 1.17+
- Erlang/OTP
- PostgreSQL with PostGIS extension
Setup
To start your Phoenix server:
- Run the complete setup:
mix setup - Start Phoenix endpoint with
mix phx.serveror inside IEx withiex -S mix phx.server
Now you can visit localhost:4000 from your browser.
Ready to run in production? Please check our deployment guides.
Learn more
- Official website: https://www.phoenixframework.org/
- Guides: https://hexdocs.pm/phoenix/overview.html
- Docs: https://hexdocs.pm/phoenix
- Forum: https://elixirforum.com/c/phoenix-forum
- Source: https://github.com/phoenixframework/phoenix
Kubernetes (K3s) Deployment
This application can be automatically deployed to a K3s Kubernetes cluster using GitHub Actions.
Prerequisites
- K3s Cluster: You need a running K3s cluster.
kubectlaccess: Ensure you havekubectlconfigured to interact with your K3s cluster.- Container Registry: This setup uses GitHub Container Registry (GHCR) to store the application's Docker image.
Initial Setup
1. GitHub Actions Secrets
The GitHub Actions workflow requires the following secret to be configured in your repository's settings (Settings -> Secrets and variables -> Actions -> Repository secrets):
KUBE_CONFIG_DATA: The base64 encoded content of your K3s kubeconfig file. This file grants GitHub Actions permission to deploy to your cluster.- To get this value, you can typically run:
(If you're on macOS, you might needcat ~/.kube/config | base64 -w 0cat ~/.kube/config | base64). Or, directly from the K3s server node:sudo cat /etc/rancher/k3s/k3s.yaml | base64 -w 0 - Ensure the user in this kubeconfig has sufficient permissions in your K3s cluster to create namespaces, deployments, services, PVCs, and secrets in the target namespace (
aprs-app).
- To get this value, you can typically run:
2. Kubernetes Secrets for the Application
The application requires secrets for database connection, Phoenix secret key base, etc. These are managed by a Kubernetes Secret object named aprs-secrets in the aprs-app namespace.
-
Copy the example secrets file:
cp k8s/secrets.yaml.example k8s/secrets.yaml -
Edit
k8s/secrets.yaml: Openk8s/secrets.yamland replace the placeholder values with your actual credentials and configuration:POSTGRES_USER: Your desired PostgreSQL username.POSTGRES_PASSWORD: Your desired PostgreSQL password.SECRET_KEY_BASE: A strong secret key for Phoenix. You can generate one usingmix phx.gen.secret.APRS_CALLSIGN,APRS_PASSCODE: Your APRS credentials, if applicable.PHX_HOST: The domain name or IP where your application will be accessible.
-
Apply the secrets to your K3s cluster: Make sure you are targeting your K3s cluster with
kubectl.kubectl apply -f k8s/namespace.yaml # Ensure namespace exists kubectl apply -f k8s/secrets.yaml -n aprs-appImportant:
k8s/secrets.yamlis included in.gitignoreand should not be committed to the repository with your actual secrets.
GitHub Actions CI/CD Workflow
The workflow is defined in .github/workflows/deploy-k3s.yaml. It will:
- Trigger on pushes to the
mainbranch. - Build the application's Docker image using the provided
Dockerfile. - Push the image to GitHub Container Registry (GHCR), tagged with the Git SHA and
latest. The image will be namedghcr.io/<YOUR_GITHUB_USERNAME_OR_ORG>/<YOUR_REPO_NAME>. - Deploy the application and its PostgreSQL database to the K3s cluster using the manifests in the
k8s/directory.- It automatically updates
k8s/app-deployment.yamlto use the newly built image tag.
- It automatically updates
Application Configuration Notes
- Database Migrations: The Kubernetes deployment for the application includes an init container that automatically runs database migrations (
/app/bin/migrate) before the main application container starts. - Health Check Endpoint: The application deployment (
k8s/app-deployment.yaml) is configured with readiness and liveness probes that expect a health check endpoint at/health(returning HTTP 200). You may need to add this to your Phoenix application's router and controller:- In
lib/aprsme_web/router.ex:scope "/", AprsmeWeb do pipe_through :browser # ... other routes get "/health", PageController, :health end - In
lib/aprsme_web/controllers/page_controller.ex(or another suitable controller):def health(conn, _params) do # You can add more sophisticated checks here if needed json(conn, %{status: "ok", version: Application.spec(:aprsme, :vsn)}) end
- In
- Image Name: The application deployment manifest (
k8s/app-deployment.yaml) uses a placeholder image nameyour-ghcr-username/aprs-app:latest. The CI/CD pipeline automatically replaces this with the correct image name from GHCR (e.g.,ghcr.io/your-github-owner/your-repo-name:<git-sha>).
Accessing the Application
The application service (k8s/app-service.yaml) is configured with type: NodePort.
- Find the NodePort assigned by Kubernetes:
kubectl get svc aprs-app-service -n aprs-app -o=jsonpath='{.spec.ports[0].nodePort}' - Access your application at
http://<your-k3s-node-ip>:<nodePort>.
If your K3s cluster is configured with an external load balancer and Ingress, you might want to change the service type to ClusterIP and create an Ingress resource for more sophisticated routing and SSL termination.