Deploying symfony 4 application to shared hosting with just FTP access

runawaycoin
Apr 18, 2018 · 6 min read

Follow this tutorial to easily deploy to and run your symfony based PHP website from a shared web host service, using just FTP.

Docker, server side ssh, composer and git etc are great tech to utilise to deploy and run your website but they are not for everyone and sometimes you just want to use a cheap and simple hosting provider rather than do all the server maintenance work yourself.

I will focus on deploying a Symfony version 4 application because that is the latest and greatest version of the framework, though most of this tutorial is applicable to previous versions of symfony too.

These are the steps to follow to create and deploy your app:

  1. Create your symfony 4 application
  2. Setup your server account
  3. FTP your application
  4. Setup your environment variables and index.php
  5. Create your database
  6. Load your website!

1) Create your symfony 4 application

Obviously you need to create a Symfony app to deploy :)

Follow the recommended guidelines using flex and composer and you shouldn’t go wrong: http://symfony.com/doc/current/setup/flex.html

I also recommend using encore / webpack for your front end css and javascript files: http://symfony.com/doc/current/frontend.html

So test your site locally to ensure it works fine, its best to match your local webserver and database application and version as close as possible to the server’s version you are going to run your site from.

This is usually apache, php and mysql (mariaDB). Pay attention to the PHP and database versions, some hosts let you choose which PHP version you want to use — the latest stable: php 7.2 is recommended if possible.

2) Setup your server account

Now you need to sign up for your shared host account and know the ftp credentials.

There are many thousands of hosts that you can use and everyone’s requirements differ so I wont guide you to any particular host for this tutorial, all you need to have for sure is PHP, and version PHP 7.2 is best to avoid any problems.

You might need to set the default PHP version for your site to use, if your host provides cPanel access, this setting is usually under MultiPHP Manager.

3) FTP your application

Now its time to deploy your application to your server.

Its good to run these composer commands to prepare your application for live production use:

SET APP_ENV=prod
composer install --no-dev --optimize-autoloader
composer dump-autoload --optimize --no-dev --classmap-authoritative

Note: that first command sets the symfony env to prod (windows), see notice on the doc here: https://symfony.com/doc/current/deployment.html#c-install-update-your-vendors

And if you are using encore run this command:

node_modules\.bin\encore production

If you are deploying to an apache server run this command to create the recommended .htaccess file:

composer require symfony/apache-pack

Its best to keep your public files separate from your logic / application files, this means uploading your files to two separate locations on the server.

Upload your public folder contents to your public_html or www folder on your FTP sever.

If there is already a .htaccess file on your server — its best to merge your file with the one on the server as it might contain server config thats needed (ie PHP version to use).

Upload the following folders (and contents) from your application to a new folder in your root of your FTP server named symfony:

bin
config
src
templates
translations
vendor

Note: Only upload the bin folder if you want to run the console, maybe via a cron job, also best to rename console to console.php

Also create the var folder but dont upload its contents.

And upload your composer.json file to this symfony folder — this is needed to help symfony find its application files.

So you should have this on your server:

\symfony
bin
config
src
templates
translations
vendor
composer.json

Note: the contents of the public_html will depend on your application, you might have more folders eg img, js, css etc. The bundles folder is needed if you have used any bundles that have front end (js / css) files. The build folder contains your built js and css files that are created by encore.

4) Setup your environment variables and index.php

Before your application will work you need to modify your index.php file and set your env vars.

First edit your index.php (locally inside your public folder, on the server will be inside your public_html folder).

Edit this line:

require __DIR__.’/../vendor/autoload.php’;

To:

require __DIR__.’/../symfony/vendor/autoload.php’;

This says where your application files are located relative to the index.php file.

Now you need to set your environment variables (ie database url etc), locally these are usually in your .env file.

Using your .env file on the server is not recommended so we need to set environment variables another way.

You can do this either inside a .htaccess file, your index.php, or in your parameters.yaml config file.

.htaccess

You can set environment variables in a .htaccess file like this (if you are running apache):

SetEnv APP_ENV prod
SetEnv DATABASE_URL 'mysql://user:pw@127.0.0.1:3306/dbname'

index.php

Some hosts might have disabled doing the above so you can add your environment variables to your index.php (or another .php file that you include inside your index.php file) file like:

$_SERVER[‘APP_ENV’]=’prod’;
$_SERVER['DATABASE_URL']='mysql://user:pw@127.0.0.1:3306/dbname'

Note: DATABASE_URL is the new convention for symfony 4 apps, the password needs to be url encoded.

parameters.yaml

The third option is to store your environment variables in a parameters.yaml config file (stored under config/packages).

parameters:
APP_ENV: "prod"
env(DATABASE_URL): "mysql://user:pw@127.0.0.1:3306/dbname"

encore configuration

If you have used encore for your js and css, you also need to tell symfony where your manifest.json is relative to your logic files.

So edit or create: config\packages\prod\framework.yaml file and add:

framework:
assets:
json_manifest_path: '%kernel.root_dir%/../../public_html/build/manifest.json'

(Note: due to formatting the last line is split but in your config file the json_manifest_path and its value should be on the same line)

5) Create and update your database

You now need to ensure your database is setup and updated.

This can be done in many ways and is a bit harder with shared hosting as ideally you run commands over ssh direct on your server.

Usually webhosts provide access to phpmyadmin where you can setup and update your database.

If you have your database locally which you want to use on the server: use phpmyadmin to import it.

Or and going forward you might change the database columns / entity properties which you want to add to your live database, so use this command locally to generate the SQL required to update the database schema:

php bin/console doctrine:schema:update --dump-sql

Before running this command copy your database from your server to your local database server. Run the above command and then execute the generated SQL on your server using phpmyadmin.

You can use the above command to generate the required SQL to create your whole database too.

6) Load your website!

Now you should be ready to load your site for the first time.

It will be slow for the first load as symfony needs to generate its cache (ideally you do this via a ssh command if it was possible).

Problems you may encounter

Server error 500

You may get this error for a number of reasons.

Maybe its due to your host disabling SetEnv in .htaccess files so add your environment variables to your index.php file instead.

Maybe symfony cant access and write to your symfony/var folder, check its permissions via ftp and chmod it to 775.

Maybe its due to wrong version of PHP, ideally it should be 7.2 or 7.1. Check your cPanel settings or however your host allows you to this up.

Any problems to test what version of PHP is being used, create a new php file with just:

<?php
phpinfo();

Upload it and load it in your browser — this tells you what php version is running.

Otherwise check your server logs files:

Check any generated error_log file in your public_html folder, or use cPanel or what ever you can use to see server errors.

Or check your symfony log: symfony/var/log/prod.log

Then try Google any error you find in them.

Check these instruction for anything else you may want to do:
https://symfony.com/doc/current/deployment.html

Good luck! :) Please share your experiences.