Skip to content

Commit

Permalink
feat: initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
pcfreak30 committed Nov 24, 2024
1 parent f8f0a75 commit 5916fa5
Show file tree
Hide file tree
Showing 55 changed files with 6,657 additions and 1 deletion.
58 changes: 58 additions & 0 deletions .github/workflows/publish.yml
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 }}
29 changes: 29 additions & 0 deletions Caddyfile
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
}
}
49 changes: 49 additions & 0 deletions Dockerfile
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"]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Lume Web
Copyright (c) 2024 Hammer Technologies LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
134 changes: 134 additions & 0 deletions README.md
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
62 changes: 62 additions & 0 deletions archive/entrypoint.sh
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 "$@"
Loading

0 comments on commit 5916fa5

Please sign in to comment.