There is surprisingly little information about deploying a Laravel app. I’ve got an EC2 and wanted to deploy a couple of experiments and had no idea what needs to happen. So, this is a quick overview that I wish I had read on the first day.
composer.json changes, then composer needs to run on the server. It does not need to run for every deploy, but that doesn’t hurt anything.
In addition, there are some folders that need to be expressly marked writable by the server.
One Time Server Task
Composer must be installed, and it can be installed on the server like this:
cd ~ curl -sS https://getcomposer.org/installer | php sudo mv composer.phar /usr/local/bin/composer
The Initial Preparation
Laravel is built with PHP, so the basic setup is the same as WordPress. So start with the same steps as deploying WordPress:
1. Point the DNS records to your server.
2. Add a
my-project.conf file to the nginx/apache config that is similar to the WordPress configuration.
3. The one difference to the conf file is to add “public” to the path. Here is the example for nginx:
4. Don’t forget to restart apache or nginx.
The next few steps require that you have your project stored in git and that you have ssh access to your server.
1. Make a script file in the root folder of your project called
deploy_constants.sh. DO NOT CHECK THIS FILE INTO GIT. It will contain your secrets. It should look like this:
#!/usr/bin/env bash #The location that all of the deployments are on this server. BASE_DIR=/var/www/html # The folder that will contain this deployment (often the domain name) DIR_NAME=my-project.com # The SSH line (That is, "ssh $SSH" should work.) SSH=me@myserver # On the server, "git clone $REPO" needs to work. REPOemail@example.com:account/repo.git ROOT=$BASE_DIR/$DIR_NAME
2. Then make another script called
deploy-to-production-setup.sh that contains:
#!/usr/bin/env bash . $(dirname "$0")/deploy_constants.sh ssh $SSH "cd $BASE_DIR && git clone $REPO $DIR_NAME" ssh $SSH "cd $ROOT/public && mkdir js" ssh $SSH "cd $ROOT/public && mkdir css" ssh $SSH "cd $ROOT/public && mkdir fonts" scp .env $SSH:$ROOT/.env ssh $SSH "cd $ROOT && chmod -R 777 ./storage" ssh $SSH "cd $ROOT && chmod -R 777 ./bootstrap/cache"
3. Run this script. That should leave a new folder on the server with all of the source files.
4. On the server, edit the file
.env to be correct for the server. At least change
APP_ENV to “production”, and
APP_URL to the actual URL. There are likely other app-specific things to change.
5. Create the following deployment script, and call it
#!/usr/bin/env bash . $(dirname "$0")/deploy_constants.sh npm run production ssh $SSH "cd $ROOT && git pull" scp -r public/js/* $SSH:$ROOT/public/js scp -r public/css/* $SSH:$ROOT/public/css scp -r public/fonts/* $SSH:$ROOT/public/fonts ssh $SSH "cd $ROOT && composer install --no-dev"
Each Deployment Iteration
Each time you want to push the latest code to production, check your code in, compile it, and run the
deploy-to-production.sh script. This compiles the assets, gets the latest code from github, and runs composer just in case something changed.
I put the following two scripts in package.json for convenience and documentation:
"deploy-production": "./deploy-to-production.sh", "deploy-production-setup": "./deploy-to-production-setup.sh"
Then I can deploy with:
npm run deploy-production
deploy-to-production-setup.sh are completely generic, so the same files can be used for all projects. It is just the values in
deploy_constants.sh that change.