CentOS 6.6 based Customizable Laravel 5 Container - 939 MB - Updated 5/29/2015
Appcontainers Laravel 5 Framework Container Build
This container is built from appcontainers/centos66, a slightly modified bare bones CentOS 6.6 Minimal Installation. Modifications to the minimal installation of CentOS 6.6 that were configured in the centos66 image can be found by looking at the appcontainers/centos66 repository located below:
[appcontainers/centos66 on the Docker Hub] (https://registry.hub.docker.com/u/appcontainers/centos66/) \
[appcontainers/centos66 on the Quay Registry] (https://quay.io/repository/appcontainers/centos66)
This containers purpose is to get a customizable laravel instance up and running with a single docker run statement. The container is built with environment variables that allow the user to plug in custom values which will allow the container to configure itself on first run. This will give the user a fully customized experience just as if you set up laravel on your own from scratch.
The container is built to allow several configurable variables to be passed in at runtime. The values are as follows:
- APP_NAME - This is the fully qualified domain name such as example.com. This should be passed without any prefix such as www.
- APACHE_SVRALIAS - This is exactly what it sounds like, the apache file ServerAlias Directive data.
- MYSQL_SERVER - This is the Host server that runs the MySQL instance where the Application DB will be stored.
- MYSQL_CLIENT - This is the hostname or the IP address of the computer making the connection to the database.
- MYSQL_USER - This is the mysql user that will be used to connect to the mysql instance, and create the database. User must have grant option.
- MYSQL_PASS - This will set the MySQL Root Password.
- MYSQL_DB - The name of the MySQL DB that the Application will use.
- APP_USER - The username that the Application will use in order to connect to the MySQL DB.
- APP_PASS - The password of the user that the Application uses to connect to the MySQL DB.
- MODE - A toggle to tell the container to install mysql locally, connect to an external server and install a new DB on the remote server, connect to an existing database on an existing remote server, or just run as a persistent data volume with no services.
- ENV - Variable to hold the enviroment, currently it serves no other purpose but is there in case its needed
- TERMTAG - Environment variable to hold the highlighted bash shell tag. Currently set to the repo name, but can be change from within the container via TERMTAG="Whatever You Want"
- SMB_ENABLE - Toggle whether Samba is installed or not. Default value is set to False, as in not installed. Setting this value to True would install and configure Samba Automatically.
- SMB_USER - The user that will be configured to allow samba connections
- SMB_PASS - The password that the samba user will use to connect to the samba share. (/var/www/html)
NOTE: If you have connected the server to a data volume that already contains a laravel instance, and a pre-generated certificate, then when a new laravel container is fired off using those volumes, it detects those existing files, and will NOT perform any reconfiguration on either the existing laravel instance, nor create a new SSL cert. It will use the existing ones in place. This is assuming that the laravel install folder, and certificate are named the same as the APP_NAME variable passed.
- Standalone - Start a local mysql instance, and install a new database on the localhost mysql instance.
- Remote - Connect to an exsiting remote database server and install a new database on the remote mysql instance.
- Existing - Connect to an existing remote database on an existing remote mysql instance.
- DataVol - This mode will uninstall the mysql, mysql-server, mod_rewrite, mod_ssl, mod_env, php php-common, php-cli, php-mysql and httpd packages. This mode is intended to be used solely as a data volume, allowing another instance to connect to the installed directory structure of the application for persistent storage.
Note: If "Remote" or "Existing" is selected, then before running the container the user must know a mysql superuser username/password, or connect to the database and ensure that the APP_USER and APP_PASS that will be used in the run statement, already have permission to either create a new database and publish a new grant (remote), or read the MYSQL_DB (existing).
Note: Keeping the default mode of "standalone" will start the local MySQL instance, and set it to run on start, setting the mode to either "remote" or "existing" will not start the local instance of mysql, and will not set it to start at runtime, however the package will be installed. If you want to uninstall it after the container is ran, you can attach to the container and issue a yum erase mysql-server command to uninstall the mysql server rpms.
Running the Container:
###Running the container with default values###
docker run -d -it --name laravel -h laravel -p 80:80 -p 443:443 appcontainers/laravel
This will assume the following
- ENV = dev
- TERMTAG = laravel
- MODE = standalone
- APP_NAME = laravel.local
- APACHE_SVRALIAS = www.laravel.local localhost
- MYSQL_SERVER = localhost
- MYSQL_CLIENT = localhost
- MYSQL_USER = root
- MYSQL_PASS = PAssw0rd
- MYSQL_DB = laravel
- APP_USER = admin
- APP_PASS = PAssw0rd
- SMB_ENABLE = False
- SMB_USER = samba
- SMB_PASS = password
Setting any of the above values will tell the container to replace the default values already set within the container with the values that are supplied at runtime. For example, if you pass in -e APP_NAME=mysite.com then laravel will be preconfigured for mysite.com, Apache will also be set to listen to request to mysite.com etc..Additionally SSL Self Signed certs were generated, and the site is configured to listen for both HTTP/HTTPS requests..
###Running the container substituting the $varables with your own custom values###
docker run -d -it \ --name laravel \ -h laravel \ -p 80:80 \ -p 443:443 \ -e APP_NAME='testapp.com' \ -e APACHE_SVRALIAS='www.testapp.com localhost' \ -e MYSQL_SERVER='localhost' \ -e MYSQL_PASS='PAssw0rd' \ -e MYSQL_DB='testapp' \ -e APP_USER='admin' \ -e APP_PASS='PAssw0rd' \ -e ENV=production \ -e TERMTAG=prod \ -e SMB_ENABLE=true \ -e SMB_USER=smbuser \ -e SMB_PASS=password \ appcontainers/laravel
This example will start a new container named laravel, It will set apache to testapp.com, It will leave the default database instance on the localhost and configure mysql to have a root password of "PAssw0rd", with the laravel database being named testapp. It will create a user named "admin" with a password of "PAssword" and set a grant statment on the testapp database to allow all privileges to be granted to the admin@localhost user. At this point your app is fully configured and you just need to go the default URL. Additionally a Self Signed SSL cert was generated, and the site was configured to be accessible via HTTP/HTTPS. At this point your app is fully configured and you just need to go the default URL on either HTTP/HTTPS. The container would also detect that SMB_ENABLE is set to true, so the container would install the samba4 and samba4-client packages, and configure samba to be accessable by the SMB_USER, using the SMB_PASS variables supplied. This would allow Samba connections to the working web directory of /var/www/html.
##MODE "Remote" or "remote" :##
In this example lets assume the following scenario:
The database will live on "mydbserver.mydomain.mytld".
The database will be named "testapp".
A connection to the existing database server will be made using the existing mysql user "superuser".
The "superuser" user also has an existing password set to "superpassword".
The laravel user that will be used to connect to the new database will be named "appadmin".
The laravel user "appadmin", password will be set to "flappyjacks".
Connections to the testapp database will be allowed from any host (%).
The superuser/superuserpassword users must already exist on the mysql server, and will be used to allow the container, to create a connection, and create the database for laravel. This means that the superuser, user must have the appropriate permissions with the grant option in order to effectively make the connection, create the database, the application user, the application password and he necessary grants to allow the application to interact accordingly with the database.
The above scenario correlates to the following configuration given at container runtime.
Note: The following assumes that on the mysql user a user named superuser has been created with the grant option, and has permissions on all databases or you are firing this connection off as the mysql root user, which has been configured already to allow connections from %.
If you are using a user other than root, ensure that the MySQL connecting user has all privileges including grant, so that the mysql script can create the app user and publish the grant to the newly created database for the application. An appropriate grant statement is as follows
GRANT ALL PRIVILEGES ON *.* TO 'superuser'@'%' IDENTIFIED BY 'superpassword' WITH GRANT OPTION;
###Running the container in "Remote" Mode :###
docker run -d -it \ --name mysql \ -h mysql \ -p 3306:3306 \ -e CREATEDB=false \ -e MYSQL_USER='admin' \ -e MYSQL_PASS='adminpassword123' \ -e MYSQL_CLIENT='172.17.0.%' \ -e TERMTAG=mysql \ appcontainers/mysql docker run -d -it \ --name laravel \ -h laravel \ -p 80:80 \ -p 443:443 \ --link mysql:mysql \ -e MODE='remote' \ -e APP_NAME='testapp.com' \ -e APACHE_SVRALIAS='www.testapp.com localhost' \ -e MYSQL_USER='superuser' \ -e MYSQL_PASS='superpassword' \ -e MYSQL_SERVER='mysql' \ -e MYSQL_CLIENT='%' -e MYSQL_DB='testapp' \ -e APP_USER='appadmin' \ -e APP_PASS='flappyjacks' \ -e ENV=production \ -e TERMTAG=prod \ appcontainers/laravel
As stated above, In this scenario, the container will connect to the MYSQL_SERVER (mysql), as superuser (MYSQL_USER)suppling the MYSQL_PASS of superpassword, which will grant access to the mysql server instance. A query will be made against the database instance to check to see if the database already exists.. If it exits then it will do nothing further, however if it does not exist then, the superuser mysql user, will create the testapp database, and place a "GRANT ALL PRIVILEGES" on that database to the APP_USER 'appadmin'@'%' (% signifies wild as in accept from any connecting IP, this can be substituted with an IP of the connecting host or from the connecting subnet like 172.17.0.%) and with the APP_PASS of "flappyjacks". It will then flush mysql privileges, and finally remove the "test" database if it exits. Finally the local mysql-server package will be removed from the laravel instance.
MODE "Existing" or "existing":
In the following example, the assumption is made that there is a remote database server, that already contains a pre-existing laravel database, and there is already a grant statement allowing the APP_USER/APP_PASS all privileges on the existing laravel database.
Note: If you are unsure if the APP_USER/APP_PASS credentials have the appropriate permissions on the existing laravel database, then you can connect to the existing database server and issue the following grant substituting the variables with actual values that will be used in the run statement.
GRANT ALL PRIVILEGES ON $MYSQL_DB.* TO '$APP_USER'@'%' IDENTIFIED BY '$APP_PASS';
Running the container in "Existing" Mode :
docker run -d -it \ --name laravel \ -h laravel \ -p 80:80 \ -p 443:443 \ -e MODE='existing' \ -e APP_NAME='testapp.com' \ -e APACHE_SVRALIAS='www.testapp.com localhost' \ -e MYSQL_SERVER='mydbserver.mydomain.mytld' \ -e MYSQL_DB='testdb123' \ -e APP_USER='appadmin' \ -e APP_PASS='flappyjacks' \ -e ENV=production \ -e TERMTAG=prod \ appcontainers/laravel
Note: Using the existing mode also tells the laravel instance to remove the local mysql-server package from the laravel instance.
MODE "Datavol" or "datavol":
As stated above the intention of the datavol mode is to set up a shell of the laravel directory structure that will be set as persistent storage. The idea is that the /var/www/html, and /etc/pki/tls directories will be flagged as persistent. A second actual instance container will then run connected to the persistent volume and will perform the configuration of the laravel application. This configuration will allow you to remove the laravel container to upgrade to a new one or reset it, without loosing any of your laravel data.
Note: When the laravel container initially runs, it checks for the existence of both the laravel directory and an existing certificate, and if detected, it skips both the laravel configuration steps, or certificate creation steps respectively. Each of these checks are independent of each other, meaning that if a laravel directory is detected, but no certificate is detected, then it will skip only the laravel configuration pieces, but will generate a new certificate. These checks are dependent upon the laravel folder, and certificate being named the same as APP_NAME. Example, if APP_NAME=example.com, then the check will search for /var/www/html/example.com for laravel, and then will check for /etc/pki/tls/certs/example.com.crt for the certificate. The checks are based on the initial configuration of the application via the very first original container run, which does perform both of those configurations.
Running the container in "Datavol" Mode :
docker run -d -it \ --name mysql \ -h mysql \ -p 3306:3306 \ -e CREATEDB=false \ -e MYSQL_USER='admin' \ -e MYSQL_PASS='adminpassword123' \ -e MYSQL_CLIENT='172.17.0.%' \ -e TERMTAG=mysql \ appcontainers/mysql docker run -d -it \ --name laravel_data \ -h laravel_data \ -v /var/www/html \ -v /etc/pki/tls \ -e MODE="datavol" \ -e ENV=production \ -e TERMTAG=webdata \ appcontainers/laravel docker run -d -it \ --name laravel \ -h laravel \ -p 80:80 \ -p 443:443 \ --volumes-from laravel_data \ --link mysql:mysql \ -e MODE=remote \ -e APP_NAME='testapp.com' \ -e APACHE_SVRALIAS='www.testapp.com localhost' \ -e MYSQL_SERVER='mysql' \ -e MYSQL_PASS='PAssw0rd' \ -e MYSQL_DB='testapp' \ -e APP_USER='admin' \ -e APP_PASS='PAssw0rd' \ -e ENV=production \ -e TERMTAG=prod \ appcontainers/laravel
Note: This mode removes all httpd/php/mysql packages from the datavol container. It is intended to be used a persistent storage only, and not actually run any application services.
Access the new Install :
###Navigate to the IP address of the server on the port specified (80/443 default) to run through the laravel installation wizard GUI###
###Connect to the IP address of the server on the default samba ports (138,139,445) via smb (smb://IP.ADD.TO.HOST)###
Docker Compose YML
Copy the text below and paste it into a file named docker-compose.yml. Then you can navigate to the directory and if you have docker-compose installed, just issue the following command:
docker-compose up -d
dbdata: image: appcontainers/centos66 hostname: dbdata stdin_open: true tty: true volumes: - /var/lib environment: - ENV=production - TERMTAG=DBDATA command: /bin/bash db: image: appcontainers/mysql hostname: db stdin_open: true tty: true restart: always volumes_from: - dbdata environment: - MYSQL_USER=appadmin - MYSQL_PASS=adminpassword123 - ENV=production - TERMTAG=DB command: /bin/bash webdata: image: appcontainers/laravel hostname: webdata stdin_open: true tty: true ports: - 138/udp:138/udp - 139:139 - 445:445 - 445/udp:445/udp volumes: - /var/www/html - /etc/pki/tls environment: - SMB_ENABLE=false - SMB_USER=samba - SMB_PASS=password - MODE=datavol - ENV=production - TERMTAG=WEBDATA command: /bin/bash web: image: appcontainers/laravel hostname: laravel stdin_open: true tty: true restart: always ports: - "80:80" - "443:443" links: - db volumes_from: - webdata environment: - MODE=remote - APP_NAME=testsite.com - APACHE_SVRALIAS=www.testsite.com localhost - MYSQL_SERVER=db - MYSQL_CLIENT=172.17.%.% - MYSQL_USER=appadmin - MYSQL_PASS=adminpassword123 - MYSQL_DB=laravel - APP_USER=appuser - APP_PASS=apppass - ENV=production - TERMTAG=LARAVEL command: /bin/bash
NOTE: This image is now set to generate a SSL key/cert Pair on first run. This cert is not shared with anyone else, and is also only self signed, which will allow for HTTPS connections, but will not be a valid cert. If you wish to use a valid cert, then place your own key/cert in /etc/pki/tls/private, /etc/pki/tls/certs respectivly, and change the apache configuration accordingly if the certificate name is changed from its default value.
05/29/2015 - Updated Flyway, MySQL connector, Added Modes, Added TERMTAG, Added Optional SMB.