To actually get our application up and running, we need to do a few more things on the remote server:
sprinkles.json
, run our migrations, and install frontend vendor assets;/var/www/<repo name>/public/
as the document root;certbot
to install an SSL certificate for your site.The tricky thing about Composer is that it will try to pull the latest version of a dependency (subject to the version constraints in composer.json
) every time you run composer update
. This means that you could end up with latest version of dependencies in production every time you update your code - even if you don't want them!
To get around this, commit the composer.lock
file to your repository. Then, when you run composer install
on the remote machine, it will pull the exact same versions of your dependencies as those that were last pulled when you ran composer update
locally.
A few more caveats:
~/.composer
directory, but it doesn't like when you try to run Composer as sudo
. To address this set proper ownership and permissions on the ~/.composer
directory:sudo chown <your username>:<your username> ~/.composer
sudo chmod u+rwx,g+rwx ~/.composer
Now, to run Composer:
cd /var/www/<repo name>
composer install
If you get errors related to the php-zip
package, you may need to install it:
sudo apt-get install zip unzip php7.0-zip
sudo service nginx restart
We can add the following line to our post-receive
hook to automatically rerun composer install
each time we push changes:
# Install or update packages specified in the lock file
composer install --working-dir=/var/www/<repo name> >> /var/log/deploy.log 2>&1
Just like we did in development, we'll run Bakery in the production environment to configure our DB and mail credentials, setup sprinkles.json
, and install assets. Again, do this in the /var/www/<repo name>
directory:
php bakery bake
When Bakery finishes, modify the .env
file and set UF_MODE
to production
.
UserFrosting ships with a default nginx configuration file, in webserver-configs/nginx.conf
. Copy this file to a new filename. You can name the copy anything you like, but the convention is to use the same name as that of your repository, followed by .conf
.
We'll start by setting the root
and server_name
directives. root
is the application's document root directory, and server_name
is the hostname (domain or subdomain) that should be served from this directory. Find the Server Info
block. Change it to look like this:
## Begin - Server Info
## Document root directory for your project. Should be set to the directory that contains your index.php.
root /var/www/<repo name>/public;
server_name owlfancy.com;
## End - Server Info
Again, <repo name>
should be replaced with your project repo name, and owlfancy.com
should be changed to your site's planned domain or subdomain.
Next, we'll tell nginx to run our application with PHP 7. Why? Because it's super fast! Find the lines that say "For FPM". Comment out the line for PHP 5, and uncomment the line for PHP 7:
# For FPM (PHP 5.x)
#fastcgi_pass unix:/var/run/php5-fpm.sock;
# For FPM (PHP 7)
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
Save your changes. We can now use scp
to copy this file from your local machine to nginx's configuration directory on the remote repository. Since we disabled remote root login, and only the root user can write to /etc/nginx/sites-available
by default, we'll first copy to our home directory on the remote server, and then use sudo
on the remote server to move it into nginx's directory.
In your local development environment:
scp /<path to local project directory>/webserver-configs/<repo name>.conf <your username>@<hostname>:~
If this succeeded, then you can go back to your remote environment, move the config file to /etc/nginx/sites-available
, and "enable" it by creating a symlink and reloading the webserver:
sudo mv ~/<repo name>.conf /etc/nginx/sites-available/<repo name>.conf
sudo ln -s /etc/nginx/sites-available/<repo name>.conf /etc/nginx/sites-enabled/<repo name>.conf
sudo service nginx reload
We also need to make sure that nginx can read the public/
directory, and write to the cache, logs, and sessions directories:
cd /var/www/<repo name>/
sudo chown <your username>:www-data public
sudo chown <your username>:www-data app/cache app/logs app/sessions
After your first git push
, you'll want to set up the cache/
directory so that it is owned by the www-data
group. Since both your user account and webserver are part of this group, they'll both be able to write to it. This is important, so that in your post-receive
script, you'll have the necessary permissions to clear the cache when you push. To do this, we'll use the setfacl
command:
sudo setfacl -d -m g::rwx /var/www/<repo name>/app/cache
A note about debugging server configuration: Browsers and operating systems tend to aggressively cache DNS resolutions and redirects. This means that if you misconfigured your server initially and it returned an error due to DNS or webserver configuration issues, your browser might still have the error response cached even after you've fixed the problem. You may need to clear your browser's cache or even your operating system's DNS cache. When configuring your server, you might have better luck using
curl
to check whether a particular URL is working, rather than going through your browser.
We can use Bakery again to compile our asset bundles for production, and copy all assets from our Sprinkles to the public/
directory so they may be served more efficiently by the webserver:
php bakery build-assets -c
If everything worked out successfully, you should now be able to access the http
version of your live site in your browser! The next step is to install an SSL certificate.