Getting Up and Running - Direct

By the end of this tutorial, your device will be serving a Symfony project using Nginx. Along the way, you’ll be:

  • Installing and setting up editor to manage your code with
  • Configuring your system to act as a web server
  • Setting up a Database and creating your database user
  • Learning how to use the Symfony installer to create projects


This tutorial assumes you are running Ubuntu 16.04 as your operating system, the package names and file locations will be different if you are running in a different environment.

Editing our Code

You will want to have a powerful way to manage code because the default environment (Ubuntu) lacks one. For these tutorials, I have chosen Atom because it’s lightweight and incredibly extendable thanks to the plugin interface. More information about Atom can be found on the official site

There is a Personal Package Archive (repositories used to install programs that cannot be found through official channels) available which allows you to install and manage Atom like any other Linux package so, you'll be adding that first.

  1. sudo add-apt-repository ppa:webupd8team/atom
  2. sudo apt-get update
  3. sudo apt-get install atom

Once you've installed Atom, we're going to install an extension to improve usability of the editor. Make sure you've got Atom Editor open, click edit -> preferences and then when the options tab opens choose the install option. Using the search option find and install php-twig.

The Twig extension is a definite recommendation as it is the default templating language used by Symfony but, through showing you how to install it, wanted to highlight the process of installing extensions. Atom Editor has an excellent array of extensions to choose from, here is a quick list as food for thought that the author recommends investigating

  • docker - Control Docker straight from Atom
  • docblockr - A helper package for commenting your code
  • pigments - Detects colour values within your code and previews them
  • color-picker - With an ctrl-click over colour values in your code, change the colour with ease
  • minimap - A navigation aid for your code which allows you to have a more visual oriented scrollbar
  • minimap-git-diff - When using version control, highlight the changes in your minimap

The Application Stack

We'll start by installing the packages that will run the web environment so start by pulling up a shell and using the following command. Note that for most of the commands in this chapter, you will either need to be an administrator or have sudo access and prefix each with sudo.

  1. sudo apt-get install mysql-server nginx php-fpm php-intl php-json php-mysql php-opcache php-xml composer

During installation, MySQL will ask you to generate a root password. Make a note of whatever you have chosen, it is the master password.

Above, we are installing

  • mysql-server - This is the Database engine that will store dynamic data
  • nginx - This is the web server that will process browser requests and deliver pages back to the user
  • php-fpm - PHP FastCGI Process Manager, a version of PHP that runs as a system daemon to run the application
  • php-intl - An internationalization plugin for PHP which performs various locale aware operations
  • php-mcrypt - An encryption interface which allows scrambling of data. Deprecated but, included for compatibility
  • php-json - Utilities for handling JavaScript Object Notation; a data storage format
  • php-mysql - A series of helper methods for allowing php to easily communicate with the database
  • php-opcache - Compiles PHP code and stores it in memory for much faster access
  • php-xml - Utiles for handling the eXtensible Markup Language; a data storage format
  • composer - A dependancy manager for PHP which allows you to simply use third party code

You may notice that in this command, we’re installing some PHP modules. A full list of Symfony requirements can be found on the Requirements for Running Symfony page.

In case we didn't install some of the above extensions, there are a series of polyfills that get downloaded with Symfony and used automatically if not present. We will verify everything is setup properly using a requirements checker which comes with Symfony later on.

User Permissions

With the system packages installed, we’ll next want to make sure our user has permissions to edit the files within the web space later on. Our web server (by default) runs as www-data so, the simplest solution will be to add our user to the www-data group.

  1. sudo usermod -aG www-data user_name

Don’t forget that we’ll need to log out and back in again for these changes to take effect. After logging back in, let’s change the ownership and permissions on the web server directory away from the default root. If we were to now run id, we’d see that our user is now in the www-data group.

  1. id

PHP Configuration

With the necessary packages installed, let’s configure PHP. First we enable one of the downloaded PHP extensions which isn’t switched on by default

  1. sudo phpenmod opcache

The second is to set the default timezone which involves editing the PHP config files for both the Apache module and the command line interface. Search for date.timezone, uncomment the declaration by removing the semi-colon and replace the value with the Area/City seperated by a slash; reference can be found on the PHP website.

  1. # /etc/php/7.0/cli/php.ini
  2. # /etc/php/7.0/fpm/php.ini
  4. date.timezone = Asia/Hong_Kong

Symfony Dedicated Installer

At this point, we have everything we need to install and run Symfony as it can be installed through Composer but a dedicated Symfony installer is the officially recommended option. It makes project creation quicker by configureing some default settings for us and some extra template code that will make things simpler later on.

  1. sudo curl -LsS -o /usr/local/bin/symfony
  2. sudo chmod a+x /usr/local/bin/symfony
  3. symfony

Running the symfony wrapper without any flags presents you with helpful information illustrating the various ways to create a project. We will be using the default settings which results in the latest release.

Creating the Project

At the time of this tutorial, Symfony 3.2 is being used. For new projects, this is recommended over the Long Term Support (LTS) because a new candidate for LTS will be released in 2017 and the coding style will be much closer to it compared to the current 2.8 LTS version of Symfony. From your home directory run the following command.

  1. symfony new mytestproject
  2. cd mytestproject

Setting up the Database

In this section, we're going to configure a user and database schema for the Symfony application to use. It's always good practise to isolate database access for security purposes. If we didn't and some malicious code ran on your website, it could reach beyond just your application.

Even with MySQL installed, it isn't fully setup yet but there is a nice helper wizard to aid in this task which you should follow the prompts for. From the command line:

  1. sudo mysql_secure_installation

With that part done, let's log in to the MySQL shell and create the DB

  1. # Log in to the SQL shell
  2. mysql -uroot -pYOUR_ROOT_PASSWORD
  3. # Create a Database
  4. CREATE DATABASE symfony_tutorial_db;
  5. # Create a user
  6. CREATE USER "symfony_db_user"@"localhost" IDENTIFIED BY "symfony_db_user_password";
  7. # Grant the user privileges on the symfony database
  8. GRANT ALL ON symfony_tutorial_db.localhost TO "symfony_db_user"@"localhost";
  9. # Refresh MySQL privileges internally
  11. # Leave the SQL prompt
  12. exit;

Connecting Symfony to the Database

Symfony configuration can be defined in various formats (ini, raw PHP, XML and YAML), even using different formats across the same project.

We’ll be using YAML (Yet Another Markup Language ) because Symfony Standard Edition uses it by default. It is a quick to write, human friendly way of defining data serialization. As a subject, configuration will be covered in greater detail in a later tutorial.

For now, you just need to know to change the options relating to database as shown below. Open app/config/parameters.yml and mofify as shown below

  1. parameters:
  2.     database_host: localhost
  3.     database_port: null
  4.     # Change this to the database you created earlier
  5.     database_name: symfony_tutorial_db
  6.     # Change this to the database user you created earlier
  7.     database_user: symfony_db_user
  8.     # Change this to the database user password you set earlier
  9.     database_password: symfony_fb_user_password
  10.     mailer_transport: smtp
  11.     mailer_host: null
  12.     mailer_port: null
  13.     mailer_user: null
  14.     mailer_password: null

Running the project

Let’s check whether everything installed correctly using the requirements checker supplied with Symfony

  1. php bin/symfony_requirements

We are ready to run Symfony but, the international extension that ships with Ubuntu is out of date; this is not a problem. Let’s use the built in PHP server in conjunction with the Symfony CLI to check the project actually runs.

  1. php bin/console server:run

With the green light given, open the browser and visit the given URL. You should be greeted by a welcome message telling us what version of Symfony is running and where the project is located.

Using Nginx as a Symfony host

Up to this point, you will have been working from your home directory so, in preperation for delivering the project from Nginx, we will move the project files to the server root. In the command below, myproject is used as a source twice because there is a hidden file present (gitignore) in the project which would otherwise be ignored.

  1. sudo mv ./* ./.* /var/www/html

For Symfony setup, this alone is not enough to get things running. If you check what files are in the project directory, you’ll see that there isn’t an index (or even an HTML/PHP) file. The public root is represented by the web directory. Furthermore, the directory index is not index.php, it is app.php.

Due to this non-standard setup, modifications to the Nginx configuration are needed. Opening up the file at /etc/nginx/sites-available/default you need to change the document root and add a declaration for Directory Index. Copy and paste the following in to this file

  1. server {
  2.     # Listen on port 80
  3.     listen 80 default;
  4.     # Set the web root
  5.     root /var/www/html/web;
  6.     # Look for app.php if no file is specified
  7.     index app.php;
  9.     location / {
  10.         # try to serve file directly, fallback to app.php
  11.         try_files $uri /app.php$is_args$args;
  12.     }
  14.     # DEV
  15.     # This rule should only be placed on your development environment
  16.     # In production, don't include this and don't deploy app_dev.php or config.php
  17.     location ~ ^/(app_dev|config)\.php(/|$) {
  18.         fastcgi_pass unix:/run/php/php7.0-fpm.sock;
  19.         fastcgi_split_path_info ^(.+\.php)(/.*)$;
  20.         include fastcgi_params;
  21.         fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
  22.         fastcgi_param DOCUMENT_ROOT $realpath_root;
  23.     }
  25.     # PROD
  26.     location ~ ^/app\.php(/|$) {
  27.         fastcgi_pass unix:/run/php/php7.0-fpm.sock;
  28.         fastcgi_split_path_info ^(.+\.php)(/.*)$;
  29.         include fastcgi_params;
  31.        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
  32.        fastcgi_param DOCUMENT_ROOT $realpath_root;
  33.        internal;
  34.    }
  36.    # return 404 for all other php files not matching the front controller
  37.    # this prevents access to other php files you don't want to be accessible.
  38.    location ~ \.php$ {
  39.      return 404;
  40.    }
  41.    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
  42.       expires max;
  43.       log_not_found off;
  44.     }
  46. }

After editing the configuration options for Nginx, it is necessary to reload Nginx in order to recognise the changes.

  1. # Test the config file for errors
  2. sudo nginx -t
  3. # If no errors were reported, reload Nginx
  4. sudo systemctl reload nginx

Symfony generates caches at various levels and requires that the project location be writable. Up to this point in the tutorial the files are owned by you the user and are not writable by the group www-data.

  1. # Change ownership of the project location
  2. sudo chown -R www-data:www-data /var/www/html
  3. # Change permissions so that both user and web server have full permissions
  4. sudo chmod -R 775 /var/www/html

Things you should try:

  • Create another Symfony project using a different version
  • Explore some of the add-ons available to Atom that can aid productivity

Communication, our greatest tool

Whether you want to connect, have a problem I can help with or simply want to drop a line, I welcome your words!