Search code examples
phpsymfonyfosrestbundle

Symfony Built-in Web Server on an external environment


I configured a web service locally using FOSRestBundle, and it's working perfectly. The only thing i need to write to start my service is

php bin/console server:run xxx.xxx.x.xx:port 

and it's all set.

But then i was reading some documentation about the symfony web server, and this information is confusing me:

The built-in web server is meant to be run in a controlled environment. It is not designed to be used on public networks.

How i'm suppose to use this in my cloud environment? If i want to make this public, how should i start my REST service without using this built-in server?

What is equivalent to the "server:run" command? If i just put the code there, it will not work. I need to start the server for my REST API.


Solution

  • The equivaluent of the server:run command in a production environment is a bit more involved. The web server on a public facing machine has more responsibility than a local development server, and so it needs a bit more configuration.

    For production (or even staging) purposes, use a production-ready web server like Apache or Nginx.

    I'll share a default setup for apache, on a Debian-based (Ubuntu) system here, and detail a few common pitfalls to avoid.

    1. Install LAMP components

      ssh into your machine, and run this command to make sure that apache, php, mysql, etc, are all installed!

      First, get the most recent data from the repositories:

      sudo apt-get update

      The LAMP components that you'll need to run symfony on:

      sudo apt-get install apache2 mysql-server libapache2-mod-auth-mysql php5-mysql php5 libapache2-mod-php5 php5-mcrypt

      Be sure to store down the root MySQL pass if it asks you for one. (in the event you didn't have it installed, yet.)

    2. Configure MySQL

      sudo mysql_install_db to initialize MySQL's system/help tables, etc.

      sudo /usr/bin/mysql_secure_installation to drop test tables, reload privilege tables.

      Jump into the MySQL shell and create a user & db for your app.

      mysql -u root -p, and supply your root pw when prompted.

      mysql> CREATE USER 'otuyh'@'localhost' IDENTIFIED BY 'password'; will create your otuyh user with the password password.

      mysql> CREATE DATABASE otuyh_app; will create the database your app needs to run on.

      mysql> GRANT ALL PRIVILEGES ON otuyh_app.* TO 'otuyh'@'localhost';

      mysql> FLUSH PRIVILEGES;

    3. Configure Apache (the production version of server:run)

      Clone or upload your project to /var/www/html.

      Edit /etc/apache2/sites-enabled/000-default.conf and change the line:

      DocumentRoot /var/www/html to DocumentRoot /var/www/html/web

      This tells apache which directory to serve requests from the web folder of your app.

      Also, alter the line ServerName white-macbook to ServerName example.com where example.com is the domain name pointed at your server.

      Finally, add an AllowOverride All line in there, too, to explicitly state that your .htaccess file can also add directives for the web server.

      Drop an .htaccess file in your web/ folder that looks something like this:

      <IfModule mod_rewrite.c>
          Options +FollowSymlinks
          RewriteEngine On
      
          RewriteBase /
      
          # Explicitly disable rewriting for front controllers
          RewriteRule ^app_dev.php - [L]
      
          RewriteCond %{REQUEST_FILENAME} !-f
          # Change below before deploying to production
          RewriteRule ^(.*)$ app_dev.php [QSA,L]
      </IfModule>
      

      Alter app_dev to just app, when you're ready to change the environment to production.

      Make sure you restart the apache2 service after having altered it's config: sudo service restart apache2.

      Run your regular sf2 schema creation, composer install, etc.

      And then, make sure that the apache user that serves the files up indeed has access to them!

      Additionally, after running composer * or cache:clear as a user other than the one serving files, write permissions can get mixed up, and www-data will need this privilege to write logs, and get cached files. A quick solution:

      chown -R your-unix-user:www-data ./app find ./app/cache -type d -exec chmod 775 {} \; find ./app/logs; -type d -exec chmod 775 {} \; find ./app/cache -type f -exec chmod 664 {} \ find ./app/logs -type f -exec chmod 664 {} \