Initial commit

This commit is contained in:
cytopia 2016-10-09 18:47:49 +02:00
commit be1620e077
No known key found for this signature in database
GPG Key ID: 6D56EDB8695128A2
17 changed files with 1865 additions and 0 deletions

89
.gitignore vendored Normal file
View File

@ -0,0 +1,89 @@
# Note:
# To effectively apply the changes you will have
# to re-index the git index (if there are already
# commited files)
#
# $ git rm -r --cached .
# $ git add .
# $ git commit -m ".gitignore index rebuild"
#
######################################
# CUSTOM
######################################
.env
log/
run/
######################################
# GENERIC
######################################
###### std ######
.lock
*.log
###### patches/diffs ######
*.patch
*.diff
*.orig
*.rej
######################################
# Operating Systems
######################################
###### OSX ######
._*
.DS*
.Spotlight-V100
.Trashes
###### Windows ######
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/
*.lnk
*.shortcut
######################################
# Editors
######################################
###### Sublime ######
*.sublime-workspace
*.sublime-project
###### Eclipse ######
.classpath
.buildpath
.project
.settings/
###### Netbeans ######
/nbproject/
###### Intellij IDE ######
.idea/
.idea_modules/
###### vim ######
*.swp
*.swo
*~
###### TextMate ######
.tm_properties
*.tmproj
###### BBEdit ######
*.bbprojectd
*.bbproject

21
LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 cytopia
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# Devilbox
The ultimate Docker LAMP/LEMP Stack for local development.
## Specials
* All logs are available on your Host computer
* MySQL localhost socket is available in PHP container
* MySQL `127.0.0.1:3006` is available in PHP container
* Xdebug is included
## Run-time Matrix
You can choose any combination of the following docker images during run-time:
| Webserver | Database | PHP |
|-----------|----------|-----|
| Apache 2.2 | [MySQL 5.5](https://github.com/cytopia/docker-mysql-5.5) | [PHP 5.5](https://github.com/cytopia/docker-php-fpm-5.5) |
| [Apache 2.4](https://github.com/cytopia/docker-apache-2.4) | MySQL 5.6 | [PHP 5.6](https://github.com/cytopia/docker-php-fpm-5.6) |
| Nginx | MySQL 5.7 | [PHP 7.0](https://github.com/cytopia/docker-php-fpm-7.0) |
| | MariaDB 5 | [PHP 7.1](https://github.com/cytopia/docker-php-fpm-7.1) |
| | MariaDB 10 | |
## Start
1. Copy `env-example` to `.env`
2. Edit `.env`
3. `docker-compose up`

View File

@ -0,0 +1,3 @@
<?php
// Fix DocumentRoot for VirtualDocumentRoot Hosts
$_SERVER['DOCUMENT_ROOT'] = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['SCRIPT_FILENAME']);

30
bin/apache-2.4/splitlogs.php Executable file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env php
<?php
// TODO: logpath could also be passed via CMD argument
// so this script could be more general
$path = "/var/log/apache-2.4";
$fh_timeout = 30; // 30 sek.
$fd = fopen("php://stdin", "r");
while (!feof($fd)) {
$row = fgets($fd);
list($vhost, $h, $l, $u, $t, $r, $s, $b, $referrer, $ua) = explode(";", $row, 10);
if (!isset(${$vhost})) {
${$vhost} = fopen($path . "/" . $vhost . "_access.log", "a+");
}
$lastwrite[$vhost] = time();
fputs (${$vhost}, "$h $l $u $t $r $s $b $referrer $ua");
foreach ($lastwrite as $vhost => $time) {
if ((time() - ($time+30)) >=0) {
fclose(${$vhost});
unset(${$vhost});
unset($lastwrite[$vhost]);
}
}
}

262
docker-compose.yml Normal file
View File

@ -0,0 +1,262 @@
##
## -------------------------
## | D E V I L S T A C K |
## -------------------------
##
## Local LAMP/LEMP stack
##
##
##
##
##
## -- DO NOT EDIT THIS FILE --
##
## Edit '.env' for configuration.
##
## If '.env' does not exist, copy 'env-example' to '.env'
## $ cp env-example .env
##
version: '2'
################################################################################
# SERVICES
################################################################################
services:
# ----------------------------------------
# HTTP
# ----------------------------------------
httpd:
#image: cytopia/${HTTPD_SERVER}:1
image: cytopia/${HTTPD_SERVER}
# Manually build via `docker-compose build`
#build:
#context: https://github.com/cytopia/docker-${HTTPD_SERVER}.git#1
# context: https://github.com/cytopia/docker-${HTTPD_SERVER}.git
environment:
# Show all executed commands during docker entrypoint?
- DEBUG_COMPOSE_ENTRYPOINT=${DEBUG_COMPOSE_ENTRYPOINT}
# Adjust timezone
- TIMEZONE=${TIMEZONE}
# Tell the webserver to look into this directory
# for additional configuration files.
#
# @see volumes:: - ./etc/${HTTPD_SERVER}:/etc/${HTTPD_SERVER}
- CUSTOM_HTTPD_CONF_DIR=/etc/${HTTPD_SERVER}
ports:
# ---- Format: ----
# [HOST-ADDR : ] HOST-PORT : DOCKER-PORT
- "127.0.0.1:80:80"
networks:
app_net:
ipv4_address: 172.16.238.10
volumes:
# ---- Format: ----
# HOST-DIRECTORY : DOCKER-DIRECTORY
# Custom scripts/binaries required for httpd server vhost
# configuration to work.
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
- ./bin/${HTTPD_SERVER}:/opt/bin
# Mount user-defined httpd configuration files
# @see environment::CUSTOM_HTTPD_CONF_DIR for how this
# is added in httpd server
- ./etc/${HTTPD_SERVER}:/etc/${HTTPD_SERVER}
# Mount user-defined httpd log
# @see ./etc/${HTTPD_SERVER}/*.conf for log defines
- ./log/${HTTPD_SERVER}:/var/log/${HTTPD_SERVER}
# Mount custom intranet
# (configured in /etc/${HTTPD_SERVER}/01-vhost-default.conf)
- ./www:/var/www/default
# Mount custom mass virtual hosting
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
- ${HOST_PATH_TO_WWW_DOCROOTS}:/shared/httpd
links:
# ---- Format: ----
# SERVICE [ : ALIAS]
- "db:database"
- "php:php-fpm"
# ----------------------------------------
# PHP-FPM
# ----------------------------------------
php:
#image: cytopia/${PHP_SERVER}:1
image: cytopia/${PHP_SERVER}
# Manually build via `docker-compose build`
#build:
#context: https://github.com/cytopia/docker-${PHP_SERVER}.git#1
# context: https://github.com/cytopia/docker-${PHP_SERVER}.git
environment:
# Show all executed commands during docker entrypoint?
- DEBUG_COMPOSE_ENTRYPOINT=${DEBUG_COMPOSE_ENTRYPOINT}
# Adjust timezone
- TIMEZONE=${TIMEZONE}
##
## PHP-FPM Listening Port
##
- PHP_FPM_PORT=9000
##
## PHP Xdebug
##
- PHP_XDEBUG_ENABLE=${PHP_XDEBUG_ENABLE}
- PHP_XDEBUG_REMOTE_PORT=${PHP_XDEBUG_REMOTE_PORT}
- PHP_XDEBUG_REMOTE_HOST=${PHP_XDEBUG_REMOTE_HOST}
##
## PHP Tweaks
##
- PHP_MAX_EXECUTION_TIME=${PHP_MAX_EXECUTION_TIME}
- PHP_MAX_INPUT_TIME=${PHP_MAX_INPUT_TIME}
- PHP_MEMORY_LIMIT=${PHP_MEMORY_LIMIT}
- PHP_POST_MAX_SIZE=${PHP_POST_MAX_SIZE}
- PHP_UPLOAD_MAX_FILESIZE=${PHP_UPLOAD_MAX_FILESIZE}
- PHP_MAX_INPUT_VARS=${PHP_MAX_INPUT_VARS}
###
### PHP Error Handling
###
- PHP_ERROR_REPORTING=${PHP_ERROR_REPORTING}
- PHP_DISPLAY_ERRORS=${PHP_DISPLAY_ERRORS}
- PHP_TRACK_ERRORS=${PHP_TRACK_ERRORS}
##
## Map remote MySQL Port to 127.0.0.1
##
- FORWARD_MYSQL_PORT_TO_LOCALHOST=1
- MYSQL_REMOTE_ADDR=172.16.238.12
- MYSQL_REMOTE_PORT=3306
- MYSQL_LOCAL_PORT=3306
##
## Mount remote MySQL socket file to local disk
##
- MOUNT_MYSQL_SOCKET_TO_LOCALDISK=1
- MYSQL_SOCKET_PATH=/tmp/mysql/mysqld.sock
##
## Additional variables needed by custom intranet
##
- HOST_PATH_TO_WWW_DOCROOTS=${HOST_PATH_TO_WWW_DOCROOTS}
- HOST_PATH_TO_MYSQL_DATADIR=${HOST_PATH_TO_MYSQL_DATADIR}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
networks:
app_net:
ipv4_address: 172.16.238.11
volumes:
# ---- Format: ----
# HOST-DIRECTORY : DOCKER-DIRECTORY
# Mount logs
- ./log/${PHP_SERVER}:/var/log/php-fpm
# Mount MySQL Socket directory
- ./run/mysql:/tmp/mysql
# Mount custom intranet
# (configured in /etc/${HTTPD_SERVER}/01-vhost-default.conf)
- ./www:/var/www/default
# Mount custom mass virtual hosting
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
- ${HOST_PATH_TO_WWW_DOCROOTS}:/shared/httpd
# ----------------------------------------
# DATABASE
# ----------------------------------------
db:
#image: cytopia/${MYSQL_SERVER}:1
image: cytopia/${MYSQL_SERVER}
# Manually build via `docker-compose build`
#build:
#context: https://github.com/cytopia/docker-${MYSQL_SERVER}.git#1
# context: https://github.com/cytopia/docker-${MYSQL_SERVER}.git
environment:
# Show all executed commands during docker entrypoint?
- DEBUG_COMPOSE_ENTRYPOINT=${DEBUG_COMPOSE_ENTRYPOINT}
# Adjust timezone
- TIMEZONE=${TIMEZONE}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_SOCKET_DIR=/tmp/mysql
# Runtime settings
- MYSQL_GENERAL_LOG=${MYSQL_GENERAL_LOG}
- MYSQL_INNODB_BUFFER_POOL_SIZE=${MYSQL_INNODB_BUFFER_POOL_SIZE}
- MYSQL_JOIN_BUFFER_SIZE=${MYSQL_JOIN_BUFFER_SIZE}
- MYSQL_SORT_BUFFER_SIZE=${MYSQL_SORT_BUFFER_SIZE}
- MYSQL_READ_RND_BUFFER_SIZE=${MYSQL_READ_RND_BUFFER_SIZE}
- MYSQL_SYMBOLIC_LINKS=${MYSQL_SYMBOLIC_LINKS}
- MYSQL_SQL_MODE=${MYSQL_SQL_MODE}
ports:
# [local-machine:]local-port:docker-port
- "127.0.0.1:3306:3306"
networks:
app_net:
ipv4_address: 172.16.238.12
volumes:
# ---- Format: ----
# HOST-DIRECTORY : DOCKER-DIRECTORY
# Mount logs
- ./log/${MYSQL_SERVER}:/var/log/mysql
# Mount MySQL Socket directory
- ./run/mysql:/tmp/mysql
# Mount MySQL Data directory
- ${HOST_PATH_TO_MYSQL_DATADIR}:/var/lib/mysql
################################################################################
# NETWORK
################################################################################
networks:
app_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1

221
env-example Normal file
View File

@ -0,0 +1,221 @@
###
### ---------------------------------------------------
### D E V I L B O X R U N - T I M E S E T T I N G S
### ---------------------------------------------------
###
### All the following settings are applied during
### $ docker-compose up
###
### No need to rebuild any dockers!
###
###
### Show all executed commands in each
### docker image during docker-compose up?
###
### 1: Yes
### 0: No
DEBUG_COMPOSE_ENTRYPOINT=0
################################################################################
###
### 1. Choose Images (Version)
###
################################################################################
###
### You can choose any combination of httpd, mysql or php.
### Each of them are fully compatible between one another.
###
###
### 1.1 Choose HTTP Server Image
###
#HTTPD_SERVER=apache-2.2
HTTPD_SERVER=apache-2.4
#HTTPD_SERVER=nginx-1
###
### 1.2 Choose MySQL Server Image
###
MYSQL_SERVER=mysql-5.5
#MYSQL_SERVER=mysql-5.6
#MYSQL_SERVER=mysql-5.7
#MYSQL_SERVER=mariadb-5
#MYSQL_SERVER=mariadb-10
###
### 1.3 Choose PHP Server Image
###
#PHP_SERVER=php-5.5
PHP_SERVER=php-fpm-5.6
#PHP_SERVER=php-7.0
#PHP_SERVER=php-7.1
#PHP_SERVER=hhvm-3
###
### 1.4 Timezone for all dockers and service config files
###
TIMEZONE=Europe/Berlin
################################################################################
###
### 2. Host Settings (Your computer)
###
################################################################################
##
## Local filesystem path to www projects.
##
##
HOST_PATH_TO_WWW_DOCROOTS=~/Sites
##
## Local filesystem path to mysql datadir.
##
## This can be an existing mysql data directory or empty.
## If it already is a mysql data directory with content,
## it will be mounted into the docker and used.
##
## If this directory is empty, a new mysql database will be
## created.
##
HOST_PATH_TO_MYSQL_DATADIR=~/data/mysql6
################################################################################
###
### 3. HTTP Docker Settings
###
################################################################################
# - no options here
################################################################################
###
### 4. MySQL Docker Settings
###
################################################################################
##
## MySQL root user password
##
## If $HOST_PATH_TO_MYSQL_DATADIR already contains an existing
## mysql datadir, enter the password for the existing mysql database
##
## If $HOST_PATH_TO_MYSQL_DATADIR is empty, choose a new password that
## will be applied
##
MYSQL_ROOT_PASSWORD=
###
### Custom MySQL Runtime Settings
###
MYSQL_GENERAL_LOG=1
MYSQL_INNODB_BUFFER_POOL_SIZE=512M
MYSQL_JOIN_BUFFER_SIZE=128M
MYSQL_SORT_BUFFER_SIZE=2M
MYSQL_READ_RND_BUFFER_SIZE=2M
MYSQL_SYMBOLIC_LINKS=0
MYSQL_SQL_MODE=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
################################################################################
###
### 5. PHP-FPM Docker Settings
###
################################################################################
###
### Xdebug
###
# Enable/Disable Xdebug
PHP_XDEBUG_ENABLE=0
# Your local port (your computer host [not the docker])
# where your ide/editor is listening for xdebug connections.
PHP_XDEBUG_REMOTE_PORT=9000
# Your local IP address (your computer host [not the docker])
# where your ide/editor is listening for xdebug connections.
PHP_XDEBUG_REMOTE_HOST=172.20.10.2
## TODO: Check if it works by automatically sending it to the broadcast address
###
### PHP Tweaks
###
# php.ini default setting:
# max_execution_time = 30
PHP_MAX_EXECUTION_TIME=90
# php.ini default setting:
# max_input_time = 60
PHP_MAX_INPUT_TIME=90
# php.ini default setting:
# memory_limit = 128M
PHP_MEMORY_LIMIT=256M
# php.ini default setting:
# post_max_size = 8M
PHP_POST_MAX_SIZE=100M
# php.ini default setting:
# upload_max_filesize = 2M
PHP_UPLOAD_MAX_FILESIZE=100M
# php.ini default setting:
# max_input_vars = 1000
PHP_MAX_INPUT_VARS=8000
###
### PHP Error Handling
###
# php.ini default setting:
# error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
PHP_ERROR_REPORTING=E_ALL
# php.ini default setting:
# display_errors = Off
PHP_DISPLAY_ERRORS=On
# php.ini default setting:
# track_errors = Off
PHP_TRACK_ERRORS=On

View File

@ -0,0 +1,23 @@
CustomLog "/var/log/apache-2.4/access_log" combined
ErrorLog "/var/log/apache-2.4/error_log"
LogLevel warn
AddDefaultCharset UTF-8
# No DNS
HostnameLookups Off
#
Timeout 60
KeepAlive On
KeepAliveTimeout 10
MaxKeepAliveRequests 100
#
#
EnableMMAP Off
EnableSendfile Off
#
#
#
#
XSendFile On
XSendFilePath /shared/httpd

View File

@ -0,0 +1,57 @@
##
## Default Host for http://localhost
##
<VirtualHost _default_:80>
ServerName localhost
ServerAdmin root@localhost
ErrorLog /var/log/apache-2.4/localhost-error.log
CustomLog /var/log/apache-2.4/localhost-access.log combined
DirectoryIndex index.php index.html
#RewriteEngine On
#RewriteRule ^/(.*\.php(/.*)?)$ fcgi://172.16.238.11:9000/var/www/default/htdocs/$1 [P]
# enablereuse
# Defining a worker will improve performance
# And in this case, re-use the worker (dependent on support from the fcgi application)
# If you have enough idle workers, this would only improve the performance marginally
#
# enablereuse requires Apache 2.4.11 or later
#<Proxy "fcgi://172.16.238.11:9000/" enablereuse=on max=10></Proxy>
<FilesMatch "\.php$">
Require all granted
# Pick one of the following approaches
# Use the standard TCP socket
SetHandler "proxy:fcgi://172.16.238.11:9000"
# If your version of httpd is 2.4.9 or newer (or has the back-ported feature), you can use the unix domain socket
#SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/:9000"
</FilesMatch>
DocumentRoot "/var/www/default/htdocs"
<Directory "/var/www/default/htdocs">
DirectoryIndex index.php index.html
AllowOverride All
Options All
RewriteEngine on
RewriteBase /
Order allow,deny
Allow from all
# Apache 2.4
Require all granted
</Directory>
</VirtualHost>

View File

@ -0,0 +1,69 @@
##
## Default Mass Virtual Host
##
<VirtualHost *:80>
# Get the server name from the Host: header
UseCanonicalName Off
ServerName localhost
ServerAlias *.loc
ServerAdmin root@localhost
# splitlogs.php is a custom script, which will filter the domain
# and create separate logfiles per domain.
LogFormat "%V;%h;%l;%u;%t;\"%r\";%>s;%b;\"%{Referer}i\";\"%{User-agent}i\"" vcommon
CustomLog "|/opt/bin/splitlogs.php" vcommon
ErrorLog /var/log/apache-2.4/other-error.log
DirectoryIndex index.php index.html
# When using VirtualDocumentRoot the PHP Env var DOCUMENT_ROOT
# is not filled, so we need to do that manually with a custom script.
VirtualDocumentRoot /shared/httpd/%-2+/htdocs/
php_admin_value auto_prepend_file /opt/bin/fix-virtual-docroot.php
#<FilesMatch "\.php$">
# Require all granted
# SetHandler proxy:fcgi://172.16.238.11:9000
#</FilesMatch>
# enablereuse
# Defining a worker will improve performance
# And in this case, re-use the worker (dependent on support from the fcgi application)
# If you have enough idle workers, this would only improve the performance marginally
#
# enablereuse requires Apache 2.4.11 or later
#<Proxy "fcgi://172.16.238.11:9000/" enablereuse=on max=10></Proxy>
<FilesMatch "\.php$">
Require all granted
# Pick one of the following approaches
# Use the standard TCP socket
SetHandler "proxy:fcgi://172.16.238.11:9000"
# If your version of httpd is 2.4.9 or newer (or has the back-ported feature), you can use the unix domain socket
#SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/:9000"
</FilesMatch>
<Directory "/shared/httpd/*/htdocs/">
DirectoryIndex index.php index.html
AllowOverride All
Options All
RewriteEngine on
RewriteBase /
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>

31
www/config.php Normal file
View File

@ -0,0 +1,31 @@
<?PHP
$MY_DIR = dirname(__FILE__);
// Translate Docker environmental variables to $ENV
$ENV = array();
exec('env', $output);
foreach ($output as $var) {
$tmp = explode('=', $var);
$ENV[$tmp[0]] = $tmp[1];
}
// HTTPD Docker
$HTTPD_HOST_NAME = 'httpd';
$HTTPD_HOST_ADDR = gethostbyname($HTTPD_HOST_NAME);
// PHP Docker
$PHP_HOST_NAME = 'php';
$PHP_HOST_ADDR = gethostbyname($PHP_HOST_NAME);
// MySQL Docker
$MYSQL_HOST_NAME = 'db';
$MYSQL_HOST_ADDR = gethostbyname($MYSQL_HOST_NAME);
$MYSQL_ROOT_PASS = $ENV['MYSQL_ROOT_PASSWORD'];
require $MY_DIR . DIRECTORY_SEPARATOR . 'include' . DIRECTORY_SEPARATOR .'functions.php';

View File

@ -0,0 +1,388 @@
/**
* Most CSS is taken from Twitter Bootstrap...
* License info taken from Bootstrap:
* // Copyright 2014-2015 Twitter, Inc.
* // Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/********************************************************************************
* Element Defaults
********************************************************************************/
html, body {
-webkit-tap-highlight-color: rgba(0,0,0,0);
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
background-color: #fff;
margin: 0;
box-sizing: border-box;
tab-size: 4;
}
h1, h2, h3 {
margin-top: 20px;
margin-bottom: 10px;
}
h1, h2, h3, h4, h5, h6 {
font-family: inherit;
font-weight: 500;
line-height: 1.1;
color: inherit;
}
h1 {
margin: .67em 0;
font-size: 2em;
}
h3 {
font-size: 24px;
}
ol, ul {
margin-top: 0;
margin-bottom: 10px;
}
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}
button, input, select, textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button, html input[type=button], input[type=reset], input[type=submit] {
-webkit-appearance: button;
cursor: pointer;
}
button, select {
text-transform: none;
}
button {
overflow: visible;
}
button, input, optgroup, select, textarea {
margin: 0;
font: inherit;
color: inherit;
}
a {
color: #337ab7;
text-decoration: none;
background-color: transparent;
}
table {
background-color: transparent;
border-spacing: 0;
border-collapse: collapse;
}
th {
text-align: left;
}
td, th {
padding: 0;
}
pre {
display: block;
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
overflow: auto;
}
code, kbd, pre, samp {
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
font-size: 1em;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/********************************************************************************
* Custom
********************************************************************************/
/* navbar */
.navbar-inverse {
background-color: #222;
border-color: #080808;
}
.navbar-static-top {
z-index: 1000;
border-width: 0 0 1px;
}
.navbar {
position: relative;
min-height: 50px;
margin-bottom: 20px;
border: 1px solid transparent;
}
.navbar-nav {
margin: 7.5px -15px;
}
.nav {
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
/* navbar header */
.container-fluid>.navbar-collapse, .container-fluid>.navbar-header, .container>.navbar-collapse, .container>.navbar-header {
margin-right: -15px;
margin-left: -15px;
}
/* navbar toggle */
.navbar-inverse .navbar-toggle {
border-color: #333;
}
.navbar-inverse .navbar-toggle .icon-bar {
background-color: #fff;
}
.navbar-toggle .icon-bar+.icon-bar {
margin-top: 4px;
}
.navbar-toggle .icon-bar {
display: block;
width: 22px;
height: 2px;
border-radius: 1px;
}
.navbar-toggle {
position: relative;
float: right;
padding: 9px 10px;
margin-top: 8px;
margin-right: 15px;
margin-bottom: 8px;
background-color: transparent;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
border-color: #101010;
}
.navbar-collapse {
padding-right: 15px;
padding-left: 15px;
overflow-x: visible;
-webkit-overflow-scrolling: touch;
border-top: 1px solid transparent;
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
}
.collapse {
display: none;
}
/* navbar brand */
span.navbar-brand {
background-color: transparent !important;
cursor:default;
}
.navbar-brand {
float: left;
height: 50px;
padding: 15px 15px;
font-size: 18px;
line-height: 20px;
color: #337ab7;
}
/* misc */
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
/* li */
.nav>li {
position: relative;
display: block;
}
.navbar-inverse .navbar-nav>li>a {
background-color: transparent !important;
}
.navbar-inverse .navbar-nav>li>a {
color: #9d9d9d;
}
.navbar-inverse .navbar-nav>.active>a, .navbar-inverse .navbar-nav>.active>a:focus, .navbar-inverse .navbar-nav>.active>a:hover {
color: #fff;
background-color: #080808;
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
line-height: 20px;
}
.nav>li>a {
position: relative;
display: block;
padding: 10px 15px;
}
/* container, row, column */
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.row {
margin-right: -15px;
margin-left: -15px;
}
.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
/* table */
.table {
width: 100%;
max-width: 100%;
margin-bottom: 20px;
}
.table-striped>tbody>tr:nth-of-type(odd) {
background-color: #f9f9f9;
}
.table>caption+thead>tr:first-child>td, .table>caption+thead>tr:first-child>th, .table>colgroup+thead>tr:first-child>td, .table>colgroup+thead>tr:first-child>th, .table>thead:first-child>tr:first-child>td, .table>thead:first-child>tr:first-child>th {
border-top: 0;
}
.table>thead>tr>th {
vertical-align: bottom;
border-bottom: 2px solid #ddd;
}
.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
/********************************************************************************
* Media queries
********************************************************************************/
@media (min-width: 768px) {
.navbar-static-top {
border-radius: 0;
}
.navbar {
border-radius: 4px;
}
.container {
width: 750px;
}
.container-fluid>.navbar-collapse, .container-fluid>.navbar-header, .container>.navbar-collapse, .container>.navbar-header {
margin-right: 0;
margin-left: 0;
}
.navbar-header {
float: left;
}
.navbar-toggle {
display: none;
}
.container-fluid>.navbar-collapse, .container-fluid>.navbar-header, .container>.navbar-collapse, .container>.navbar-header {
margin-right: 0;
margin-left: 0;
}
.navbar-fixed-bottom .navbar-collapse, .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse {
padding-right: 0;
padding-left: 0;
}
.navbar-collapse.collapse {
display: block!important;
height: auto!important;
padding-bottom: 0;
overflow: visible!important;
}
.navbar-collapse {
width: auto;
border-top: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.navbar-nav {
float: left;
margin: 0;
}
.navbar-nav>li {
float: left;
}
.navbar-nav>li>a {
padding-top: 15px;
padding-bottom: 15px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
.col-md-12 {
width: 100%;
}
.col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9 {
float: left;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
/* Overwrites for PHPinfo(); */
a.navbar-brand {
background-color: transparent !important;
}
.navbar-inverse .navbar-nav>li>a {
background-color: transparent !important;
}

73
www/htdocs/databases.php Normal file
View File

@ -0,0 +1,73 @@
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<link href="/assets/css/custom.css" rel="stylesheet">
<title>DevilBox</title>
</head>
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand" href="#">DevilBox</span>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
<li><a href="/vhosts.php">Virtual Hosts</a></li>
<li class="active"><a href="#">Databases</a></li>
<li><a href="/php.php">PHP</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<h1>Databases</h1>
<br/>
<br/>
<div class="row">
<div class="col-md-12">
<?php
$databases = getDatabases();
?>
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Size</th>
</th>
</thead>
<tbody>
<?php foreach ($databases as $name => $size): ?>
<tr>
<td><?php echo $name;?></td>
<td><?php echo round($size, 1);?> MB</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div><!-- /.container -->
</body>
</html>

218
www/htdocs/index.php Normal file
View File

@ -0,0 +1,218 @@
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<link href="/assets/css/custom.css" rel="stylesheet">
<title>DevilBox</title>
</head>
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand" href="#">DevilBox</span>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="/vhosts.php">Virtual Hosts</a></li>
<li><a href="/databases.php">Databases</a></li>
<li><a href="/php.php">PHP</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<h1>DevilBox Overview</h1>
<br/>
<br/>
<div class="row">
<div class="col-md-12">
<table class="table table-striped">
<tbody>
<tr></tr>
<!--
Docker Images
-->
<tr>
<th colspan="2"><h3>Docker Images</h3></th>
</tr>
<tr>
<th>Webserver</th>
<td><?php echo getHttpVersion();?>&nbsp;&nbsp;&nbsp;(IP: <?php echo $HTTPD_HOST_ADDR;?>)</td>
</tr>
<tr>
<th>PHP</th>
<td><?php echo getPHPVersion(); ?>&nbsp;&nbsp;&nbsp;(IP: <?php echo $PHP_HOST_ADDR;?>)</td>
</tr>
<tr>
<th>MySQL Server</th>
<td><?php echo getMySQLVersion();?>&nbsp;&nbsp;&nbsp;(IP: <?php echo $MYSQL_HOST_ADDR;?>)</td>
</tr>
<!--
Docker Host (your computer)
-->
<tr>
<th colspan="2"><h3>Host computer</h3></th>
</tr>
<tr>
<th>MySQL datadir</th>
<td><?php echo $ENV['HOST_PATH_TO_MYSQL_DATADIR'];?></td>
</tr>
<tr>
<th>MySQL socket</th>
<td>./run/mysql/mysql.sock</td>
</tr>
<tr>
<th>WWW Document Roots</th>
<td><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?></td>
</tr>
<tr>
<th>Log dir</th>
<td>./log</td>
</tr>
<tr></tr>
<!-- ############################################################ -->
<!-- HTTPD Docker -->
<!-- ############################################################ -->
<tr>
<th colspan="2"><h3>[docker] HTTPD</h3></th>
</tr>
<tr>
<td colspan="2">--</td>
</tr>
<!-- ############################################################ -->
<!-- PHP Docker -->
<!-- ############################################################ -->
<tr>
<th colspan="2"><h3>[docker] PHP</h3></th>
</tr>
<tr>
<th>MySQL Remote Port forwarded to PHP Docker?</th>
<td><?php echo ($ENV['FORWARD_MYSQL_PORT_TO_LOCALHOST']) ? 'To: 127.0.0.1:'.$ENV['MYSQL_LOCAL_PORT'] : 'No'; ?></td>
</tr>
<tr>
<th>MySQL Remote Socket mounted on PHP Docker?</th>
<td>
<?php
if ($ENV['MOUNT_MYSQL_SOCKET_TO_LOCALDISK']) {
if (file_exists($ENV['MYSQL_SOCKET_PATH'])) {
echo 'To: '.$ENV['MYSQL_SOCKET_PATH'];
} else {
echo 'To: '.$ENV['MYSQL_SOCKET_PATH']. ' - [ERROR] no such file';
}
} else {
echo 'No';
}
?>
</td>
</tr>
<tr>
<th>PHP-MySQL connection test: localhost</th>
<td><?php echo testMySQLLocalhost(); ?></td>
</tr>
<tr>
<th>PHP-MySQL connection test: 127.0.0.1</th>
<td><?php echo testMySQLLocalIp(); ?></td>
</tr>
<tr>
<th>PHP-MySQL connection test: <?php echo $MYSQL_HOST_ADDR;?></th>
<td><?php echo testMySQLRemotelIp(); ?></td>
</tr>
<tr>
<th>PHP custom run-time options</th>
<td>
<pre>
<?php /* TODO: compare with ini_get() */?>
<?php if ($ENV['PHP_XDEBUG_ENABLE'] == 1): ?>
xdebug.remote_enable = <?php echo $ENV['PHP_XDEBUG_ENABLE']."\n";?>
xdebug.remote_port = <?php echo $ENV['PHP_XDEBUG_REMOTE_PORT']."\n";?>
xdebug.remote_host = <?php echo $ENV['PHP_XDEBUG_REMOTE_HOST']."\n";?>
<?php endif; ?>
max_execution_time = <?php echo $ENV['PHP_MAX_EXECUTION_TIME']."\n";?>
max_input_time = <?php echo $ENV['PHP_MAX_INPUT_TIME']."\n";?>
memory_limit = <?php echo $ENV['PHP_MEMORY_LIMIT']."\n";?>
post_max_size = <?php echo $ENV['PHP_POST_MAX_SIZE']."\n";?>
upload_max_filesize = <?php echo $ENV['PHP_UPLOAD_MAX_FILESIZE']."\n";?>
max_input_vars = <?php echo $ENV['PHP_MAX_INPUT_VARS']."\n";?>
error_reporting = <?php echo $ENV['PHP_ERROR_REPORTING']."\n";?>
display_errors = <?php echo $ENV['PHP_DISPLAY_ERRORS']."\n";?>
track_errors = <?php echo $ENV['PHP_TRACK_ERRORS'];?>
</pre>
</td>
</tr>
<tr></tr>
<!-- ############################################################ -->
<!-- MySQL Docker -->
<!-- ############################################################ -->
<tr>
<th colspan="2"><h3>[docker] MySQL</h3></th>
</tr>
<tr>
<th>MySQL root password</th>
<td><?php echo $MYSQL_ROOT_PASS; ?></td>
</tr>
<tr>
<th>MySQL socket</th>
<td><?php echo getMySQLConfig('socket'); ?></td>
</tr>
<tr>
<th>MySQL custom run-time options</th>
<td>
<pre>
general_log = <?php echo getMySQLConfig('general-log')."\n";?>
innodb_buffer_pool_size = <?php echo getMySQLConfig('innodb-buffer-pool-size')."\n";?>
join_buffer_size = <?php echo getMySQLConfig('join-buffer-size')."\n";?>
sort_buffer_size = <?php echo getMySQLConfig('sort-buffer-size')."\n";?>
read_rnd_buffer_size = <?php echo getMySQLConfig('read-rnd-buffer_size')."\n";?>
symbolic_links = <?php echo getMySQLConfig('symbolic-links')."\n";?>
sql_mode = <?php echo getMySQLConfig('sql-mode')."\n";?>
</pre>
</td>
</tr>
</tbody>
</table>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container -->
</body>
</html>

51
www/htdocs/php.php Normal file
View File

@ -0,0 +1,51 @@
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<link href="/assets/css/custom.css" rel="stylesheet">
<title>DevilBox</title>
</head>
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand" href="#">DevilBox</span>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
<li><a href="/vhosts.php">Virtual Hosts</a></li>
<li><a href="/databases.php">Databases</a></li>
<li class="active"><a href="#">PHP</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-12">
<?php phpinfo(); ?>
</div>
</div>
</div><!-- /.container -->
</body>
</html>

111
www/htdocs/vhosts.php Normal file
View File

@ -0,0 +1,111 @@
<?php require '../config.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<link href="/assets/css/custom.css" rel="stylesheet">
<title>DevilBox</title>
</head>
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand" href="#">DevilBox</span>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
<li class="active"><a href="#">Virtual Hosts</a></li>
<li><a href="/databases.php">Databases</a></li>
<li><a href="/php.php">PHP</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<h1>Virtual Hosts</h1>
<br/>
<br/>
<div class="row">
<div class="col-md-12">
<?php $vHosts = getVhosts(); ?>
<?php if ($vHosts): ?>
<table class="table table-striped">
<thead>
<tr>
<th>Project</th>
<th>DocumentRoot</th>
<th>Valid</th>
<th>URL</th>
</th>
</thead>
<tbody>
<?php foreach ($vHosts as $vHost): ?>
<?php
$err = array();
$ern = 0;
if (!$vHost['htdocs']) {
$err[] = 'Missing <strong>htdocs</strong> directory in: <strong>'.$ENV['HOST_PATH_TO_WWW_DOCROOTS'].'/'.$vHost['name'].'/</strong>';
$ern++;
}
if ($vHost['dns_ok']) {
if ($vHost['dns_ip'] != '127.0.0.1') {
$err[] = 'Error in <strong>/etc/hosts</strong><br/>'.
'Found:<br/>'.
'<code>'.$vHost['dns_ip'].' '.$vHost['domain'].'</code><br/>'.
'But it should be:<br/>'.
'<code>127.0.0.1 '.$vHost['domain'].'</code><br/>';
$ern++;
}
} else {
$err[] = 'Missing entry in <strong>/etc/hosts</strong>:<br/><code>127.0.0.1 '.$vHost['domain'].'</code>';
$ern++;
}
?>
<tr>
<td><?php echo $vHost['name'];?></td>
<td><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?>/<?php echo $vHost['name'];?>/htdocs</td>
<?php if ($ern): ?>
<td colspan="2">
<?php echo implode('<br/>', $err); ?>
</td>
<?php else: ?>
<td>OK</td>
<td><a target="_blank" href="<?php echo $vHost['href'];?>"><?php echo $vHost['domain'];?></a></td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<h4>No projects here.</h4>
<p>Simply create a folder in <strong><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?></strong> (on your host computer - not inside the docker).</p>
<p><strong>Example:</strong><br/><?php echo $ENV['HOST_PATH_TO_WWW_DOCROOTS'];?>/my_project</p>
<?php endif;?>
</div>
</div>
</div><!-- /.container -->
</body>
</html>

189
www/include/functions.php Normal file
View File

@ -0,0 +1,189 @@
<?php
function my_exec($cmd, &$output = '')
{
// Clean output
$output = '';
exec($cmd, $output, $exit_code);
return $exit_code;
}
/********************************************************************************
*
* G E T D A T A
*
********************************************************************************/
/**
* Get all MySQL Databases.
* @return mixed Array of name => size
*/
function getDatabases() {
global $MYSQL_HOST_ADDR;
global $MYSQL_ROOT_PASS;
$conn = mysqli_connect($MYSQL_HOST_ADDR, 'root', $MYSQL_ROOT_PASS);
$sql = 'SELECT
table_schema AS db_name,
SUM( data_length + index_length ) / 1024 / 1024 "MB"
FROM
information_schema.TABLES
WHERE
table_schema != "mysql" AND
table_schema != "performance_schema" AND
table_schema != "information_schema"
GROUP BY
table_schema
ORDER BY db_name;';
$result = mysqli_query($conn, $sql);
$data = array();
while ($row = $result->fetch_array(MYSQLI_NUM)) {
// name => size
$data[$row[0]] = $row[1];
}
mysqli_close($conn);
return $data;
}
function is_valid_dir($path) {
return (is_dir($path) || (is_link($path) && is_dir(readlink($path))));
}
/**
* Get all VirtualHosts
* @return [type] [description]
*/
function getVhosts() {
global $ENV;
$docRoot = '/shared/httpd';
$vhosts = array();
if ($handle = opendir($docRoot)) {
while (false !== ($directory = readdir($handle))) {
if (is_valid_dir($docRoot . DIRECTORY_SEPARATOR . $directory) && $directory != '.' && $directory != '..') {
$output;
$domain = $directory.'.loc';
$url = 'http://'.$domain;
$htdocs_ok = is_valid_dir($docRoot.DIRECTORY_SEPARATOR.$directory.DIRECTORY_SEPARATOR.'htdocs');
$dns_ok = my_exec('getent hosts '.$domain, $output) == 0 ? TRUE : FALSE;
$dns_ip = '';
if (isset($output[0])) {
$tmp = explode(' ', $output[0]);
if (isset($tmp[0])) {
$dns_ip = $tmp[0];
}
}
$vhosts[] = array(
'name' => $directory,
'htdocs' => $htdocs_ok,
'dns_ok' => $dns_ok,
'dns_ip' => $dns_ip,
'domain' => $directory.'.loc',
'href' => 'http://' . $directory.'.loc'
);
}
}
}
return $vhosts;
}
/********************************************************************************
*
* G E T V E R S I O N
*
********************************************************************************/
/**
* Get HTTPD Version
* @return [type] [description]
*/
function getHttpVersion() {
preg_match('/\w+\/[.0-9]+/i', $_SERVER['SERVER_SOFTWARE'], $matches);
if (isset($matches[0])) {
return $matches[0];
} else {
return 'Unknown Webserver';
}
}
/**
* Get MySQL Version
* @return [type] [description]
*/
function getMySQLVersion() {
return getMySQLConfig('version_comment') . ' ' . getMySQLConfig('version');
}
function getPHPVersion() {
return 'PHP ' . phpversion() .' (' . php_sapi_name().')';
}
function getMySQLConfig($key) {
global $MYSQL_HOST_ADDR;
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect($MYSQL_HOST_ADDR, 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
$key = str_replace('-', '_', $key);
$query = 'SHOW VARIABLES WHERE Variable_Name = "'.$key.'";';
$result = mysqli_query($link, $query);
$data = mysqli_fetch_array($result);
if (isset($data[1])) {
return $data[1];
}
return FALSE;
}
/********************************************************************************
*
* T E S T M Y S Q L C O N N E C T I O N
*
********************************************************************************/
function testMySQLLocalhost() {
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect('localhost', 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
return 'OK: Connection via localhost socket';
}
function testMySQLLocalIp() {
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect('127.0.0.1', 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
return 'OK: Connection via 127.0.0.1';
}
function testMySQLRemotelIp() {
global $MYSQL_HOST_ADDR;
global $MYSQL_ROOT_PASS;
$link = @mysqli_connect($MYSQL_HOST_ADDR, 'root', $MYSQL_ROOT_PASS);
if (!$link) {
return 'Cannot conncet to MySQL Database: '.mysqli_connect_error();
}
return 'OK: Connection via '.$MYSQL_HOST_ADDR;
}