illustration

Install a Symfony 3 application on a test server

You have a Symfony 3 application and you want to put it on test ? In this post, we will install a server on Debian 8 ( Jessie ) with PHP7 and Nginx. To deploy our application, we will use "deployer" tool. To your keyboards !

When you want to test new tools, or try new configurations, I advise you to do this on a temporary server and take note of your actions.

For my part, I chose Public Cloud OVH offers. This allow to start quicky a virtual server and you can to get bill by hour ( the cheapest is now 0,008€ / hour ). It's perfect when I want to test a configuration for a day. Stop ads and let's talk about serious things !

I start to call my project "projet" ... not very original, I was not inspired !
Choose the DNS that you will use for your test. To keep consistency, I chose projet.kezaweb.fr. Associate your DNS to your test server.

Login to your server, and start to update your repositories.

sudo apt-get update

We will install PHP 7.1 who is absent from official repository for Debian 8.
Create the file /etc/apt/sources.list.d/php.list and put the following line :

deb https://packages.sury.org/php jessie main

Next, update your package manager and install PHP 7.1 together with Nginx, Git, Mysql and Curl.

sudo apt-get install apt-transport-https lsb-release ca-certificates
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sudo apt-get update
sudo apt-get install --no-install-recommends php7.1 php7.1-fpm php7.1-mysql php7.1-curl php7.1-json php7.1-gd php7.1-mcrypt php7.1-msgpack php7.1-memcached php7.1-intl php7.1-sqlite3 php7.1-gmp php7.1-geoip php7.1-mbstring php7.1-redis php7.1-xml php7.1-zip
sudo apt-get install mysql-server mysql-client nginx git curl

Perfect ! We have installed the necessary tools to make work Symfony 3. We will now create a user for our Symfony project. 

sudo adduser projet

We will now define a php-fpm pool for this user. ( If you put many applications on your server, this is allow you to distinguish them from each other ).

debian@test:/etc/php/7.1/fpm/pool.d$ sudo cp www.conf projet.conf

In this new file projet.conf, change the user by "projet" as well as the address of the socket :  /var/run/php/php7.1-fpm-projet.sock. When it's done, restart php-fpm through the next command : 

sudo service php7.1-fpm restart

To confirm that all is good, you need to check that files are correctly generated.

debian@test:/var/run/php$ ls
php7.1-fpm-projet.sock  php7.1-fpm.pid  php7.1-fpm.sock

I use a database for my Symfony project. It's test, so I will not create a specific user on mysql. Root user will do the trick.

debian@test:~$ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 226
Server version: 5.5.55-0+deb8u1 (Debian)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database projet;
Query OK, 1 row affected (0.00 sec)

Let's prepare the ground for nginx.

debian@test:~$ sudo mkdir -p /var/www/projet.kezaweb.fr/shared/app/config
debian@test:~$ sudo chown -R projet:www-data /var/www/projet.kezaweb.fr

In app/config, move your parameters.yml with the correct data of your server. ( with database access ).

It's time to implement your vhost. We will create a new file and put it to /etc/nginx/sites-available/projet.kezaweb.fr

server {
        listen 80;
        server_name projet.kezaweb.fr;
        root /var/www/projet.kezaweb.fr/current/web;

        location / {
            try_files $uri /app.php$is_args$args;
        }

        # PROD
        location ~ ^/app\.php(/|$) {
            fastcgi_pass unix:/var/run/php/php7.1-fpm-projet.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;
            internal;
        }

        # return 404 for all other php files not matching the front controller
        # this prevents access to other php files you don't want to be accessible.
        location ~ \.php$ {
          return 404;
        }

}

Make a symbolic link to the directory /etc/nginx/sites-enabled/ and test your new nginx configuration with this command :

debian@test:~$ sudo nginx -t

If the answer is positive, it's perfect !
For the last step, you have to use a version control system like Git, and your repository have to be accessible from your new server. I chose the tool "deployer PHP". To insall it, many methods are availables. For my part, I chose to integrate it to my project trought composer.

Before to continue, you have to confirm that you have a ssh gateway between your computeur and projet@yourserver. If don't, create it. It is also necessary that your git project can be clone from your user account without ask a password. When it's done with your ssh keys, we can finish it by writing the file deploy.php.

<?php
namespace Deployer;
require 'recipe/symfony3.php';

// Configuration

set('ssh_type', 'native');
set('ssh_multiplexing', true);

set('repository', 'git@bitbucket.org:kezaweb/projet.git');

add('shared_files', []);
add('shared_dirs', ['web/uploads']);

add('writable_dirs', ['web/uploads']);

// Servers
set('default_stage', 'test');


server('test', 'projet.kezaweb.fr')
    ->user('projet')
    ->identityFile()
    ->set('deploy_path', '/var/www/projet.kezaweb.fr')
    ->stage('test')
    ->set('branch', 'master')
    ->pty(true);
// Tasks

after('deploy:symlink', 'deploy:create_cache_dir');

// [Optional] if deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');

// Migrate database before symlink new release.
before('deploy:symlink', 'database:migrate');

Restart nginx on remote server. Then, on your project, execute the command ./deb deploy... Quite simply !

And normaly, everything should be okay ;)




  • 2017-11-05 aguidis

    Je suis en 3.3.10. Tu veux dire que Deployer "sait" de base qu'il doit aller chercher le fichier dans "/shared/app/config" ?
    A priori j'ai les droits suffisants. En installant "acl" sur le serveur je n'ai plus eu l'erreur... Ce qui est curieux c'est que j'ai forcé le "writtable_mode" à "chgrp" et non "acl" donc j'étais étonné de voir cette erreur :

    > Cant't set writable dirs with ACL

  • 2017-11-05 Yoann

    C'est étrange, car normalement tu n'as pas besoin de faire une tâche copy_sf_parameters.
    Tu es sur quelle version de symfony ?
    Pour ton erreur sur le depoy:writable, il faut effectivement faire attention à ce que ton utilisateur ait tout les droits nécessaires pour agir dans ton projet. Je l'ai effectivement pas précisé dans mon post :)

  • 2017-11-05 aguidis

    Pour que mon application puisse utiliser le parameters.yml du serveur j'ai dû faire une tâche custom qui copie ce fichier dans le répertoire de la release en cours (cp {{sf_parameters_file_path}} {{release_path}}/app/config/parameters.yml):

    after('deploy:update_code', 'copy_sf_parameters');

    Ca semble fonctionner :)

    Maintenant j'ai une erreur pendant la tâche `deploy:writable`:
    > Unable to setup correct permissions for writable dirs.
    You need to configure sudo's sudoers files to not prompt for password,
    or setup correct permissions manually.

    J'ai de l'espoir je vais y arriver ^^'

  • 2017-11-05 Yoann

    Bonjour :)
    Je ne comprend pas ta question. Qu'entends-tu pas "utiliser" ?
    Le fichier parameters.yml doit être présent dans shared/app/config car il n'est pas versionné et est propre à chaque application.

  • 2017-11-05 aguidis

    Bonjour,

    merci pour cette présentation. Je voulais savoir à quel moment vous utilisiez le parameters.yml dans /shared/app/config ?