While most people develop Laravel applications on the excellent Homestead platform, which uses Nginx for the HTTP server, I still prefer to use Apache 2 HTTP server, because it is most widely supported, especially on shared hosting. Accordingly, I frequently set up Linux hosts, such as Vagrant boxes, to run Laravel with Apache. Here are the key (and sometimes easy to overlook!) steps.
- Install PHP, Apache HTTP server, and MySQL.
- Enable
mod_rewrite
for Apache. - Install Composer globally.
- Create your Laravel project in user directory.
- Set permissions for Laravel folders.
- Set up an Apache virtual host for your Laravel project.
- Add new virtual host to
hosts
file. - Enable new virtual host and (optionally) disable the default virtual host.
- [Optional] Install Node.JS JavaScript engine, which is required for Laravel Elixir.
- [Optional] Create a MySQL (or SQLite) database to use with your Laravel project.
Let’s look at each step in detail. (Or skip to the Summary below for minimal details.)
Install PHP, Apache HTTP server, and MySQL.
To install PHP, including everything needed to support Laravel framework, on Ubuntu-based Linux system, such as Vagrant, run the following commands in the terminal/shell.
sudo apt-get update && sudo apt-get -y install software-properties-common python-software-properties sudo apt-add-repository -y ppa:ondrej/php && sudo apt-get update sudo apt-add-repository -y ppa:git-core/ppa && sudo apt-get update export DEBIAN_FRONTEND=noninteractive sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password password mysql_password' sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password mysql_password' sudo apt-get -y install mysql-server sudo apt-get -y install php5.6-bz2 php5.6-cli php5.6-curl php5.6-json php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-readline php5.6-sqlite3 php5.6-xml php5.6-xsl php5.6-zip php-xdebug apache2 libapache2-mod-php5.6 git curl
By using Ondrej Sury‘s PPA for PHP, you can install PHP 5.5, 5.6, or 7.0 (and soon 7.1!) or any combination. See this article for more details. Specifically, to install PHP 7.0 instead of 5.6, just replace each instance of php5.6
with php7.0
above.
Also, note that using debconf-set-selections
utility allows us to install MySQL without being prompted for the root password. In this case, we set the password to mysql_password
, but you probably want to use something else.
Enable mod_rewrite
for Apache.
One of the most frequently encountered difficulties when starting with Laravel on Apache HTTP server is that the mod_rewrite
extension is not enabled. Laravel requires mode_rewrite
to properly transform URLs to be interpreted by its routing function via .htaccess
. On some Ubuntu platforms, mod_rewrite
will be enabled by default, but for enhanced security, the default is now for it to be disabled. To enable
mod_rewrite
extension, run:
sudo a2enmod rewrite sudo service apache2 restart sudo apachectl -t -D DUMP_MODULES | grep rewrite
The last command (apachectl
) should return rewrite_module (shared)
. If this is not returned, then some failure occurred with the installation or configuration of mod_rewrite
extension.
Install Composer globally.
The Laravel framework (and most recent PHP packages) use the Composer package management utility. Composer allows you to quickly and easily install the PHP modules that you need without having to worry about managing all of their dependencies. Likewise, Composer will automatically keep all of your packages updated, when maintainers publish new versions.
To simplify use of Composer, we are going to install it globally, so that you can run it from most any directory in the terminal/shell. (The Laravel installation instructions have you install Composer specifically for your Laravel project, but that’s usually not necessary.) We won’t go over all of the details for install Composer, because the Composer web site has simple, yet thorough instructions. Just go to the Composer Download page and follow the instructions. The only change to make to the given instructions is that on the third step, run the installer like this:
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
Since we are installing to the /usr/local/bin
directory you must run this command as root
user by using sudo
.
The Composer installer will report the results and you should be able to verify successful installation by running composer
in terminal/shell which should give you a list of all of the Composer commands.
Create your Laravel project in user directory.
Now we are ready to create our Laravel project, which installs all of the necessary files into a new directory. For this example, we will create our project in a user directory, which simplifies managing the permissions of the files and directories. Specifically, we’ll install to projects/laravel_project
under our user’s home directory ($HOME
). Here’s how to do it:
cd $HOME mkdir projects cd projects composer create-project laravel/laravel laravel_project --prefer-dist 5.2.*
In this example, we are explicitly installing version 5.2 of Laravel framework, but you can choose any version; check this article for details. Also, we use the Composer --prefer-dist
parameter to reduce the amount of data that must be downloaded.
After a few minutes, all of the necessary files will be downloaded and installed, including all of the dependencies. Composer should finish with the messages:
Writing lock file Generating autoload files > Illuminate\Foundation\ComposerScripts::postUpdate > php artisan optimize Generating optimized class loader > php artisan key:generate Application key [base64:Q1wREnWZ5E/AmhQ8JLZr85NjiFot9IIDJ8+vTeWnNts=] set successfully.
Of course, your application key will be different. And, as shown, you can always re-generate the key by running php artisan key:generate
in your project directory.
To confirm that the installation succeeded, run:
cd laravel_project php artisan
This should give you a list of the Artisan commands. Artisan is Laravel’s powerful built-in command-line utility, which simplifies many common development tasks. Check it out!
Set permissions for Laravel folders.
Another common pitfall in configuring Laravel on Linux is setting the appropriate permissions for a couple of the directories. Laravel needs to be able to write transient (temporary) data to some directories while it’s performing it’s magic, specifically the storage
and bootstrap/cache
directories. Run the following commands from the Laravel base project folder (e.g., $HOME/projects/laravel_project
):
chmod -R 777 storage bootstrap/cache
Essentially, this sets “full access” permissions on these directories, so that no matter what process executes the Laravel application, it will be able to read from and write to them. Read more about Linux file permissions and how to manage them here.
Set up an Apache virtual host for your Laravel project.
Probably the one thing (from the developer’s perspective anyway!) that Nginx makes so simple compared to Apache is virtual host configuration. Virtual hosts is the web server terminology for allowing a single machine (host) to serve multiple web sites. For us, the main value is in allowing us to create an abbreviated name for our Laravel project. In addition, for Laravel, we actually must use a virtual host, so that we can properly set permissions for the project directories to avoid ‘403 Forbidden’ HTTP error, due to changes to default security settings in versions 2.4.3 and above of Apache server. See this article for more details.
In this step, we’ll create a new site configuration named laravel_project.conf
which contains our named virtual host configuration. All of the files that we’ll be working with are system files owned by the root
user, so we must use sudo
command with all of them. Also, don’t feel obligated to use the nano editor; I just use it here, since it’s installed by default on Ubuntu Linux (and it’s a pretty good editor, too!).
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/laravel.conf sudo nano /etc/apache2/sites-available/laravel_project.conf
Modify the laravel_project.conf
contents so that they look like this:
NameVirtualHost *:8080 Listen 8080 <VirtualHost *:8080> ServerAdmin admin@example.com ServerName laravel.dev ServerAlias www.laravel.dev DocumentRoot /home/user/projects/laravel_project/public <Directory /home/user/projects/laravel_project/public/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all Require all granted </Directory> LogLevel debug ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
In this file, replace /home/user
with the name of the $HOME directory for your account on the machine. (This is the directory where you created the projects
directory earlier.) Also, note that the root directory (DocumentRoot
) is the public
directory in your Laravel project folder. This is mainly for security as it means that the actually application files are stored in directories that the web server does not have access to. Finally, observe that we have specified that the TCP port that Apache will allow connections on (“listen” on) for the virtual host is 8080. This is a frequently used alternate port to the standard HTTP port of 80. We use 8080 to avoid conflicting with any other web applications already installed on your system.
Add new virtual host to hosts
file.
You probably noticed in the previous step when setting up the virtual host configuration for our project, we specified laravel.dev
as the ServerName
. Basically, this is the “short” name for our virtual host. So, everything is set from the virtual host perspective to use this name. However, we need to configure our machine to recognize this name. To do this, we add an entry to machine’s hosts
file. Open the hosts file:
sudo nano /etc/hosts
In the hosts
file, add this new line at the end (or anywhere):
127.0.0.1 laravel.dev
Save the file.
Enable new virtual host and (optionally) disable the default virtual host.
After all of this, we are almost done! The last thing that we need to do is enable the virtual host configuration laravel_project.conf
that we created above. To do this:
sudo a2ensite laravel_project.conf
You’ll be prompted to reload the Apache server process. However, before we do that, we (optionally) may want to disable the default Apache configuration. Again, if you have other web applications, such as phpMyAdmin, running on your machine, you do not want to disable this configuration. Otherwise, to avoid confusion, it probably makes sense to disable it:
sudo a2dissite 000-default.conf
Note that enabling (a2ensite
) and disabling (a2dissite
) don’t delete or otherwise change your configurations; they simply turn them “on” or “off”. (Basically, these utilities create or remove a symbolic link to the configurations in the /etc/apache2/sites-available
directory to the same name in the /etc/apache2/sites-enabled
directory.)
Now, we are ready to restart Apache server and see if everything works! To restart the server:
sudo services apache2 restart
Now, open a web browser and enter http://laravel.dev:8080/ in the address field. You should see the standard Laravel landing page screen.
If you don’t see the landing page, then check that the above steps were performed correctly. Specifically, ensure that you have set permissions on storage
and bootstrap/cache
directories and that you have specified Require all granted
in the section of
laravel_project.conf
.
[Optional] Install Node.JS JavaScript engine, which is required for Laravel Elixir.
These final two steps are entirely optional, but they can be helpful in setting up a fully-functional development environment.
In this step, we install the popular Node.JS JavaScript engine. Node.JS provides many great utilities, including supporting the Gulp task-runner/build utility used to process CSS and JavaScript files, which underpins the Laravel Elixir tool.
Previously, I have written about installing Node.JS from source code. However, using the official Node.JS PPA makes things a snap. To install Node.JS, do the following:
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get -y install nodejs
The script that is downloaded via curl
sets up the Node.JS repositories and updates the repository cache, so you can proceed directly to installation.
To confirm that the install succeeded, check the versions of Node.JS and its companion NPM utility:
node -v npm -v
[Optional] Create a MySQL (or SQLite) database to use with your Laravel project.
The final (optional) step in the process is to create a MySQL database for your project. Instead of showing all the details here, please refer to this article. It includes information about setting the database configuration details in the Laravel .env
file so that Laravel can load them directly.
Summary
To wrap up this article, here are the steps with only the actual commands that you run to use as a quick reference.
- Install PHP, Apache HTTP server, and MySQL.
- Enable
mod_rewrite
for Apache. - Install Composer globally.
- Create your Laravel project in user directory.
- Set permissions for Laravel folders.
- Set up an Apache virtual host for your Laravel project.
- Add new virtual host to
hosts
file. - Enable new virtual host and (optionally) disable the default virtual host.
- [Optional] Install Node.JS JavaScript engine, which is required for Laravel Elixir.
- [Optional] Create a MySQL (or SQLite) database to use with your Laravel project.
sudo apt-get update && sudo apt-get -y install software-properties-common python-software-properties sudo apt-add-repository -y ppa:ondrej/php && sudo apt-get update sudo apt-add-repository -y ppa:git-core/ppa && sudo apt-get update export DEBIAN_FRONTEND=noninteractive sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password password mysql_password' sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password mysql_password' sudo apt-get -y install mysql-server sudo apt-get -y install php5.6-bz2 php5.6-cli php5.6-curl php5.6-json php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-readline php5.6-sqlite3 php5.6-xml php5.6-xsl php5.6-zip php-xdebug apache2 libapache2-mod-php5.6 git curl
sudo a2enmod rewrite sudo service apache2 restart sudo apachectl -t -D DUMP_MODULES | grep rewrite
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer php -r "unlink('composer-setup.php')"
cd $HOME mkdir projects cd projects composer create-project laravel/laravel laravel_project --prefer-dist 5.2.* ## Check installation cd laravel_project php artisan
chmod -R 777 storage bootstrap/cache
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/laravel.conf sudo nano /etc/apache2/sites-available/laravel_project.conf
## laravel_project.conf NameVirtualHost *:8080 Listen 8080 <VirtualHost *:8080> ServerAdmin admin@example.com ServerName laravel.dev ServerAlias www.laravel.dev DocumentRoot /home/user/projects/laravel_project/public <Directory /home/user/projects/laravel_project/public/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all Require all granted </Directory> LogLevel debug ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
sudo nano /etc/hosts
In the hosts
file, add this new line at the end (or anywhere):
127.0.0.1 laravel.dev
sudo a2ensite laravel_project.conf sudo a2dissite 000-default.conf ### OPTIONAL sudo services apache2 restart
Open web browser to http://laravel.dev:8080/.
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get -y install nodejs node -v npm -v
mysql -uusername -ppassword mysql> CREATE DATABASE `laravel` CHARACTER SET utf8 COLLATE utf8_general_ci; mysql> CREATE USER 'laravel_user'@'%' IDENTIFIED BY 's3cr3t'; mysql> USE `laravel`; mysql> GRANT ALL PRIVILEGES ON `laravel`.* TO 'laravel_user'@'%'; mysql> FLUSH PRIVILEGES; mysql> exit;
Note that on the GRANT
statement, the backticks (`
) are only around the database name. The .*
, which means “all tables”, are outside of the backticks.
To see the permissions (privileges) granted to laravel_user
, in the MySQL shell, run:
mysql> SHOW GRANTS FOR 'laravel_user'@'%';
This should return something like:
+-----------------------------------------------------------+ | Grants for laravel_user@% | +-----------------------------------------------------------+ | GRANT USAGE ON *.* TO 'laravel_user'@'%' | | GRANT ALL PRIVILEGES ON `laravel`.* TO 'laravel_user'@'%' | +-----------------------------------------------------------+
An alternate method of creating the database non-interactively (i.e., without logging into MySQL directly, but by running commands at the shell prompt) is to use the MySQL -e
command-line parameter:
mysql -uusername -ppassword -e "CREATE DATABASE \`laravel\` CHARACTER SET utf8 COLLATE utf8_general_ci;" mysql -uusername -ppassword -e "CREATE USER 'laravel_user'@'%' IDENTIFIED BY 's3cr3t';" mysql -uusername -ppassword -e "USE \`laravel\`; GRANT ALL PRIVILEGES ON `laravel`.* TO 'laravel_user'@'%'; FLUSH PRIVILEGES;"
Note that you must “escape” the backtick characters (`
) by putting a backslash (\
) in front of them.
Update the .env
file in the root directory of your project with the appropriate parameter values to match your new database:
## .env file DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=laravel_user DB_PASSWORD=s3cr3t
Hope that you found this useful. Let me know your thoughts and questions in the comments.