-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
55 changed files
with
6,657 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
name: Build and Publish Docker Image | ||
|
||
on: | ||
push: | ||
branches: | ||
- develop | ||
tags: | ||
- 'v*' | ||
pull_request: | ||
branches: | ||
- develop | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
IMAGE_NAME: ${{ github.repository }} | ||
|
||
jobs: | ||
build-and-publish: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
packages: write | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: '1.23.2' | ||
|
||
- name: Log in to the Container registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Extract metadata for Docker | ||
id: meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
tags: | | ||
type=ref,event=branch | ||
type=ref,event=pr | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
type=sha | ||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
push: ${{ github.event_name != 'pull_request' }} | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
# Global Caddy configuration | ||
admin off | ||
|
||
# Logging | ||
log { | ||
level INFO | ||
output file /var/log/caddy/access.log | ||
} | ||
} | ||
|
||
# Metrics exporter with authentication and SSL | ||
:8080 { | ||
# Basic authentication for metrics | ||
basicauth /* { | ||
{$METRICS_USERNAME} {$METRICS_PASSWORD} | ||
} | ||
|
||
# Proxy to metrics exporter | ||
reverse_proxy localhost:9104 { | ||
transport http { | ||
tls_insecure_skip_verify | ||
} | ||
} | ||
|
||
tls { | ||
challenge http | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
ARG MYSQL_VERSION=8 | ||
ARG METRICS_EXPORTER_VERSION=develop | ||
ARG MYSQL_MANAGER_VERSION=develop | ||
|
||
# Disable Percona Telemetry | ||
ARG PERCONA_TELEMETRY_DISABLE=1 | ||
|
||
# Use metrics exporter as builder stage | ||
FROM ghcr.io/lumeweb/akash-metrics-exporter:${METRICS_EXPORTER_VERSION} AS metrics-exporter | ||
|
||
FROM percona:${MYSQL_VERSION} | ||
|
||
# Switch to root for setup | ||
USER root | ||
|
||
# Install dependencies and set up directories in a single layer | ||
RUN percona-release enable pxb-80 && \ | ||
yum install -y --setopt=tsflags=nodocs percona-xtrabackup-80 lz4 zstd && \ | ||
yum clean all && \ | ||
rm -rf /var/cache/yum && \ | ||
mkdir -p /var/log/{mysql,mysql-manager} /etc/mysql /var/run/mysqld && \ | ||
chown -R mysql:mysql /var/log/{mysql,mysql-manager} /etc/mysql /var/run/mysqld && \ | ||
rm -f /docker-entrypoint.sh | ||
|
||
# Copy files | ||
COPY --chown=mysql:mysql entrypoint.sh /entrypoint.sh | ||
COPY --chown=mysql:mysql paths.sh /paths.sh | ||
COPY --chown=mysql:mysql lib/ /usr/local/lib/ | ||
COPY --from=metrics-exporter /usr/bin/metrics-exporter /usr/bin/akash-metrics-exporter | ||
|
||
# Make entrypoint executable | ||
RUN chmod +x /entrypoint.sh | ||
|
||
# Configure environment | ||
ENV METRICS_PORT=9104 \ | ||
METRICS_USERNAME=admin \ | ||
METRICS_PASSWORD= | ||
|
||
# Define volume | ||
VOLUME ["/data"] | ||
|
||
# Expose ports | ||
EXPOSE 8080 3306 33060 | ||
|
||
# Switch to mysql user | ||
USER mysql | ||
|
||
ENTRYPOINT ["/entrypoint.sh"] | ||
CMD ["mysqld"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
# MySQL High Availability Manager | ||
|
||
A robust MySQL high availability solution with automatic failover, monitoring, and configuration management. | ||
|
||
## Features | ||
|
||
- Automatic master/slave failover | ||
- Dynamic configuration optimization | ||
- Health monitoring and metrics export | ||
- etcd-based cluster coordination | ||
- Prometheus metrics export via Caddy | ||
- Docker container ready | ||
|
||
## Requirements | ||
|
||
- Docker | ||
- etcd cluster | ||
- Prometheus (optional, for metrics) | ||
|
||
## Quick Start | ||
|
||
```bash | ||
# Pull the image | ||
docker pull ghcr.io/lumeweb/mysql-ha-manager:latest | ||
|
||
# Start a standalone instance | ||
docker run -d \ | ||
--name mysql-standalone \ | ||
-e MYSQL_ROOT_PASSWORD=mypassword \ | ||
-p 3306:3306 \ | ||
ghcr.io/lumeweb/mysql-akash-mysql:latest | ||
|
||
# Start a cluster node | ||
docker run -d \ | ||
--name mysql-node1 \ | ||
-e CLUSTER_MODE=true \ | ||
-e ETCD_HOST=etcd-host \ | ||
-e ETCD_PORT=2379 \ | ||
-e MYSQL_ROOT_PASSWORD=mypassword \ | ||
-p 3306:3306 \ | ||
ghcr.io/lumeweb/mysql-ha-manager:latest | ||
``` | ||
|
||
## Environment Variables | ||
|
||
### Required | ||
- `MYSQL_ROOT_PASSWORD`: Root password for MySQL | ||
- `ETCD_HOST`: etcd host (required for cluster mode) | ||
- `ETCD_PORT`: etcd port (required for cluster mode) | ||
|
||
### Optional | ||
- `CLUSTER_MODE`: Enable cluster mode (default: false) | ||
- `PORT`: MySQL port (default: 3306) | ||
- `ETCD_USERNAME`: etcd authentication username | ||
- `ETCD_PASSWORD`: etcd authentication password | ||
- `METRICS_USERNAME`: Metrics authentication username | ||
- `METRICS_PASSWORD`: Metrics authentication password | ||
- `MYSQL_REPL_USER`: Replication user (default: repl) | ||
- `MYSQL_REPL_PASSWORD`: Replication password | ||
|
||
## Cluster Architecture | ||
|
||
The solution uses etcd for cluster coordination: | ||
|
||
1. Nodes register themselves in etcd with health information | ||
2. Role changes (master/slave) are coordinated through etcd | ||
3. Automatic failover occurs when master becomes unhealthy | ||
4. Configuration is dynamically optimized based on resources | ||
|
||
## Monitoring | ||
|
||
### Prometheus Metrics | ||
|
||
Metrics are exposed on port 8080 with basic auth: | ||
|
||
```bash | ||
# Example metrics query | ||
curl -u admin:password http://localhost:8080/metrics | ||
``` | ||
|
||
Available metrics include: | ||
- MySQL server status | ||
- Replication lag | ||
- Connection pool stats | ||
- Query performance | ||
- Resource usage | ||
|
||
### Health Checks | ||
|
||
Health status is maintained in etcd and includes: | ||
- Connection status | ||
- Replication status | ||
- Resource utilization | ||
- Error conditions | ||
|
||
## Configuration | ||
|
||
The system automatically generates optimal MySQL configurations based on: | ||
- Available memory | ||
- CPU cores | ||
- Container limits | ||
- Environment (Kubernetes vs standalone) | ||
|
||
## Development | ||
|
||
### Building | ||
|
||
```bash | ||
# Build the image | ||
docker build -t mysql-ha-manager . | ||
|
||
# Run tests | ||
docker run --rm mysql-ha-manager test | ||
``` | ||
|
||
### Contributing | ||
|
||
1. Fork the repository | ||
2. Create your feature branch | ||
3. Commit your changes | ||
4. Push to the branch | ||
5. Create a Pull Request | ||
|
||
## License | ||
|
||
MIT License - see LICENSE file for details | ||
|
||
## Support | ||
|
||
- GitHub Issues: [Report a bug](https://github.com/lumeweb/akash-mysql/issues) | ||
|
||
## Authors | ||
|
||
Hammer Technologies LLC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/bin/bash | ||
set -eo pipefail | ||
shopt -s nullglob | ||
|
||
set -x | ||
|
||
source ./paths.sh | ||
source "${LIB_PATH}/core/logging.sh" | ||
source "${LIB_PATH}/mysql-init.sh" | ||
source "${LIB_PATH}/mysql-startup.sh" | ||
|
||
# Main entrypoint logic | ||
main() { | ||
# Environment setup | ||
CLUSTER_MODE=${CLUSTER_MODE:-false} | ||
HOST=${HOST:-localhost} | ||
PORT=${PORT:-3306} | ||
NODE_ID="${HOST}:${PORT}" | ||
|
||
# Check if command starts with an option | ||
if [ "${1:0:1}" = '-' ]; then | ||
set -- mysqld "$@" | ||
fi | ||
|
||
# Check for help flags | ||
for arg; do | ||
case "$arg" in | ||
-'?'|--help|--print-defaults|-V|--version) | ||
exec "$@" | ||
;; | ||
esac | ||
done | ||
|
||
if [ "$1" = 'mysqld' ]; then | ||
# Get data directory | ||
DATADIR=$(mysqld --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null | awk '$1 == "datadir" { print $2; exit }') | ||
|
||
# Initialize if needed | ||
if initialize_mysql "$DATADIR" "$MYSQL_ROOT_PASSWORD"; then | ||
log_info "Database initialized, starting MySQL..." | ||
if [ "$CLUSTER_MODE" = "true" ]; then | ||
exec "${LIB_PATH}/cluster-start.sh" "$@" | ||
else | ||
exec "${LIB_PATH}/standalone-start.sh" "$@" | ||
fi | ||
else | ||
log_info "Database exists, starting MySQL..." | ||
if [ "$CLUSTER_MODE" = "true" ]; then | ||
exec "${LIB_PATH}/cluster-start.sh" "$@" | ||
else | ||
exec "${LIB_PATH}/standalone-start.sh" "$@" | ||
fi | ||
fi | ||
|
||
return 0 | ||
fi | ||
|
||
# If we got here, just execute the command | ||
exec "$@" | ||
} | ||
|
||
main "$@" |
Oops, something went wrong.