diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100755 index 0000000..191381e --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1 @@ +.git \ No newline at end of file diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 0000000..74e4471 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +docker_settings.sh diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100755 index 0000000..33727f4 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,103 @@ +# Due to layout of this project, the dockerfile will be moved up two directories and run during +# the build. Thus when performing any ADD commands, remember that this is "where you are" +# The layout is this way so that the settings file sits one level above the project (trunk) so that +# each dev can have their own settings and they do not get merged into the trunk. + +FROM debian:jessie + +RUN apt-get update +RUN apt-get dist-upgrade -y + + +# Install the relevant packages +RUN apt-get install vim apache2 libapache2-mod-php5 php5-cli php5-mysqlnd curl php5-curl php5-mcrypt -y + + +# Install yui-compressor for js (and possibly css) minification later. +RUN apt-get install yui-compressor -y + +# Install supervisor (through PIP) +RUN apt-get install python-pip python-dev build-essential -y +RUN pip install --upgrade pip +RUN pip install supervisor + +# Enable the php mod we just installed +RUN a2enmod php5 + + +# expose port 80 and 443 for the web requests +EXPOSE 80 + + +###### Update the php INI settings ######### + +# Increase php's max allowed memory size if you need to +#RUN sed -i 's;memory_limit = .*;memory_limit = -1;' /etc/php5/apache2/php.ini +#RUN sed -i 's;memory_limit = .*;memory_limit = -1;' /etc/php5/cli/php.ini + +RUN sed -i 's;display_errors = .*;display_errors = Off;' /etc/php5/apache2/php.ini +RUN sed -i 's;display_errors = .*;display_errors = On;' /etc/php5/cli/php.ini + +# Change apache php to allow larger uploads/POSTs +RUN sed -i 's;post_max_size = .*;post_max_size = 4000M;' /etc/php5/apache2/php.ini +RUN sed -i 's;upload_max_filesize = .*;upload_max_filesize = 2000M;' /etc/php5/apache2/php.ini + +# Set the max execution time if you want to +#RUN sed -i 's;max_execution_time = .*;max_execution_time = 300;' /etc/php5/apache2/php.ini +#RUN sed -i 's;max_execution_time = .*;max_execution_time = 300;' /etc/php5/cli/php.ini + +# This is also needed for execution time +#RUN sed -i 's;max_input_time = .*;max_input_time = 300;' /etc/php5/apache2/php.ini + + +####### END of updating php INI ######## +######################################## + +# Manually set the apache environment variables in order to get apache to work immediately. +ENV APACHE_RUN_USER www-data +ENV APACHE_RUN_GROUP www-data +ENV APACHE_LOG_DIR /var/log/apache2 + +# It appears that the new apache requires these env vars as well +ENV APACHE_LOCK_DIR /var/lock/apache2 +ENV APACHE_PID_FILE /var/run/apache2/apache2.pid + +# Set up url rewrite ability +RUN a2enmod rewrite +RUN php5enmod mcrypt + +# Install the cron service +RUN apt-get install cron -y + + + +# Add our websites files to the default apache directory (/var/www) +COPY Lychee /var/www/lychee + +# Update our apache sites available with the config we created +RUN cp /var/www/lychee/docker/apache-config.conf /etc/apache2/sites-enabled/000-default.conf + +# Add our supervisor config to the container +RUN cp /var/www/lychee/docker/supervisord.conf /etc/supervisord.conf + + +# Use the crontab file. +# The crontab file was already added when we added "project" +RUN crontab /var/www/lychee/docker/crons.conf + +# Set the base permissions for the site. +RUN chown root:www-data -R /var/www +RUN chmod 750 -R /var/www/lychee + +# Set up the uploads and data directories to be volumes that are writeable. +RUN chmod 770 -R /var/www/lychee/uploads/ +RUN chmod 770 -R /var/www/lychee/data/ + +RUN ln -s /var/www/lychee/uploads uploads +RUN ln -s /var/www/lychee/data data +VOLUME /uploads +VOLUME /data + +# Execute the containers startup script which will start many processes/services +# The startup file was already added when we added "project" +CMD ["/bin/bash", "/var/www/lychee/docker/startup.sh"] diff --git a/docker/README.md b/docker/README.md new file mode 100755 index 0000000..a46567e --- /dev/null +++ b/docker/README.md @@ -0,0 +1,6 @@ +This area is for building and deploying Lychee through docker. + +## Steps +* Copy the docker_settings.sh.tmpl file to docker_settings.sh and fill in the settings appropriately +* Run the command `bash build.sh` +* Deploy your container with bash deploy.sh \ No newline at end of file diff --git a/docker/apache-config.conf b/docker/apache-config.conf new file mode 100755 index 0000000..743abd9 --- /dev/null +++ b/docker/apache-config.conf @@ -0,0 +1,25 @@ +# This is the apache config as it will appear for the deployed container. Bear in mind that this +# does not overwrite anything on the host that the container is deployed to so everything is "safe" +# +# This will need to match up with how files are added to the container from the Dockerfile + + ServerAdmin webmaster@localhost + + DocumentRoot /var/www/lychee + + Options Indexes FollowSymLinks + AllowOverride All + Order allow,deny + allow from all + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/error.log + + # Possible values include: debug, info, notice, warn, error, crit, + # alert, emerg. + LogLevel warn + + CustomLog ${APACHE_LOG_DIR}/access.log combined + + diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 0000000..98ff92a --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# ensure running bash +if ! [ -n "$BASH_VERSION" ];then + echo "this is not bash, calling self with bash...."; + SCRIPT=$(readlink -f "$0") + /bin/bash $SCRIPT + exit; +fi + +# Get the path to script just in case executed from elsewhere. +SCRIPT=$(readlink -f "$0") +SCRIPTPATH=$(dirname "$SCRIPT") +cd $SCRIPTPATH + +# Load the variables from settings file. +source docker_settings.sh + +# Copy the docker file up and run it in order to build the container. +# We need to move the dockerfile up so that it can easily add everything to the container. +cp -f Dockerfile ../../. +cp -f .dockerignore ../../. +cd ../../. + +# Ask the user if they want to use the docker cache +read -p "Do you want to use a cached build (y/n)? " -n 1 -r +echo "" # (optional) move to a new line +if [[ $REPLY =~ ^[Yy]$ ]] +then + docker build --pull --tag $REGISTRY/$PROJECT_NAME . +else + docker build --no-cache --pull --tag $REGISTRY/$PROJECT_NAME . +fi + +# Remove the duplicated Dockerfile after the build. +rm $SCRIPTPATH/../../Dockerfile +rm $SCRIPTPATH/../../.dockerignore + +docker push $REGISTRY/$PROJECT_NAME + +echo "Run the container with the following command:" +echo "bash deploy.sh" diff --git a/docker/crons.conf b/docker/crons.conf new file mode 100755 index 0000000..e247561 --- /dev/null +++ b/docker/crons.conf @@ -0,0 +1,6 @@ +# This will become the crontab file. Place any crons that need performing in here. +# This needs to "link up" with how files are added to the conainer from the dockerfile. + +# Add any crons below. +# * * * * * /usr/bin/php /var/www/lychee/path/to/script + diff --git a/docker/deploy.sh b/docker/deploy.sh new file mode 100755 index 0000000..dfadc04 --- /dev/null +++ b/docker/deploy.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# ensure running bash +if ! [ -n "$BASH_VERSION" ];then + echo "this is not bash, calling self with bash...."; + SCRIPT=$(readlink -f "$0") + /bin/bash $SCRIPT + exit; +fi + +SCRIPT=$(readlink -f "$0") +SCRIPTPATH=$(dirname "$SCRIPT") +cd $SCRIPTPATH + +# load the variables +source $SCRIPTPATH/docker_settings.sh + +CONTAINER_IMAGE="`echo $REGISTRY`/`echo $PROJECT_NAME`" + +echo $PROJECT_NAME +echo "============" + +docker kill $PROJECT_NAME +docker rm $PROJECT_NAME + +# Create the volumes if they dont exist already. +mkdir -p $VOLUME_DIR/uploads +mkdir -p $VOLUME_DIR/data + +docker run -d \ +-p 80:80 \ +-e MYSQL_HOST="$MYSQL_HOST" \ +-e MYSQL_DB_NAME="$MYSQL_DB_NAME" \ +-e MYSQL_USER="$MYSQL_USER" \ +-e MYSQL_PASSWORD="$MYSQL_PASSWORD" \ +-e MYSQL_PORT="$MYSQL_PORT" \ +-v $VOLUME_DIR/uploads:/uploads \ +-v $VOLUME_DIR/data:/data \ +--restart=always \ +--name="$PROJECT_NAME" \ +$CONTAINER_IMAGE diff --git a/docker/docker_settings.sh.tmpl b/docker/docker_settings.sh.tmpl new file mode 100644 index 0000000..1cdeeda --- /dev/null +++ b/docker/docker_settings.sh.tmpl @@ -0,0 +1,22 @@ +# If you want to have the image pushed to your private registry, put it here. +#REGISTRY="docker-registry.mydomain.org:5000" + +# If you want to hav the image be pushed to your public dockerhub, just use your username instead +#REGISTRY="myUsername" + +# If you don't uncomment one of the REGISTRY options above, then the image just won't get pushed. + +# Set the name for this in your registry. You probably want to leave this as lychee +PROJECT_NAME="lychee" + + +# Specify where you want your volume data. +VOLUME_DIR="$HOME/lychee-volume" + + +# Specify the database details. +MYSQL_HOST="lychee.mydomain.com" +MYSQL_DB_NAME="lychee" +MYSQL_USER="lychee" +MYSQL_PASSWORD="myPassword" +MYSQL_PORT=3306 \ No newline at end of file diff --git a/docker/startup.sh b/docker/startup.sh new file mode 100755 index 0000000..7c28cb2 --- /dev/null +++ b/docker/startup.sh @@ -0,0 +1,16 @@ +# Please do not manually call this file! + +# Have supervisor manage the apache process instead +service apache2 stop + +# Make sure I have permissions to the volumes +chown root:www-data -R /var/www/lychee/data +chown root:www-data -R /var/www/lychee/uploads +chmod 770 /var/www/lychee/uploads +chmod 770 /var/www/lychee/data + +# Here is a good point to run database migrations (before the webserver is started up by supervisord) +#/usr/bin/php /var/www/lychee/scripts/migrate.php + +# Start supervisord to manage all processes and tye up the FG process for the docker container. +/usr/local/bin/supervisord \ No newline at end of file diff --git a/docker/supervisord.conf b/docker/supervisord.conf new file mode 100755 index 0000000..6ddd6e3 --- /dev/null +++ b/docker/supervisord.conf @@ -0,0 +1,11 @@ +[supervisord] +nodaemon=true + +[program:apache2] +command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND" +autorestart=true + +# Add your own scripts to be executed by supervisor by uncommenting and editing the following lines. +#[program:MyScriptOfAwesomeness] +#command=/usr/bin/php /var/www/lychee/project/scripts/MyScriptOfAwesomeness.php +#autorestart=true \ No newline at end of file diff --git a/php/Modules/Database.php b/php/Modules/Database.php index 11924b5..23243a5 100755 --- a/php/Modules/Database.php +++ b/php/Modules/Database.php @@ -80,10 +80,16 @@ final class Database { * @return object|false Returns the connection when successful. */ public static function connect($host = 'localhost', $user, $password) { - - // Open a new connection to the MySQL server - $connection = @new Mysqli($host, $user, $password); - + + // Load the database settings from the environment variables passed to the docker container + $host = getenv('MYSQL_HOST'); + $dbname = getenv('MYSQL_DB_NAME'); + $user = getenv('MYSQL_USER'); + $password = getenv('MYSQL_PASSWORD'); + $port = getenv('MYSQL_PORT'); + + $connection = @new \mysqli($host, $user, $password, $dbname, $port); + // Check if the connection was successful if ($connection->connect_errno) return false; @@ -125,7 +131,10 @@ final class Database { * @return boolean Returns true when successful. */ public static function createDatabase($connection, $name = 'lychee') { - + + // Override whatever the user fills in with whatever is in the settings file. + $name = getenv('MYSQL_DB_NAME'); + // Check dependencies Validator::required(isset($connection), __METHOD__);