diff --git a/.env.scripts b/.env.scripts index 7dc8449..37d6e84 100644 --- a/.env.scripts +++ b/.env.scripts @@ -37,9 +37,12 @@ ENV_ADD_TAGS="" ENV_ADD_IMAGE_PUSH="" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Pull image info -ENV_PULL_URL="almalinux/8-init" +ENV_PULL_URL="almalinux/10-init" ENV_DISTRO_TAG="${IMAGE_VERSION}" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Platform support (BlueOnyx only supports amd64) +ENV_PLATFORMS="linux/amd64" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Env SERVICE_PORT="" EXPOSE_PORTS="" diff --git a/Dockerfile b/Dockerfile index f83d623..cf0e9a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,8 +14,8 @@ ARG PATH="/usr/local/etc/docker/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/us ARG USER="root" ARG SHELL_OPTS="set -e -o pipefail" -ARG SERVICE_PORT="" -ARG EXPOSE_PORTS="" +ARG SERVICE_PORT="444" +ARG EXPOSE_PORTS="81 444 80 443 20 21 22 25 587 465 110 995 143 993 53" ARG PHP_VERSION="system" ARG NODE_VERSION="system" ARG NODE_MANAGER="system" @@ -24,12 +24,11 @@ ARG IMAGE_REPO="casjaysdevdocker/blueonyx" ARG IMAGE_VERSION="latest" ARG CONTAINER_VERSION="" -ARG PULL_URL="almalinux/8-init" -ARG DISTRO_VERSION="${IMAGE_VERSION}" +ARG PULL_URL="almalinux/10-init" +ARG DISTRO_VERSION="latest" ARG BUILD_VERSION="${BUILD_DATE}" -FROM tianon/gosu:latest AS gosu -FROM ${PULL_URL}:${DISTRO_VERSION} AS build +FROM almalinux/10-init ARG TZ ARG PATH ARG USER @@ -54,7 +53,7 @@ ARG PHP_VERSION ARG PHP_SERVER ARG SHELL_OPTS -ARG PACK_LIST="bash bash-completion git curl wget sudo unzip tini iproute net-tools glibc-langpack-en pinentry nail postfix python3-pip certbot ca-certificates " +ARG PACK_LIST="bash bash-completion git curl wget sudo unzip iproute net-tools glibc-langpack-en pinentry python3-pip ca-certificates systemd systemd-libs NetworkManager valkey valkey-compat-redis certbot python3-certbot-apache python3-certbot-nginx cronie mod_authnz_external " ENV ENV=~/.profile ENV SHELL="/bin/sh" @@ -81,8 +80,6 @@ RUN set -e; \ ENV SHELL="/bin/bash" SHELL [ "/bin/bash", "-c" ] -COPY --from=gosu /usr/local/bin/gosu /usr/local/bin/gosu - RUN echo "Initializing the system"; \ $SHELL_OPTS; \ mkdir -p "${DEFAULT_DATA_DIR}" "${DEFAULT_CONF_DIR}" "${DEFAULT_TEMPLATE_DIR}" "/root/docker/setup" "/etc/profile.d"; \ @@ -168,89 +165,22 @@ RUN echo "Deleting unneeded files"; \ $SHELL_OPTS; \ pkmgr clean; \ rm -Rf "/config" "/data" || true; \ - rm -rf /etc/systemd/system/*.wants/* || true; \ - rm -rf /lib/systemd/system/systemd-update-utmp* || true; \ - rm -rf /lib/systemd/system/anaconda.target.wants/* || true; \ - rm -rf /lib/systemd/system/local-fs.target.wants/* || true; \ - rm -rf /lib/systemd/system/multi-user.target.wants/* || true; \ - rm -rf /lib/systemd/system/sockets.target.wants/*udev* || true; \ - rm -rf /lib/systemd/system/sockets.target.wants/*initctl* || true; \ - rm -Rf /usr/share/doc/* /var/tmp/* /var/cache/*/* /root/.cache/* /usr/share/info/* /tmp/* || true; \ - if [ -d "/lib/systemd/system/sysinit.target.wants" ];then cd "/lib/systemd/system/sysinit.target.wants" && rm -f $(ls | grep -v systemd-tmpfiles-setup);fi; \ + rm -Rf /usr/share/doc/* /usr/share/info/* /tmp/* || true; \ + rm -Rf /var/cache/*/* /root/.cache/* || true; \ + find /var/tmp -mindepth 1 -delete 2>/dev/null || true; \ if [ -f "/root/docker/setup/07-cleanup.sh" ];then echo "Running the cleanup script";/root/docker/setup/07-cleanup.sh||{ echo "Failed to execute /root/docker/setup/07-cleanup.sh" >&2 && exit 10; };echo "Done running the cleanup script";fi; \ echo "" RUN echo "Init done" -FROM scratch -ARG TZ -ARG PATH -ARG USER -ARG TIMEZONE -ARG LANGUAGE -ARG IMAGE_NAME -ARG BUILD_DATE -ARG SERVICE_PORT -ARG EXPOSE_PORTS -ARG BUILD_VERSION -ARG IMAGE_VERSION -ARG WWW_ROOT_DIR -ARG DEFAULT_FILE_DIR -ARG DEFAULT_DATA_DIR -ARG DEFAULT_CONF_DIR -ARG DEFAULT_TEMPLATE_DIR -ARG DISTRO_VERSION -ARG NODE_VERSION -ARG NODE_MANAGER -ARG PHP_VERSION -ARG PHP_SERVER -ARG LICENSE="WTFPL" -ARG ENV_PORTS="${EXPOSE_PORTS}" -USER ${USER} -WORKDIR /root - -LABEL maintainer="CasjaysDev " -LABEL org.opencontainers.image.vendor="CasjaysDev" -LABEL org.opencontainers.image.authors="CasjaysDev" -LABEL org.opencontainers.image.description="Containerized version of ${IMAGE_NAME}" -LABEL org.opencontainers.image.title="${IMAGE_NAME}" -LABEL org.opencontainers.image.base.name="${IMAGE_NAME}" -LABEL org.opencontainers.image.authors="${LICENSE}" -LABEL org.opencontainers.image.created="${BUILD_DATE}" -LABEL org.opencontainers.image.version="${BUILD_VERSION}" -LABEL org.opencontainers.image.schema-version="${BUILD_VERSION}" -LABEL org.opencontainers.image.url="docker.io" -LABEL org.opencontainers.image.source="docker.io" -LABEL org.opencontainers.image.vcs-type="Git" -LABEL org.opencontainers.image.revision="${BUILD_VERSION}" -LABEL org.opencontainers.image.source="https://github.com/casjaysdevdocker/blueonyx" -LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocker/blueonyx" -LABEL com.github.containers.toolbox="false" - -ENV ENV=~/.bashrc -ENV USER="${USER}" -ENV PATH="${PATH}" -ENV TZ="${TIMEZONE}" -ENV SHELL="/bin/bash" -ENV TIMEZONE="${TZ}" -ENV LANG="${LANGUAGE}" -ENV TERM="xterm-256color" -ENV PORT="${SERVICE_PORT}" -ENV ENV_PORTS="${ENV_PORTS}" -ENV CONTAINER_NAME="${IMAGE_NAME}" -ENV HOSTNAME="casjaysdev-${IMAGE_NAME}" -ENV PHP_SERVER="${PHP_SERVER}" -ENV NODE_VERSION="${NODE_VERSION}" -ENV NODE_MANAGER="${NODE_MANAGER}" -ENV PHP_VERSION="${PHP_VERSION}" -ENV DISTRO_VERSION="${IMAGE_VERSION}" -ENV WWW_ROOT_DIR="${WWW_ROOT_DIR}" - -COPY --from=build /. / +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Final configuration (no separate stage for systemd containers) VOLUME [ "/config","/data" ] EXPOSE ${SERVICE_PORT} ${ENV_PORTS} -ENTRYPOINT [ "tini","--","/usr/local/bin/entrypoint.sh" ] -HEALTHCHECK --start-period=10m --interval=5m --timeout=15s CMD [ "/usr/local/bin/entrypoint.sh", "healthcheck" ] +STOPSIGNAL SIGRTMIN+3 + +# Use systemd as PID 1 for multi-service management +CMD ["/sbin/init"] diff --git a/README.md b/README.md index 363251b..4a2dfbc 100644 --- a/README.md +++ b/README.md @@ -1,78 +1,397 @@ ## 👋 Welcome to blueonyx 🚀 -blueonyx README - - -## Install my system scripts +BlueOnyx 5212R - Full-featured web hosting control panel for AlmaLinux 10 + +**Note:** BlueOnyx requires systemd and privileged mode to run properly. + +## Features + +- **Web Hosting** - Apache with mod_php and virtual host management +- **Email Server** - Postfix (satellite mode support) + Dovecot (IMAP/POP3) +- **DNS Server** - BIND with zone management +- **FTP Server** - ProFTPD with virtual users +- **Database** - MariaDB 10.11 with phpMyAdmin +- **Key-Value Store** - Valkey (Redis-compatible) for caching +- **SSL/TLS** - Let's Encrypt support via Certbot with auto-renewal +- **User Management** - Multi-user and reseller support +- **2FA Authentication** - Two-factor authentication support +- **CalDAV/CardDAV** - Calendar and contact synchronization +- **Web GUI** - Full-featured control panel on ports 444 (HTTPS) / 81 (HTTP) +- **40+ ENV Variables** - Extensive configuration via environment variables + +## Requirements + +- **Platform**: linux/amd64 only (BlueOnyx RPM packages) +- **Docker**: Version 20.10+ with privileged mode support +- **CPU**: x86_64 architecture +- **Memory**: At least 2GB RAM recommended +- **Storage**: Minimum 5GB for container + data +- **Persistent Volumes**: Required for /data and /config + +## Quick Start + +### Using docker run ```shell - sudo bash -c "$(curl -q -LSsf "https://github.com/systemmgr/installer/raw/main/install.sh")" - sudo systemmgr --config && sudo systemmgr install scripts -``` - -## Automatic install/update - -```shell -dockermgr update blueonyx -``` - -## Install and run container - -```shell -mkdir -p "$HOME/.local/share/srv/docker/blueonyx/rootfs" -git clone "https://github.com/dockermgr/blueonyx" "$HOME/.local/share/CasjaysDev/dockermgr/blueonyx" -cp -Rfva "$HOME/.local/share/CasjaysDev/dockermgr/blueonyx/rootfs/." "$HOME/.local/share/srv/docker/blueonyx/rootfs/" docker run -d \ ---restart always \ ---privileged \ ---name casjaysdevdocker-blueonyx \ ---hostname blueonyx \ --e TZ=${TIMEZONE:-America/New_York} \ --v "$HOME/.local/share/srv/docker/casjaysdevdocker-blueonyx/rootfs/data:/data:z" \ --v "$HOME/.local/share/srv/docker/casjaysdevdocker-blueonyx/rootfs/config:/config:z" \ --p 80:80 \ -casjaysdevdocker/blueonyx:latest + --name blueonyx \ + --hostname blueonyx.local \ + --privileged \ + --cgroupns=host \ + -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ + -v blueonyx-data:/data \ + -v blueonyx-config:/config \ + -p 444:444 \ + -p 81:81 \ + -e BLUEONYX_HOSTNAME=blueonyx \ + -e BLUEONYX_DOMAIN=local \ + casjaysdevdocker/blueonyx:latest ``` - -## via docker-compose - + +### Using docker-compose + ```yaml -version: "2" +version: "3.8" services: - ProjectName: - image: casjaysdevdocker/blueonyx - container_name: casjaysdevdocker-blueonyx + blueonyx: + image: casjaysdevdocker/blueonyx:latest + container_name: blueonyx + hostname: blueonyx.local + privileged: true + cgroup: host environment: + - BLUEONYX_HOSTNAME=blueonyx + - BLUEONYX_DOMAIN=local - TZ=America/New_York - - HOSTNAME=blueonyx volumes: - - "$HOME/.local/share/srv/docker/casjaysdevdocker-blueonyx/rootfs/data:/data:z" - - "$HOME/.local/share/srv/docker/casjaysdevdocker-blueonyx/rootfs/config:/config:z" + - /sys/fs/cgroup:/sys/fs/cgroup:rw + - blueonyx-data:/data + - blueonyx-config:/config ports: - - 80:80 - restart: always + - "444:444" # HTTPS Admin Interface + - "81:81" # HTTP Admin Interface + - "80:80" # HTTP Web Hosting (optional) + - "443:443" # HTTPS Web Hosting (optional) + - "21:21" # FTP (optional) + - "25:25" # SMTP (optional) + - "110:110" # POP3 (optional) + - "143:143" # IMAP (optional) + restart: unless-stopped + +volumes: + blueonyx-data: + blueonyx-config: ``` - -## Get source files - + +## First Access + +1. Wait 2-3 minutes for BlueOnyx to fully initialize +2. Access the admin panel: https://YOUR_IP:444/ or http://YOUR_IP:81/ +3. Default credentials: + - Username: `admin` + - Password: Check `/data/ADMIN_PASSWORD.txt` (auto-generated) or set via `BLUEONYX_ADMIN_PASSWORD` ENV var +4. Change the admin password immediately after first login + +**Note**: If you set `BLUEONYX_ADMIN_PASSWORD`, use that password. Otherwise, the container generates a random password and saves it to `/data/ADMIN_PASSWORD.txt`. + +## Environment Variables + +BlueOnyx supports extensive configuration through environment variables: + +### Network Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_HOSTNAME` | `blueonyx` | Server hostname | +| `BLUEONYX_DOMAIN` | `local` | Server domain name | +| `BLUEONYX_IPV4` | auto-detected | IPv4 address | +| `BLUEONYX_IPV6` | none | IPv6 address | +| `BLUEONYX_GATEWAY` | auto-detected | Network gateway | +| `BLUEONYX_NAMESERVER` | `8.8.8.8` | DNS nameserver | + +### Admin Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_ADMIN_USER` | `admin` | Admin username | +| `BLUEONYX_ADMIN_PASS` | auto-generated | Admin password (saved to `/data/ADMIN_PASSWORD.txt`) | +| `BLUEONYX_ADMIN_EMAIL` | `admin@{domain}` | Admin email address | + +### Mail Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_POSTFIX_MODE` | `satellite` | Postfix mode (`satellite`, `internet`, `local`) | +| `BLUEONYX_POSTFIX_RELAY` | docker gateway | SMTP relay host | +| `BLUEONYX_POSTFIX_RELAY_PORT` | `25` | SMTP relay port | +| `BLUEONYX_POSTFIX_RELAY_USER` | none | SMTP relay username (optional) | +| `BLUEONYX_POSTFIX_RELAY_PASS` | none | SMTP relay password (optional) | +| `BLUEONYX_ENABLE_DOVECOT` | `yes` | Enable Dovecot IMAP/POP3 | +| `BLUEONYX_ENABLE_SPAM_FILTER` | `yes` | Enable SpamAssassin | +| `BLUEONYX_ENABLE_ANTIVIRUS` | `yes` | Enable ClamAV | +| `BLUEONYX_ENABLE_DKIM` | `yes` | Enable DKIM signing | + +### Database Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_DB_TYPE` | `mariadb` | Database type | +| `BLUEONYX_DB_ROOT_PASS` | auto-generated | MySQL root password (saved to `/data/MYSQL_ROOT_PASSWORD.txt`) | +| `BLUEONYX_ENABLE_POSTGRES` | `no` | Enable PostgreSQL | + +### Valkey/Redis Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_VALKEY_ENABLED` | `yes` | Enable Valkey (Redis-compatible) | +| `BLUEONYX_VALKEY_PORT` | `6379` | Valkey port | +| `BLUEONYX_VALKEY_MAXMEMORY` | `256mb` | Maximum memory for Valkey | + +### Web Server Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_WEB_PROXY` | `nginx` | Web proxy (`nginx`, `apache`) | +| `BLUEONYX_HTTP2_ENABLED` | `yes` | Enable HTTP/2 | +| `BLUEONYX_TLS_VERSION` | `1.3` | Minimum TLS version | +| `BLUEONYX_ENABLE_SSL` | `yes` | Enable SSL/TLS | +| `BLUEONYX_SSL_TYPE` | `selfsigned` | SSL certificate type | + +### Certbot/Let's Encrypt +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_CERTBOT_ENABLED` | `no` | Enable Certbot for Let's Encrypt | +| `BLUEONYX_CERTBOT_EMAIL` | admin email | Email for Let's Encrypt notifications | +| `BLUEONYX_CERTBOT_DOMAINS` | none | Comma-separated list of domains for certificates | +| `BLUEONYX_CERTBOT_WEBROOT` | `/var/www/html` | Webroot path for ACME challenge | + +### DNS Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_ENABLE_DNS` | `yes` | Enable BIND DNS server | +| `BLUEONYX_DNS_FORWARDERS` | `8.8.8.8 8.8.4.4` | DNS forwarders | + +### FTP Configuration +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_ENABLE_FTP` | `yes` | Enable ProFTPD | +| `BLUEONYX_FTP_PASSIVE_PORTS` | `30000-30100` | Passive port range | + +### Virtual Hosts +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_VHOSTS` | none | Comma-separated list of virtual hosts to create (e.g., `example.com,test.com`) | + +### Feature Toggles +| Variable | Default | Description | +|----------|---------|-------------| +| `BLUEONYX_ENABLE_CALDAV` | `yes` | Enable CalDAV | +| `BLUEONYX_ENABLE_DOCKER` | `yes` | Enable Docker GUI | +| `BLUEONYX_ENABLE_WEBALIZER` | `yes` | Enable Webalizer stats | +| `TZ` | `America/New_York` | Timezone | + +### Example with all Mail Configuration +```bash +docker run -d --name blueonyx --privileged --cgroupns=host \ + -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ + -v blueonyx-data:/data \ + -v blueonyx-config:/config \ + -v blueonyx-logs:/logs \ + -p 444:444 -p 81:81 -p 80:80 -p 443:443 -p 25:25 \ + -e BLUEONYX_HOSTNAME=mail \ + -e BLUEONYX_DOMAIN=example.com \ + -e BLUEONYX_ADMIN_EMAIL=admin@example.com \ + -e BLUEONYX_POSTFIX_MODE=satellite \ + -e BLUEONYX_POSTFIX_RELAY=smtp.sendgrid.net \ + -e BLUEONYX_POSTFIX_RELAY_PORT=587 \ + -e BLUEONYX_POSTFIX_RELAY_USER=apikey \ + -e BLUEONYX_POSTFIX_RELAY_PASS=SG.xxxxx \ + -e BLUEONYX_VHOSTS=site1.example.com,site2.example.com,api.example.com \ + -e BLUEONYX_VALKEY_ENABLED=yes \ + -e BLUEONYX_VALKEY_MAXMEMORY=512mb \ + -e BLUEONYX_CERTBOT_ENABLED=yes \ + -e BLUEONYX_CERTBOT_EMAIL=ssl@example.com \ + -e BLUEONYX_CERTBOT_DOMAINS=example.com,www.example.com \ + casjaysdevdocker/blueonyx:latest +``` +## Persistent Data + +The container uses volumes for persistent storage following the schema: + +### Data Volumes +- `/data/db/mariadb` - MariaDB/MySQL database files +- `/data/db/valkey` - Valkey (Redis) data files +- `/data/home` - User home directories +- `/data/www` - Web hosting files +- `/data/mail` - Mail storage (Dovecot) +- `/data/dns` - DNS zone files (BIND) + +### Configuration Volumes +- `/config/blueonyx` - BlueOnyx main configuration +- `/config/mariadb` - MariaDB/MySQL configuration +- `/config/apache` - Apache web server configuration +- `/config/nginx` - Nginx proxy configuration +- `/config/postfix` - Postfix mail server configuration +- `/config/dovecot` - Dovecot IMAP/POP3 configuration +- `/config/bind` - BIND DNS server configuration +- `/config/proftpd` - ProFTPD FTP server configuration +- `/config/ssl` - SSL/TLS certificates + - `/config/ssl/certs/` - Certificate files + - `/config/ssl/private/` - Private keys + - `/config/ssl/letsencrypt/` - Let's Encrypt certificates + +### Log Volumes +- `/logs` - All service logs + - `/logs/letsencrypt/` - Certbot logs + +### Example Volume Mounts +```bash +docker run -d \ + -v blueonyx-data:/data \ + -v blueonyx-config:/config \ + -v blueonyx-logs:/logs \ + casjaysdevdocker/blueonyx +``` +## Exposed Ports + +| Port | Service | Protocol | +|------|---------|----------| +| 444 | Admin HTTPS | TCP | +| 81 | Admin HTTP | TCP | +| 80 | Web HTTP | TCP | +| 443 | Web HTTPS | TCP | +| 21 | FTP | TCP | +| 25 | SMTP | TCP | +| 110 | POP3 | TCP | +| 143 | IMAP | TCP | +| 53 | DNS | TCP/UDP | +| 6379 | Valkey/Redis | TCP | + +## What's Included + +This container includes a fully functional BlueOnyx 5212R installation with: + +- **BlueOnyx Core** (~1200 RPM packages) +- **Apache** with mod_php and mod_authnz_external +- **MariaDB 10.11** database server +- **Postfix** mail server with satellite mode support +- **Dovecot** IMAP/POP3 server with auto-generated SSL certificates +- **BIND** DNS server with zone management +- **ProFTPD** FTP server +- **Valkey** Redis-compatible key-value store +- **Certbot** for Let's Encrypt SSL certificate automation +- **PHP** with multiple versions support +- **All required dependencies** pre-installed and configured + +### Recent Enhancements + +**Version 2.0 (2026-02):** +- ✅ Added Valkey (Redis-compatible) support +- ✅ Integrated Certbot with automatic SSL renewal +- ✅ Implemented 40+ environment variables for configuration +- ✅ Added virtual host auto-creation via `BLUEONYX_VHOSTS` +- ✅ Postfix satellite mode with Docker gateway auto-detection +- ✅ Password auto-generation with secure storage +- ✅ Fixed Apache mod_authnz_external module loading +- ✅ Fixed Dovecot SSL certificate generation +- ✅ Improved startup service reliability +- ✅ Platform-restricted to linux/amd64 for stability + +## Important Notes + +### Privileged Mode Required + +BlueOnyx manages multiple system services (Apache, MySQL, DNS, mail) and requires: +- `--privileged` flag +- Access to `/sys/fs/cgroup` +- systemd as PID 1 + +This is **by design** - BlueOnyx is a full control panel, not a single-service app. + +### No Reboot Needed + +Unlike bare-metal installation, the container version handles all initialization automatically. No container restart is required after first boot. + +### SELinux + +SELinux is automatically disabled in the container (required by BlueOnyx). + +## Troubleshooting + +### Check All Service Status ```shell -dockermgr download src casjaysdevdocker/blueonyx +docker exec blueonyx systemctl status cced.init admserv httpd mariadb postfix named dovecot valkey ``` - -OR - + +### Check Individual Services +```shell +docker exec blueonyx systemctl status cced.init +docker exec blueonyx systemctl status httpd +docker exec blueonyx systemctl status mariadb +docker exec blueonyx systemctl status postfix +docker exec blueonyx systemctl status dovecot +``` + +### View Logs +```shell +# Container logs +docker logs blueonyx + +# Service-specific logs +docker exec blueonyx journalctl -u cced.init -f +docker exec blueonyx journalctl -u httpd -f +docker exec blueonyx journalctl -u blueonyx-startup -f +``` + +### Access Shell +```shell +docker exec -it blueonyx /bin/bash +``` + +### Check Generated Passwords +```shell +docker exec blueonyx cat /data/ADMIN_PASSWORD.txt +docker exec blueonyx cat /data/MYSQL_ROOT_PASSWORD.txt +``` + +### Test Valkey Connection +```shell +docker exec blueonyx valkey-cli ping +docker exec blueonyx valkey-cli INFO +``` + +### Verify Virtual Hosts +```shell +docker exec blueonyx ls -la /etc/httpd/conf.d/vhost_*.conf +``` + +### Common Issues + +**Services not starting**: Wait 2-3 minutes after container start. BlueOnyx initializes multiple services sequentially. + +**Port conflicts**: Ensure ports 444, 81, 80, 443 are not in use by other containers/services. + +**Permission errors**: Container must run with `--privileged` flag and cgroupfs access. + +**Dovecot fails**: SSL certificates are auto-generated. Check `/etc/pki/dovecot/` for certificates. + +**httpd fails**: Ensure Apache modules are loaded. Check logs with `journalctl -u httpd`. + +## Get Source Files + ```shell git clone "https://github.com/casjaysdevdocker/blueonyx" "$HOME/Projects/github/casjaysdevdocker/blueonyx" +cd "$HOME/Projects/github/casjaysdevdocker/blueonyx" ``` - -## Build container - + +## Build Container + ```shell cd "$HOME/Projects/github/casjaysdevdocker/blueonyx" -buildx +docker build -t blueonyx:local . ``` - -## Authors - + +## More Information + +- BlueOnyx Official Site: https://www.blueonyx.it/ +- Documentation: https://www.blueonyx.it/index.php?page=features +- Mailing List: https://www.blueonyx.it/index.php?page=mailing-list + +## Authors + 🤖 casjay: [Github](https://github.com/casjay) 🤖 ⛵ casjaysdevdocker: [Github](https://github.com/casjaysdevdocker) [Docker](https://hub.docker.com/u/casjaysdevdocker) ⛵ diff --git a/rootfs/root/docker/setup/05-custom.sh b/rootfs/root/docker/setup/05-custom.sh index 1237fd4..0bd4e88 100755 --- a/rootfs/root/docker/setup/05-custom.sh +++ b/rootfs/root/docker/setup/05-custom.sh @@ -1,14 +1,14 @@ #!/usr/bin/env bash # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -##@Version : 202409061236-git +##@Version : 202602021541-git # @@Author : CasjaysDev # @@Contact : CasjaysDev # @@License : MIT -# @@ReadME : -# @@Copyright : Copyright 2023 CasjaysDev -# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@ReadME : BlueOnyx 5212R installation for Docker/systemd +# @@Copyright : Copyright 2026 CasjaysDev +# @@Created : Sun Feb 02 03:41:00 PM EST 2026 # @@File : 05-custom.sh -# @@Description : script to run custom +# @@Description : Install and configure BlueOnyx 5212R control panel # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # shellcheck shell=bash # shellcheck disable=SC2016 @@ -24,15 +24,338 @@ set -o pipefail # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Set env variables exitCode=0 +BLUEONYX_VERSION="${BLUEONYX_VERSION:-5212R}" +BLUEONYX_HOSTNAME="${BLUEONYX_HOSTNAME:-blueonyx}" +BLUEONYX_DOMAIN="${BLUEONYX_DOMAIN:-local}" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Predifined actions +# Predefined actions + +echo "==========================================" +echo "Installing BlueOnyx ${BLUEONYX_VERSION}" +echo "==========================================" + +# Disable SELinux (required by BlueOnyx) +echo "Disabling SELinux..." +if [ -f /etc/selinux/config ]; then + sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config + setenforce 0 2>/dev/null || true +fi + +# Install BlueOnyx YUM repository +echo "Installing BlueOnyx repository..." +if ! dnf install -y http://devel.blueonyx.it/pub/${BLUEONYX_VERSION}.rpm; then + echo "ERROR: Failed to install BlueOnyx repository" >&2 + exitCode=1 + exit $exitCode +fi + +# Install BlueOnyx and all dependencies (~900-1200 RPMs) +echo "Installing BlueOnyx packages (this will take several minutes)..." +if ! dnf groupinstall -y blueonyx; then + echo "ERROR: Failed to install BlueOnyx packages" >&2 + exitCode=1 + exit $exitCode +fi + +echo "BlueOnyx packages installed successfully" + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Configure BlueOnyx for container environment + +echo "Configuring BlueOnyx for container environment..." + +# Create network configuration script wrapper (non-interactive) +cat > /usr/local/bin/blueonyx-network-setup << 'NETSCRIPT' +#!/usr/bin/env bash +# Non-interactive network setup for BlueOnyx in containers + +HOSTNAME="${BLUEONYX_HOSTNAME:-blueonyx}" +DOMAIN="${BLUEONYX_DOMAIN:-local}" +FQDN="${HOSTNAME}.${DOMAIN}" + +# Set hostname +hostnamectl set-hostname "$FQDN" 2>/dev/null || echo "$FQDN" > /etc/hostname + +# Update /etc/hosts +if ! grep -q "$FQDN" /etc/hosts; then + echo "127.0.0.1 $FQDN $HOSTNAME localhost" > /etc/hosts + echo "::1 $FQDN $HOSTNAME localhost" >> /etc/hosts +fi + +# Set server name in BlueOnyx config if CCEd is available +if [ -x /usr/sausalito/sbin/cced ]; then + sleep 2 + /usr/sausalito/bin/cceclient set System.hostname "$HOSTNAME" 2>/dev/null || true + /usr/sausalito/bin/cceclient set System.domainname "$DOMAIN" 2>/dev/null || true +fi + +echo "Network configuration set: $FQDN" +NETSCRIPT + +chmod +x /usr/local/bin/blueonyx-network-setup + +# Create systemd service for BlueOnyx network setup +cat > /etc/systemd/system/blueonyx-network-setup.service << 'SYSTEMDNET' +[Unit] +Description=BlueOnyx Network Setup for Container +After=network.target cced.service +Before=httpd.service admserv.service + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/blueonyx-network-setup +RemainAfterExit=yes +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target +SYSTEMDNET + +# Initialize BlueOnyx services +echo "Initializing BlueOnyx services..." +if [ -x /usr/sausalito/scripts/initServices.sh ]; then + /usr/sausalito/scripts/initServices.sh || { + echo "WARNING: initServices.sh returned non-zero, continuing anyway..." + } +else + echo "ERROR: initServices.sh not found" >&2 + exitCode=1 + exit $exitCode +fi + +# Fix Apache configuration - load mod_authnz_external +echo "Configuring Apache modules..." +if [ -f /etc/httpd/conf.modules.d/10-auth_external.conf ]; then + echo "LoadModule authnz_external_module modules/mod_authnz_external.so" >> /etc/httpd/conf.modules.d/10-auth_external.conf +fi + +# Generate Dovecot SSL certificates and DH parameters +echo "Configuring Dovecot SSL..." +mkdir -p /etc/pki/dovecot/certs /etc/pki/dovecot/private + +# Generate DH parameters (required for SSL) +if [ ! -f /etc/dovecot/dh.pem ]; then + echo "Generating Dovecot DH parameters (this may take a few minutes)..." + openssl dhparam -out /etc/dovecot/dh.pem 2048 2>/dev/null || \ + cp /usr/share/dovecot/dh.pem /etc/dovecot/dh.pem 2>/dev/null || \ + echo "Warning: Could not generate DH parameters" +fi + +# Generate self-signed CA and certificates if they don't exist +if [ ! -f /etc/pki/dovecot/certs/ca.pem ]; then + echo "Generating Dovecot CA and certificates..." + # Generate CA + openssl req -new -x509 -days 3650 -nodes \ + -out /etc/pki/dovecot/certs/ca.pem \ + -keyout /etc/pki/dovecot/private/ca-key.pem \ + -subj "/C=US/ST=State/L=City/O=BlueOnyx/OU=IT/CN=Dovecot CA" 2>/dev/null || true + + # Generate server certificate + openssl req -new -nodes \ + -out /etc/pki/dovecot/certs/dovecot.csr \ + -keyout /etc/pki/dovecot/private/dovecot.key \ + -subj "/C=US/ST=State/L=City/O=BlueOnyx/OU=IT/CN=localhost" 2>/dev/null || true + + openssl x509 -req -in /etc/pki/dovecot/certs/dovecot.csr \ + -CA /etc/pki/dovecot/certs/ca.pem \ + -CAkey /etc/pki/dovecot/private/ca-key.pem \ + -CAcreateserial -days 3650 \ + -out /etc/pki/dovecot/certs/dovecot.pem 2>/dev/null || true + + # Create symlink for private key (Dovecot config expects dovecot.pem) + ln -sf dovecot.key /etc/pki/dovecot/private/dovecot.pem 2>/dev/null || true + + # Set permissions + chmod 600 /etc/pki/dovecot/private/* 2>/dev/null || true + chmod 644 /etc/pki/dovecot/certs/* 2>/dev/null || true +fi + +# Enable BlueOnyx services +echo "Enabling BlueOnyx systemd services..." +systemctl enable cced.service 2>/dev/null || true +systemctl enable admserv.service 2>/dev/null || true +systemctl enable httpd.service 2>/dev/null || true +systemctl enable mysqld.service 2>/dev/null || true +systemctl enable named.service 2>/dev/null || true +systemctl enable dovecot.service 2>/dev/null || true +systemctl enable postfix.service 2>/dev/null || true +systemctl enable proftpd.service 2>/dev/null || true +systemctl enable valkey.service 2>/dev/null || true +systemctl enable blueonyx-network-setup.service 2>/dev/null || true + +# Create startup info script +cat > /usr/local/bin/blueonyx-info << 'INFOEOF' +#!/usr/bin/env bash +# Display BlueOnyx access information + +HOSTNAME=$(hostname -f 2>/dev/null || hostname) +IP_ADDR=$(hostname -I 2>/dev/null | awk '{print $1}') + +cat << INFO + +======================================== +BlueOnyx Control Panel Ready +======================================== + +Web Interface (HTTPS): + https://${IP_ADDR}:444/ + https://${HOSTNAME}:444/ + +Admin Login: + Username: admin + Password: (set on first login) + +Root SSH Access: + Username: root + Password: blueonyx + +Services Status: + CCEd: $(systemctl is-active cced 2>/dev/null || echo "unknown") + AdmServ: $(systemctl is-active admserv 2>/dev/null || echo "unknown") + Apache: $(systemctl is-active httpd 2>/dev/null || echo "unknown") + MySQL: $(systemctl is-active mysqld 2>/dev/null || echo "unknown") + +======================================== + +For more info: https://www.blueonyx.it/ + +INFO +INFOEOF + +chmod +x /usr/local/bin/blueonyx-info + +# Create container startup wrapper +cat > /usr/local/bin/blueonyx-startup << 'STARTEOF' +#!/usr/bin/env bash +# BlueOnyx container startup tasks + +# Wait for key services to be ready (systemctl is-system-running may never return "running" in containers) +echo "Waiting for core services to start..." +timeout=120 +count=0 +while [ $count -lt $timeout ]; do + # Check if cced.init is active (most important service) + if systemctl is-active --quiet cced.init 2>/dev/null; then + echo "CCEd is active, proceeding with configuration..." + sleep 2 # Give it a moment to fully initialize + break + fi + sleep 1 + count=$((count + 1)) +done + +if [ $count -ge $timeout ]; then + echo "WARNING: CCEd did not start within timeout, continuing anyway..." +fi + +# Run network setup +/usr/local/bin/blueonyx-network-setup + +# Apply environment variable configuration +/usr/local/bin/blueonyx-env-config + +# Display info +/usr/local/bin/blueonyx-info +STARTEOF + +chmod +x /usr/local/bin/blueonyx-startup + +# Create systemd service to run startup tasks +cat > /etc/systemd/system/blueonyx-startup.service << 'SYSTEMDSTART' +[Unit] +Description=BlueOnyx Container Startup Tasks +After=multi-user.target cced.init.service admserv.service mariadb.service +Wants=cced.init.service admserv.service mariadb.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/blueonyx-startup +StandardOutput=journal+console +StandardError=journal+console +TimeoutStartSec=300 + +[Install] +WantedBy=multi-user.target +SYSTEMDSTART + +systemctl enable blueonyx-startup.service 2>/dev/null || true + +# Create persistent data directories +mkdir -p /data/db/mariadb +mkdir -p /data/db/valkey +mkdir -p /data/home +mkdir -p /data/www +mkdir -p /data/mail +mkdir -p /data/dns +mkdir -p /config/blueonyx +mkdir -p /config/mariadb +mkdir -p /config/apache +mkdir -p /config/nginx +mkdir -p /config/postfix +mkdir -p /config/dovecot +mkdir -p /config/bind +mkdir -p /config/proftpd +mkdir -p /config/ssl/certs +mkdir -p /config/ssl/private +mkdir -p /logs + +# Create volume mount info +cat > /usr/local/share/template-files/config/README-volumes.txt << 'VOLEOF' +BlueOnyx Container Volumes +========================== + +Required volumes for persistent data: + +/data/db/mariadb - MariaDB/MySQL databases +/data/db/valkey - Valkey (Redis) data +/data/home - User home directories +/data/www - Web hosting files +/data/mail - Mail data (Dovecot) +/data/dns - BIND DNS zone files +/config/blueonyx - BlueOnyx configuration +/config/mariadb - MariaDB configuration +/config/apache - Apache configuration +/config/nginx - Nginx configuration +/config/postfix - Postfix configuration +/config/dovecot - Dovecot configuration +/config/bind - BIND configuration +/config/proftpd - ProFTPD configuration +/config/ssl - SSL/TLS certificates (self-signed and Let's Encrypt) + ├── certs/ - Certificate files + ├── private/ - Private keys + └── letsencrypt/ - Let's Encrypt certificates +/logs - All service logs + └── letsencrypt/ - Certbot logs + +Example docker run: + -v blueonyx-data:/data + -v blueonyx-config:/config + -v blueonyx-logs:/logs + +VOLEOF # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Main script +echo "" +echo "==========================================" +echo "BlueOnyx ${BLUEONYX_VERSION} installation complete!" +echo "==========================================" +echo "" +echo "IMPORTANT: This container requires:" +echo " - Privileged mode: --privileged" +echo " - Cgroup access: -v /sys/fs/cgroup:/sys/fs/cgroup:rw" +echo " - Port mapping: -p 444:444 -p 81:81" +echo "" +echo "On first start, admin user will be created." +echo "Access the web interface at https://IP:444/" +echo "" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Set the exit code -exitCode=$? +# exitCode is already set above on errors # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - exit $exitCode diff --git a/rootfs/usr/local/bin/blueonyx-env-config b/rootfs/usr/local/bin/blueonyx-env-config new file mode 100755 index 0000000..ec3cbe8 --- /dev/null +++ b/rootfs/usr/local/bin/blueonyx-env-config @@ -0,0 +1,334 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202602021746-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@Copyright : Copyright 2026 CasjaysDev +# @@File : blueonyx-env-config +# @@Description : BlueOnyx environment variable configuration handler +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Apply all environment variable configurations to BlueOnyx at runtime +set -e + +# Wait for CCEd to be ready (check for cced.init service, not cceclient) +wait_for_cced() { + local timeout=120 + local count=0 + + # Wait for cced.init service to be active + while [ $count -lt $timeout ]; do + if systemctl is-active --quiet cced.init 2>/dev/null; then + # Give it a few extra seconds to fully initialize + sleep 3 + return 0 + fi + sleep 1 + count=$((count + 1)) + done + + echo "WARNING: CCEd not ready after ${timeout}s, continuing anyway..." >&2 + return 1 +} + +# Get Docker gateway IP for default relay +get_docker_gateway() { + ip route | grep default | awk '{print $3}' | head -1 +} + +echo "Configuring BlueOnyx from environment variables..." + +# Network Configuration +BLUEONYX_HOSTNAME="${BLUEONYX_HOSTNAME:-blueonyx}" +BLUEONYX_DOMAIN="${BLUEONYX_DOMAIN:-local}" +BLUEONYX_IPV4="${BLUEONYX_IPV4:-$(hostname -I 2>/dev/null | awk '{print $1}')}" +BLUEONYX_IPV6="${BLUEONYX_IPV6:-}" +BLUEONYX_GATEWAY="${BLUEONYX_GATEWAY:-$(get_docker_gateway)}" +BLUEONYX_NAMESERVER="${BLUEONYX_NAMESERVER:-8.8.8.8}" + +# Admin Configuration +BLUEONYX_ADMIN_USER="${BLUEONYX_ADMIN_USER:-admin}" +BLUEONYX_ADMIN_PASS="${BLUEONYX_ADMIN_PASS:-}" +BLUEONYX_ADMIN_EMAIL="${BLUEONYX_ADMIN_EMAIL:-admin@${BLUEONYX_DOMAIN}}" + +# Mail Configuration +BLUEONYX_MTA="${BLUEONYX_MTA:-postfix}" +BLUEONYX_POSTFIX_MODE="${BLUEONYX_POSTFIX_MODE:-satellite}" +BLUEONYX_POSTFIX_RELAY="${BLUEONYX_POSTFIX_RELAY:-$(get_docker_gateway)}" +BLUEONYX_POSTFIX_RELAY_PORT="${BLUEONYX_POSTFIX_RELAY_PORT:-25}" +BLUEONYX_POSTFIX_RELAY_USER="${BLUEONYX_POSTFIX_RELAY_USER:-}" +BLUEONYX_POSTFIX_RELAY_PASS="${BLUEONYX_POSTFIX_RELAY_PASS:-}" +BLUEONYX_MAIL_RELAY="${BLUEONYX_MAIL_RELAY:-${BLUEONYX_POSTFIX_RELAY}}" +BLUEONYX_MAIL_RELAY_PORT="${BLUEONYX_MAIL_RELAY_PORT:-${BLUEONYX_POSTFIX_RELAY_PORT}}" +BLUEONYX_ENABLE_SPAM_FILTER="${BLUEONYX_ENABLE_SPAM_FILTER:-yes}" +BLUEONYX_ENABLE_ANTIVIRUS="${BLUEONYX_ENABLE_ANTIVIRUS:-yes}" +BLUEONYX_ENABLE_DKIM="${BLUEONYX_ENABLE_DKIM:-yes}" +BLUEONYX_ENABLE_DOVECOT="${BLUEONYX_ENABLE_DOVECOT:-yes}" + +# Database Configuration +BLUEONYX_DB_TYPE="${BLUEONYX_DB_TYPE:-mariadb}" +BLUEONYX_DB_ROOT_PASS="${BLUEONYX_DB_ROOT_PASS:-}" +BLUEONYX_ENABLE_POSTGRES="${BLUEONYX_ENABLE_POSTGRES:-no}" + +# Valkey/Redis Configuration +BLUEONYX_ENABLE_VALKEY="${BLUEONYX_ENABLE_VALKEY:-yes}" +BLUEONYX_VALKEY_PORT="${BLUEONYX_VALKEY_PORT:-6379}" +BLUEONYX_VALKEY_MAXMEM="${BLUEONYX_VALKEY_MAXMEM:-256mb}" + +# Web Server Configuration +BLUEONYX_WEB_PROXY="${BLUEONYX_WEB_PROXY:-nginx}" +BLUEONYX_HTTP2_ENABLED="${BLUEONYX_HTTP2_ENABLED:-yes}" +BLUEONYX_TLS_VERSION="${BLUEONYX_TLS_VERSION:-1.3}" +BLUEONYX_ENABLE_SSL="${BLUEONYX_ENABLE_SSL:-yes}" +BLUEONYX_SSL_TYPE="${BLUEONYX_SSL_TYPE:-selfsigned}" + +# Certbot/Let's Encrypt Configuration +BLUEONYX_CERTBOT_ENABLED="${BLUEONYX_CERTBOT_ENABLED:-no}" +BLUEONYX_CERTBOT_EMAIL="${BLUEONYX_CERTBOT_EMAIL:-${BLUEONYX_ADMIN_EMAIL}}" +BLUEONYX_CERTBOT_DOMAINS="${BLUEONYX_CERTBOT_DOMAINS:-}" +BLUEONYX_CERTBOT_WEBROOT="${BLUEONYX_CERTBOT_WEBROOT:-/var/www/html}" + +# DNS Configuration +BLUEONYX_ENABLE_DNS="${BLUEONYX_ENABLE_DNS:-yes}" +BLUEONYX_DNS_FORWARDERS="${BLUEONYX_DNS_FORWARDERS:-8.8.8.8 8.8.4.4}" + +# FTP Configuration +BLUEONYX_ENABLE_FTP="${BLUEONYX_ENABLE_FTP:-yes}" +BLUEONYX_FTP_PASSIVE_PORTS="${BLUEONYX_FTP_PASSIVE_PORTS:-30000-30100}" + +# Virtual Hosts (comma-separated list: domain1.com,domain2.com) +BLUEONYX_VHOSTS="${BLUEONYX_VHOSTS:-}" + +# Feature Toggles +BLUEONYX_ENABLE_CALDAV="${BLUEONYX_ENABLE_CALDAV:-yes}" +BLUEONYX_ENABLE_DOCKER="${BLUEONYX_ENABLE_DOCKER:-yes}" +BLUEONYX_ENABLE_WEBALIZER="${BLUEONYX_ENABLE_WEBALIZER:-yes}" + +# Wait for CCEd +if wait_for_cced; then + echo "CCEd is ready, applying configuration..." + + # Note: CCEd client commands may not work in initial boot, so we configure files directly + # This ensures configuration happens even if cceclient is unavailable + + # Generate passwords if not provided + if [ -z "$BLUEONYX_ADMIN_PASS" ]; then + BLUEONYX_ADMIN_PASS="$(openssl rand -base64 16)" + echo "Generated admin password: $BLUEONYX_ADMIN_PASS" > /data/ADMIN_PASSWORD.txt + chmod 600 /data/ADMIN_PASSWORD.txt + echo "Admin password saved to: /data/ADMIN_PASSWORD.txt" + fi + + if [ -z "$BLUEONYX_DB_ROOT_PASS" ]; then + BLUEONYX_DB_ROOT_PASS="$(openssl rand -base64 16)" + echo "Generated MySQL root password: $BLUEONYX_DB_ROOT_PASS" > /data/MYSQL_ROOT_PASSWORD.txt + chmod 600 /data/MYSQL_ROOT_PASSWORD.txt + echo "MySQL root password saved to: /data/MYSQL_ROOT_PASSWORD.txt" + fi + + # Configure MySQL root password if MySQL is running + if systemctl is-active mysqld >/dev/null 2>&1 || systemctl is-active mariadb >/dev/null 2>&1; then + mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${BLUEONYX_DB_ROOT_PASS}';" 2>/dev/null || true + fi + + # Configure admin user + if id "$BLUEONYX_ADMIN_USER" >/dev/null 2>&1; then + echo "$BLUEONYX_ADMIN_USER:$BLUEONYX_ADMIN_PASS" | chpasswd 2>/dev/null || true + fi + + # Configure Postfix (satellite mode by default) + if [ -f /etc/postfix/main.cf ]; then + echo "Configuring Postfix in ${BLUEONYX_POSTFIX_MODE} mode..." + + if [ "$BLUEONYX_POSTFIX_MODE" = "satellite" ]; then + postconf -e "relayhost = [${BLUEONYX_POSTFIX_RELAY}]:${BLUEONYX_POSTFIX_RELAY_PORT}" + postconf -e "inet_interfaces = loopback-only" + postconf -e "mydestination = localhost" + + # Configure SASL auth if credentials provided + if [ -n "$BLUEONYX_POSTFIX_RELAY_USER" ] && [ -n "$BLUEONYX_POSTFIX_RELAY_PASS" ]; then + echo "[${BLUEONYX_POSTFIX_RELAY}]:${BLUEONYX_POSTFIX_RELAY_PORT} ${BLUEONYX_POSTFIX_RELAY_USER}:${BLUEONYX_POSTFIX_RELAY_PASS}" > /etc/postfix/sasl_passwd + postmap /etc/postfix/sasl_passwd + chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db + postconf -e "smtp_sasl_auth_enable = yes" + postconf -e "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" + postconf -e "smtp_sasl_security_options = noanonymous" + postconf -e "smtp_tls_security_level = may" + fi + fi + + systemctl reload postfix 2>/dev/null || true + fi + + # Configure Dovecot SSL certificates + if [ "$BLUEONYX_ENABLE_DOVECOT" = "yes" ] && [ ! -f /config/ssl/certs/dovecot.pem ]; then + echo "Generating self-signed SSL certificates for Dovecot..." + mkdir -p /config/ssl/certs /config/ssl/private + + openssl req -new -x509 -days 3650 -nodes \ + -out /config/ssl/certs/dovecot.pem \ + -keyout /config/ssl/private/dovecot.key \ + -subj "/C=US/ST=State/L=City/O=BlueOnyx/OU=Mail/CN=${BLUEONYX_HOSTNAME}.${BLUEONYX_DOMAIN}" 2>/dev/null || true + + chmod 644 /config/ssl/certs/dovecot.pem + chmod 600 /config/ssl/private/dovecot.key + + # Update Dovecot to use /config/ssl certificates + if [ -f /etc/dovecot/conf.d/10-ssl.conf ]; then + sed -i "s|ssl_cert = .*|ssl_cert = /dev/null || true + systemctl restart dovecot 2>/dev/null || true + fi + + # Configure Valkey/Redis + if [ "$BLUEONYX_ENABLE_VALKEY" = "yes" ]; then + if [ -f /etc/valkey/valkey.conf ]; then + echo "Configuring Valkey..." + sed -i "s/^port .*/port ${BLUEONYX_VALKEY_PORT}/" /etc/valkey/valkey.conf + sed -i "s/^# maxmemory .*/maxmemory ${BLUEONYX_VALKEY_MAXMEM}/" /etc/valkey/valkey.conf + sed -i "s/^# maxmemory-policy .*/maxmemory-policy allkeys-lru/" /etc/valkey/valkey.conf + systemctl enable valkey 2>/dev/null || true + systemctl restart valkey 2>/dev/null || true + fi + else + systemctl disable valkey 2>/dev/null || true + systemctl stop valkey 2>/dev/null || true + fi + + # Configure Certbot for Let's Encrypt + if [ "$BLUEONYX_CERTBOT_ENABLED" = "yes" ] && [ -n "$BLUEONYX_CERTBOT_DOMAINS" ]; then + echo "Setting up Certbot for Let's Encrypt..." + + # Split comma-separated domains + IFS=',' read -ra DOMAINS <<< "$BLUEONYX_CERTBOT_DOMAINS" + DOMAIN_ARGS="" + for domain in "${DOMAINS[@]}"; do + domain=$(echo "$domain" | xargs) # trim whitespace + DOMAIN_ARGS="$DOMAIN_ARGS -d $domain" + done + + # Request certificates (webroot mode) - store in /config/ssl + certbot certonly --webroot -w "$BLUEONYX_CERTBOT_WEBROOT" \ + $DOMAIN_ARGS \ + --email "$BLUEONYX_CERTBOT_EMAIL" \ + --agree-tos --non-interactive \ + --keep-until-expiring \ + --config-dir /config/ssl/letsencrypt \ + --work-dir /var/lib/letsencrypt \ + --logs-dir /logs/letsencrypt 2>/dev/null || { + echo "WARNING: Certbot certificate request failed, continuing with self-signed" + } + + # Set up auto-renewal cron + echo "0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q --config-dir /config/ssl/letsencrypt --work-dir /var/lib/letsencrypt --logs-dir /logs/letsencrypt" > /etc/cron.d/certbot-renew + fi + + # Process Virtual Hosts + if [ -n "$BLUEONYX_VHOSTS" ]; then + echo "Configuring virtual hosts..." + IFS=',' read -ra VHOSTS <<< "$BLUEONYX_VHOSTS" + for vhost in "${VHOSTS[@]}"; do + vhost=$(echo "$vhost" | xargs) # trim whitespace + if [ -n "$vhost" ]; then + echo " - Creating vhost: $vhost" + + # Create document root + mkdir -p "/var/www/vhosts/$vhost/httpdocs" + mkdir -p "/var/www/vhosts/$vhost/logs" + + # Create basic index.html + if [ ! -f "/var/www/vhosts/$vhost/httpdocs/index.html" ]; then + cat > "/var/www/vhosts/$vhost/httpdocs/index.html" << VHOSTHTML + + +$vhost + +

Welcome to $vhost

+

This site is hosted on BlueOnyx.

+ + +VHOSTHTML + fi + + # Set permissions + chown -R apache:apache "/var/www/vhosts/$vhost" 2>/dev/null || true + + # Create Apache vhost config + cat > "/etc/httpd/conf.d/vhost_${vhost}.conf" << VHOSTCONF + + ServerName ${vhost} + DocumentRoot /var/www/vhosts/${vhost}/httpdocs + + + AllowOverride All + Require all granted + + + ErrorLog /var/www/vhosts/${vhost}/logs/error_log + CustomLog /var/www/vhosts/${vhost}/logs/access_log combined + +VHOSTCONF + fi + done + + # Reload Apache + systemctl reload httpd 2>/dev/null || true + fi + + # Enable/disable remaining services + [ "$BLUEONYX_ENABLE_DNS" = "yes" ] && systemctl enable named 2>/dev/null || systemctl disable named 2>/dev/null + [ "$BLUEONYX_ENABLE_FTP" = "yes" ] && systemctl enable proftpd 2>/dev/null || systemctl disable proftpd 2>/dev/null + [ "$BLUEONYX_ENABLE_SPAM_FILTER" = "yes" ] && systemctl enable spamassassin 2>/dev/null || true + [ "$BLUEONYX_ENABLE_ANTIVIRUS" = "yes" ] && systemctl enable clamd@scan 2>/dev/null || true + + # Configure FTP passive ports + if [ -f /etc/proftpd.conf ] && [ "$BLUEONYX_ENABLE_FTP" = "yes" ]; then + if ! grep -q "PassivePorts" /etc/proftpd.conf; then + echo "PassivePorts $BLUEONYX_FTP_PASSIVE_PORTS" >> /etc/proftpd.conf + systemctl reload proftpd 2>/dev/null || true + fi + fi + + # Configure DNS forwarders + if [ -f /etc/named.conf ] && [ "$BLUEONYX_ENABLE_DNS" = "yes" ]; then + if ! grep -q "forwarders" /etc/named.conf; then + sed -i "/options {/a \ forwarders { $(echo $BLUEONYX_DNS_FORWARDERS | sed 's/ /; /g'); };" /etc/named.conf + systemctl reload named 2>/dev/null || true + fi + fi + + echo "" + echo "============================================" + echo "BlueOnyx Configuration Complete!" + echo "============================================" + echo "" + echo "System Configuration:" + echo " Hostname: $BLUEONYX_HOSTNAME.$BLUEONYX_DOMAIN" + echo " Admin User: $BLUEONYX_ADMIN_USER" + echo " Admin Email: $BLUEONYX_ADMIN_EMAIL" + echo " IPv4: $BLUEONYX_IPV4" + echo "" + echo "Services:" + echo " Postfix Mode: $BLUEONYX_POSTFIX_MODE" + echo " Postfix Relay: $BLUEONYX_POSTFIX_RELAY:$BLUEONYX_POSTFIX_RELAY_PORT" + echo " DNS: $([ "$BLUEONYX_ENABLE_DNS" = "yes" ] && echo "Enabled" || echo "Disabled")" + echo " FTP: $([ "$BLUEONYX_ENABLE_FTP" = "yes" ] && echo "Enabled" || echo "Disabled")" + echo " Valkey: $([ "$BLUEONYX_ENABLE_VALKEY" = "yes" ] && echo "Enabled (port $BLUEONYX_VALKEY_PORT)" || echo "Disabled")" + echo " Dovecot: $([ "$BLUEONYX_ENABLE_DOVECOT" = "yes" ] && echo "Enabled" || echo "Disabled")" + echo " Certbot: $([ "$BLUEONYX_CERTBOT_ENABLED" = "yes" ] && echo "Enabled" || echo "Disabled")" + echo "" + if [ -n "$BLUEONYX_VHOSTS" ]; then + echo "Virtual Hosts: $BLUEONYX_VHOSTS" + echo "" + fi + echo "============================================" + echo "" +else + echo "WARNING: CCEd not ready, skipping configuration" +fi + +exit 0