diff --git a/Ubuntu-16.04/frameworks/laravel/cloud-init.yaml b/Ubuntu-16.04/frameworks/laravel/cloud-init.yaml new file mode 100644 index 0000000..a696980 --- /dev/null +++ b/Ubuntu-16.04/frameworks/laravel/cloud-init.yaml @@ -0,0 +1,146 @@ +#cloud-config +# Run Laravel, nginx, MySQL, Let's Encrypt on Ubuntu +packages: + - nginx + - mysql-server + - php7.0-fpm + - php7.0-mysql + - php7.0-mbstring + - php7.0-xml + - composer + - unzip + - git + - jq + +runcmd: + # domain, DO API token to use later + - export DOMAIN=<%YOUR_TOP_LEVEL_DOMAIN.COM%> + - export DO_API_TOKEN=<%YOUR_DIGITALOCEAN_API_TOKEN%> + # url of public laravel app repo to use, default ot official quickstart demo app + - export LARAVEL_REPO=https://github.com/laravel/quickstart-basic + # SUBDOMAIN will default to NAME OF THIS DROPLET, to override, replace $(...) with your subdomain + - export SUBDOMAIN=$(curl -s http://169.254.169.254/metadata/v1/hostname) + + # get this servers public_ipv4 and droplet_id to use later + - export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address) + - export DROPLET_ID=$(curl -s http://169.254.169.254/metadata/v1/id) + # get the droplet owner's email (needed for letsencrypt TOS) + - 'export EMAIL=$(curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DO_API_TOKEN" https://api.digitalocean.com/v2/account | jq -r ".account.email")' + + # add a laravel_user + - adduser --disabled-password --gecos "" laravel_user + - usermod -aG www-data laravel_user + + # run the unattended equivalent of mysql_secure_installation + - export MYSQL_PWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c16) + - mysqladmin -u root password "$MYSQL_PWD" + - mysql -u root -p"$MYSQL_PWD" -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')" + - mysql -u root -p"$MYSQL_PWD" -e "DELETE FROM mysql.user WHERE User=''" + - mysql -u root -p"$MYSQL_PWD" -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'" + - mysql -u root -p"$MYSQL_PWD" -e "CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;" + - mysql -u root -p"$MYSQL_PWD" -e "GRANT ALL ON laravel.* TO 'laravel_user'@'localhost' IDENTIFIED BY '$MYSQL_PWD';" + - mysql -u root -p"$MYSQL_PWD" -e "FLUSH PRIVILEGES" + + # Disable the "find closest file match" behavior in php for security + - sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/7.0/fpm/php.ini + - systemctl restart php7.0-fpm + + # setup the laravel app + - mkdir -p /var/www/html/laravel_app + - cd /var/www/html/laravel_app + - git clone $LARAVEL_REPO . + - export HOME=/root && export COMPOSER_HOME=/root + - composer install + # site is publicly accessible, switch to production and turn off debug + - sed -i -e 's/APP_ENV=.*/APP_ENV=production/' /var/www/html/laravel_app/.env + - sed -i -e 's/APP_DEBUG=.*/APP_DEBUG=false/' /var/www/html/laravel_app/.env + # specify domain, update to use HTTPS + - sed -i -e 's|http://localhost|https://'"$SUBDOMAIN"."$DOMAIN"'|' /var/www/html/laravel_app/.env + # update the laravel DB config + - sed -i -e 's/DB_DATABASE=.*/DB_DATABASE=laravel/' /var/www/html/laravel_app/.env + - sed -i -e 's/DB_USERNAME=.*/DB_USERNAME=laravel_user/' /var/www/html/laravel_app/.env + - sed -i -e 's/DB_PASSWORD=.*/DB_PASSWORD='"$MYSQL_PWD"'/' /var/www/html/laravel_app/.env + - php artisan migrate --force + - chown -R laravel_user:www-data . + - chgrp -R www-data storage bootstrap/cache + - chmod -R ug+rwx storage bootstrap/cache + # activate a basic laravel/php config file for nginx + - mv /home/laravel_nginx_conf /etc/nginx/sites-available/laravel + - sed -i 's/DOMAINPLACEHOLDER/'$SUBDOMAIN"."$DOMAIN'/' /etc/nginx/sites-available/laravel + - ln -s /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/ + - rm /etc/nginx/sites-enabled/default + - systemctl restart nginx + + # install certbot, update + - add-apt-repository ppa:certbot/certbot -y + - apt-get update + - apt install python-certbot-nginx -y + # create a subdomain a-record for this droplet + - 'curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $DO_API_TOKEN" -d "{\"type\":\"A\", \"name\":\"$SUBDOMAIN\", \"data\":\"$PUBLIC_IPV4\"}" https://api.digitalocean.com/v2/domains/$DOMAIN/records' + # run certbot to generate ssl certs, generate dhparams + - certbot --nginx -n -d $SUBDOMAIN"."$DOMAIN --email $EMAIL --agree-tos --redirect --hsts + - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + # write ssl_dhparam directive to nginx config + - sed -i 's/server_name/ssl_dhparam \/etc\/ssl\/certs\/dhparam.pem;\n\tserver_name/' /etc/nginx/sites-available/laravel + - systemctl restart nginx + +write_files: +- path: /etc/cron.d/letsencrypt_renew + content: "15 3 * * * /usr/bin/certbot renew --quiet" +- path: /home/laravel_nginx_conf + content: | + server { + listen 80; + listen [::]:80; + + root /var/www/html/laravel_app/public; + index index.php index.html index.htm index.nginx-debian.html; + + server_name DOMAINPLACEHOLDER; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/run/php/php7.0-fpm.sock; + } + + location ~ /\.ht { + deny all; + } + } + +do_base_images: [ubuntu-16-04-x32, ubuntu-16-04-x64, ubuntu-17-04-x32, ubuntu-17-04-x64] +readme: | + This script starts with an Ubuntu 16.04 or 17.04 server and finishes with a laravel app and mysql database running behind nginx with HTTPS using [cloud-init](https://www.digitalocean.com/community/tutorials/an-introduction-to-cloud-config-scripting). + + + ## Prerequisites: + Before running this, you'll need to: + 1. Configure your domain to [point at DigitalOcean Nameservers](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-host-name-with-digitalocean) + 2. Add your top-level domain _(domain.com, no subdomain)_ in [DigitalOcean control panel](https://cloud.digitalocean.com/networking/domains). + 3. Replace [<%YOUR_TOP_LEVEL_DOMAIN.COM%>](cloud-init.yaml#L16) with your top-level domain (domain.com) + 4. Replace [<%YOUR_DIGITALOCEAN_API_TOKEN%>](cloud-init.yaml#L17) with an API token. [Get one here.](https://cloud.digitalocean.com/settings/api/tokens) + 5. This will use the [laravel quickstart example](https://github.com/laravel/quickstart-basic) app by default, but you can [change the github repo](cloud-init.yaml#L19) to another laravel/mysql app if you like. + + + ## Deploy Plan: + Once prerequisites are met, paste [cloud-init.yaml](cloud-init.yaml) into user-data section on droplet create page. Once booted, server will: + + 1. Install and start [nginx](https://www.digitalocean.com/community/tags/nginx) + 2. Install, configure and run [mysql](https://www.digitalocean.com/community/tags/mysql) + 3. Clone the laravel example app from github, configure and initialize it. + 2. Update DigitalOcean DNS to point a subdomain [this_droplet_name].[your_top_level_domain.com] + at public IPV4 address of this server. + 3. Install and run [Let's Encrypt](https://www.digitalocean.com/community/tags/let-s-encrypt) certbot tool to automatically generate and renew SSL + certificates (allowing magento to run only via HTTPS) + + Install takes ~3 minutes, once server is created you can SSH in and follow progress by running `tail -f /var/log/cloud-init-output.log`. Once install is finished you can go to https://[this_droplet_name].[your_top_level_domain.com] and confirm that the app is running correctly. + + ## Further Reading: + This is meant to be used as scaffolding to get going quickly, it builds on detailed instructions provided in the following tutorials: + - [Install nginx, mysql, php on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04) + - [Install Let's Encrypt (certbot) with nginx on ubuntu](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04) + - [Deploy a Laravel Application on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-laravel-application-with-nginx-on-ubuntu-16-04) diff --git a/Ubuntu-16.04/frameworks/laravel/readme.md b/Ubuntu-16.04/frameworks/laravel/readme.md new file mode 100644 index 0000000..1f822dd --- /dev/null +++ b/Ubuntu-16.04/frameworks/laravel/readme.md @@ -0,0 +1,32 @@ +# Run Laravel, nginx, MySQL, Let's Encrypt on Ubuntu + +This script starts with an Ubuntu 16.04 or 17.04 server and finishes with a laravel app and mysql database running behind nginx with HTTPS using [cloud-init](https://www.digitalocean.com/community/tutorials/an-introduction-to-cloud-config-scripting). + + +## Prerequisites: +Before running this, you'll need to: +1. Configure your domain to [point at DigitalOcean Nameservers](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-host-name-with-digitalocean) +2. Add your top-level domain _(domain.com, no subdomain)_ in [DigitalOcean control panel](https://cloud.digitalocean.com/networking/domains). +3. Replace [<%YOUR_TOP_LEVEL_DOMAIN.COM%>](cloud-init.yaml#L16) with your top-level domain (domain.com) +4. Replace [<%YOUR_DIGITALOCEAN_API_TOKEN%>](cloud-init.yaml#L17) with an API token. [Get one here.](https://cloud.digitalocean.com/settings/api/tokens) +5. This will use the [laravel quickstart example](https://github.com/laravel/quickstart-basic) app by default, but you can [change the github repo](cloud-init.yaml#L19) to another laravel/mysql app if you like. + + +## Deploy Plan: +Once prerequisites are met, paste [cloud-init.yaml](cloud-init.yaml) into user-data section on droplet create page. Once booted, server will: + +1. Install and start [nginx](https://www.digitalocean.com/community/tags/nginx) +2. Install, configure and run [mysql](https://www.digitalocean.com/community/tags/mysql) +3. Clone the laravel example app from github, configure and initialize it. +2. Update DigitalOcean DNS to point a subdomain [this_droplet_name].[your_top_level_domain.com] +at public IPV4 address of this server. +3. Install and run [Let's Encrypt](https://www.digitalocean.com/community/tags/let-s-encrypt) certbot tool to automatically generate and renew SSL +certificates (allowing magento to run only via HTTPS) + +Install takes ~3 minutes, once server is created you can SSH in and follow progress by running `tail -f /var/log/cloud-init-output.log`. Once install is finished you can go to https://[this_droplet_name].[your_top_level_domain.com] and confirm that the app is running correctly. + +## Further Reading: +This is meant to be used as scaffolding to get going quickly, it builds on detailed instructions provided in the following tutorials: +- [Install nginx, mysql, php on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04) +- [Install Let's Encrypt (certbot) with nginx on ubuntu](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04) +- [Deploy a Laravel Application on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-laravel-application-with-nginx-on-ubuntu-16-04)