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 47284bf
Show file tree
Hide file tree
Showing 55 changed files with 6,711 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
188 changes: 188 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# MySQL for Akash

A production-ready MySQL solution optimized for Akash Network deployments, supporting both standalone and high-availability cluster modes.

## Features

- Optimized for Akash deployments
- Automatic master/slave failover in cluster mode
- Dynamic configuration optimization
- Resource-aware scaling
- Prometheus metrics export
- Zero-config standalone mode
- Automatic backup management
- SSL/TLS support

## Deployment Modes

### Standalone Mode

Perfect for single-node deployments where high availability isn't required:

```sdl
services:
mysql:
image: ghcr.io/lumeweb/akash-mysql:latest
env:
- MYSQL_ROOT_PASSWORD=mypassword
expose:
- port: 3306
as: 3306
to:
- global: true
```

### Cluster Mode

For high-availability deployments with automatic failover:

```sdl
services:
etcd:
image: bitnami/etcd:latest
env:
- ALLOW_NONE_AUTHENTICATION=yes
expose:
- port: 2379
to:
- service: mysql
mysql-master:
image: ghcr.io/lumeweb/akash-mysql:latest
env:
- CLUSTER_MODE=true
- ETCD_HOST=etcd
- ETCD_PORT=2379
- MYSQL_ROOT_PASSWORD=mypassword
expose:
- port: 3306
as: 3306
to:
- global: true
mysql-slave:
image: ghcr.io/lumeweb/akash-mysql:latest
count: 2
env:
- CLUSTER_MODE=true
- ETCD_HOST=etcd
- ETCD_PORT=2379
- MYSQL_ROOT_PASSWORD=mypassword
expose:
- port: 3306
to:
- global: true
```

## Environment Variables

### Required
- `MYSQL_ROOT_PASSWORD`: Root password for MySQL

### Optional
- `CLUSTER_MODE`: Enable cluster mode (default: false)
- `PORT`: MySQL port (default: 3306)
- `ETCD_HOST`: etcd host (required for cluster mode)
- `ETCD_PORT`: etcd port (required for cluster mode)
- `ETCD_USERNAME`: etcd authentication username
- `ETCD_PASSWORD`: etcd authentication password
- `METRICS_PORT`: Prometheus metrics port (default: 8080)
- `METRICS_USERNAME`: Metrics authentication username
- `METRICS_PASSWORD`: Metrics authentication password
- `MYSQL_REPL_USER`: Replication user (default: repl)
- `MYSQL_REPL_PASSWORD`: Replication password
- `BACKUP_ENABLED`: Enable automated backups (default: false)
- `BACKUP_SCHEDULE`: Backup schedule in cron format
- `SSL_ENABLED`: Enable SSL/TLS (default: false)

## etcd Protocol Schema

The cluster uses etcd for coordination with the following key structure:

### Node Registration
```
/mysql/nodes/{node_id}
{
"status": "online|offline|unhealthy",
"hostname": "host.name",
"port": "3306",
"role": "master|slave",
"health": {
"status": "process:up,ping:ok,read:ok,write:ok",
"connections": 42,
"uptime": 3600,
"errors": 0
},
"lastHeartbeat": "2024-01-01T00:00:00Z"
}
```

### Role Assignment
```
/mysql/roles/{node_id}
"master|slave"
```

### Master Info
```
/mysql/nodes/master
{
"host": "master.host",
"port": 3306,
"status": "online",
"binlog": {
"file": "mysql-bin.000001",
"position": 1234
}
}
```

### Lease Management
- Each node maintains a 10-second TTL lease
- Health updates occur every 5 seconds
- Node status is automatically marked offline when lease expires

## Monitoring

### Prometheus Metrics
Available on port 8080 with basic auth:

```bash
curl -u $METRICS_USERNAME:$METRICS_PASSWORD http://host:8080/metrics
```

Metrics include:
- MySQL server status
- Replication lag
- Connection pool stats
- Query performance
- Resource usage
- Backup status

### Health Monitoring
- Continuous health checks
- Automatic failover on master failure
- Resource utilization tracking
- Error condition monitoring

## Configuration

The system automatically optimizes for:
- Available memory
- CPU cores
- Container limits
- Network conditions
- Workload patterns

## Support

- Documentation: [Wiki](https://github.com/lumeweb/akash-mysql/wiki)
- Issues: [GitHub Issues](https://github.com/lumeweb/akash-mysql/issues)

## License

MIT License - see LICENSE file for details

## 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 47284bf

Please sign in to comment.