Skip to content

Instantly share code, notes, and snippets.

@leosuncin
Last active August 5, 2018 05:53
Show Gist options
  • Save leosuncin/681c95f22eecc5524698bc6e8dbe1ea8 to your computer and use it in GitHub Desktop.
Save leosuncin/681c95f22eecc5524698bc6e8dbe1ea8 to your computer and use it in GitHub Desktop.
# El nombre de la aplicacion
APP_NAME=rest-app
# Token de acceso de la API de DigitalOcean
DIGITALOCEAN_ACCESS_TOKEN=
# Region de disponibilidad de DigitalOcean
DIGITALOCEAN_REGION=nyc1
# Nombre de usuario de GitHub
GITHUB_USERNAME=leosuncin
# Token de acceso de GitHub
GITHUB_ACCESS_TOKEN=
# Repositorio de GitHub a clonar
GITHUB_REPOSITORY=https://github.com/jlagneau/demo-rest-api.git

Despliegue automatizado de Symfony 3 a DigitalOcean

Este snippet contiene los archivos necesarios para desplegar una aplicacion Symfony 3 en DigitalOcean utilizando Vagrant. The monolithic way

Requerimientos previos

Ejecucion

Instalar los siguientes plugins para Vagrant:

vagrant plugin install vagrant-digitalocean vagrant-env

Crear un archivo .env a partir del ejemplo .env.dist

cp .env.dist .env

Crear un token de acceso de DigitalOcean y reemplazar DIGITALOCEAN_ACCESS_TOKEN en .env

Crear un token de acceso de GitHub y reemplazar GITHUB_ACCESS_TOKEN en .env

Personalizar el resto de valores en .env

Ejecutar vagrant:

vagrant up --provider=digital_ocean

Solucion de errores comunes

Si da un error de timeout quitar la clave de SSH en DigitalOcean y volver a intentar.

Si la region de disponibilidad tiene problemas se puede obtener una lista con eval $(egrep -v '^#' .env | xargs) vagrant digitalocean-list regions $DIGITALOCEAN_ACCESS_TOKEN y luego cambiar el valor de DIGITALOCEAN_REGION.

<VirtualHost *:80>
ServerSignature Off
DocumentRoot "/var/www/APP_NAME/web/"
DirectoryIndex app.php
<Directory "/var/www/APP_NAME/web">
AllowOverride None
Order Allow,Deny
Allow from All
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
<FilesMatch "(^#.*#|\.(bak|conf|dist|fla|in[ci]|log|orig|psd|sh|sql|sw[op])|~)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>
</Directory>
CustomLog /var/log/apache2/APP_NAME-access.log combined
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 5
AddDefaultCharset utf-8
<IfModule mod_deflate.c>
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE "application/atom+xml" \
"application/javascript" \
"application/json" \
"application/ld+json" \
"application/manifest+json" \
"application/rdf+xml" \
"application/rss+xml" \
"application/schema+json" \
"application/vnd.geo+json" \
"application/vnd.ms-fontobject" \
"application/x-font-ttf" \
"application/x-javascript" \
"application/x-web-app-manifest+json" \
"application/xhtml+xml" \
"application/xml" \
"font/collection" \
"font/eot" \
"font/opentype" \
"font/otf" \
"font/ttf" \
"image/bmp" \
"image/svg+xml" \
"image/vnd.microsoft.icon" \
"image/x-icon" \
"text/cache-manifest" \
"text/calendar" \
"text/css" \
"text/html" \
"text/javascript" \
"text/plain" \
"text/markdown" \
"text/vcard" \
"text/vnd.rim.location.xloc" \
"text/vtt" \
"text/x-component" \
"text/x-cross-domain-policy" \
"text/xml"
</IfModule>
</IfModule>
<IfModule mod_headers.c>
Header append Vary User-Agent env=!dont-vary
Header set X-UA-Compatible "IE=edge"
# `mod_headers` cannot match based on the content-type, however,
# the `X-UA-Compatible` response header should be send only for
# HTML documents and not for the other resources.
<FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ic[os]|jpe?g|m?js|json(ld)?|m4[av]|manifest|map|markdown|md|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$">
Header unset X-UA-Compatible
</FilesMatch>
# Prevent some browsers from MIME-sniffing the response.
#
# This reduces exposure to drive-by download attacks and cross-origin
# data leaks, and should be left uncommented, especially if the server
# is serving user-uploaded content or content that could potentially be
# treated as executable by the browser.
Header set X-Content-Type-Options "nosniff"
# Remove the `X-Powered-By` response header
Header unset X-Powered-By
</IfModule>
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 year"
# Data interchange
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rdf+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/ld+json "access plus 0 seconds"
ExpiresByType application/schema+json "access plus 0 seconds"
ExpiresByType application/vnd.geo+json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/calendar "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
# Favicon (cannot be renamed!) and cursor images
ExpiresByType image/vnd.microsoft.icon "access plus 1 week"
ExpiresByType image/x-icon "access plus 1 week"
# HTML
ExpiresByType text/html "access plus 0 seconds"
# JavaScript
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
# Manifest files
ExpiresByType application/manifest+json "access plus 1 week"
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
ExpiresByType text/cache-manifest "access plus 0 seconds"
# Markdown
ExpiresByType text/markdown "access plus 0 seconds"
# Media files
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType image/bmp "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType image/webp "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# Web fonts
# Collection
ExpiresByType font/collection "access plus 1 month"
# Embedded OpenType (EOT)
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
ExpiresByType font/eot "access plus 1 month"
# OpenType
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType font/otf "access plus 1 month"
# TrueType
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/ttf "access plus 1 month"
# Web Open Font Format (WOFF) 1.0
ExpiresByType application/font-woff "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType font/woff "access plus 1 month"
# Web Open Font Format (WOFF) 2.0
ExpiresByType application/font-woff2 "access plus 1 month"
ExpiresByType font/woff2 "access plus 1 month"
# Other
ExpiresByType text/x-cross-domain-policy "access plus 1 week"
</IfModule>
</VirtualHost>
#!/bin/bash
set -eo pipefail
export MYSQL_DATABASE=${MYSQL_DATABASE:-bd_ds_erp}
export MYSQL_USER=${MYSQL_USER:-root}
export MYSQL_ROOT_PASSWORD=$(grep root_mysql_pass= /root/.digitalocean_password | grep -oP '(?<=").*(?=")')
export DEBIAN_FRONTEND=noninteractive
export COMPOSER_ALLOW_SUPERUSER=1
# Actualizar el sistema
apt-get update -yqq
apt-get dist-upgrade -yqq
# Instala programas basicos y extensiones de PHP
apt-get install -yqq htop byobu rsync git acl\
php-mbstring php-intl php-zip php-xml php-json
# Instala Micro editor
(
cd /usr/local/bin
curl https://getmic.ro | bash
)
# Instala NetData
bash <(curl -Ss https://my-netdata.io/kickstart.sh) all --dont-wait --auto-update
sed -i "\$i echo 1 > /sys/kernel/mm/ksm/run" /etc/rc.local
echo 1 > /sys/kernel/mm/ksm/run
sed -i "\$i echo 1000 > /sys/kernel/mm/ksm/sleep_millisecs\n" /etc/rc.local
echo 1000 > /sys/kernel/mm/ksm/sleep_millisecs
# Instala composer
(
curl --silent --fail --location --retry 3 --output /tmp/composer-installer.php --url https://getcomposer.org/installer
php /tmp/composer-installer.php --no-ansi --install-dir=/usr/local/bin --filename=composer
)
# Cambia la zona horaria
ln -snf /usr/share/zoneinfo/America/El_Salvador /etc/localtime
echo "America/El_Salvador" > /etc/timezone
sed -i -e "s/;date.timezone\s*=.*/date.timezone = America\/El_Salvador/" /etc/php/7.0/cli/php.ini
sed -i -e "s/;date.timezone\s*=.*/date.timezone = America\/El_Salvador/" /etc/php/7.0/apache2/php.ini
# Configura la autenticacion basica
echo "machine github.com
login $GITHUB_USERNAME
password $GITHUB_ACCESS_TOKEN
machine api.github.com
login $GITHUB_USERNAME
password $GITHUB_ACCESS_TOKEN" >> ~/.netrc && chmod 600 ~/.netrc
# Configura la autenticacion por SSH
if [[ ! -z $SSH_PRIVATE_KEY ]]; then
eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan github.com > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
fi
# Habilita modulos de Apache
a2enmod deflate expires filter headers include mime rewrite setenvif
# Copia el archivo de configuracion de Apache
sed -e "s/APP_NAME/$APP_NAME/g" /vagrant/symfony.conf > /etc/apache2/sites-available/$APP_NAME.conf
# Deshabilita el sitio por defecto
a2dissite 000-default
# Habilita el sitio de la aplicacion
a2ensite $APP_NAME
# Clona el repositorio
git clone $GITHUB_REPOSITORY /var/www/$APP_NAME && cd $_
# Genera el archivo de configuracion
echo "parameters:
database_host: 127.0.0.1
database_port: null
database_name: $MYSQL_DATABASE
database_user: $MYSQL_USER
database_password: $MYSQL_ROOT_PASSWORD
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
secret: $(sha256sum composer.json | cut -d ' ' -f 1)" > app/config/parameters.yml
# Instala las dependencias
composer install -o -n --no-progress --no-scripts --no-dev
# Arregla los permisos de los archivos
chown -R www-data:www-data /var/www/$APP_NAME
setfacl -R -m u:www-data:rX /var/www/$APP_NAME
setfacl -R -m u:www-data:rwX /var/www/$APP_NAME/var
setfacl -dR -m u:www-data:rwX /var/www/$APP_NAME/var
# Restaura un backup de la BD si existiera
if [[ -f /vagrant/$APP_NAME.sql ]]; then
mysql -u $MYSQL_USER -p$MYSQL_ROOT_PASSWORD $MYSQL_DATABASE < /vagrant/$APP_NAME.sql
# else
# php bin/console doctrine:database:create -n -e prod
# php bin/console doctrine:migration:migrate -n -e prod
fi
# Verifica la configuracion de Apache y reinicia Apache
apachectl configtest && systemctl restart apache2
# Crea un cronjob para realizar backups de la BD
mkdir -p /var/backup && chmod 777 $_
echo "0 22 * * * mysqldump --add-drop-table -u $MYSQL_USER -p$MYSQL_ROOT_PASSWORD --database $MYSQL_DATABASE | gzip > /var/backup/$MYSQL_DATABASE-\`date +%Y.%m.%d\`.sql.gz" | crontab -
Vagrant.configure("2") do |config|
config.env.enable
config.vm.define "#{ENV['APP_NAME']}-vps" do |vps|
vps.vm.provision "shell" do |s|
s.path = "vagrant-provision.sh"
s.env = {
"APP_NAME" => ENV["APP_NAME"],
"GITHUB_USERNAME" => ENV['GITHUB_USERNAME'],
"GITHUB_ACCESS_TOKEN" => ENV['GITHUB_ACCESS_TOKEN'],
"GITHUB_REPOSITORY" => ENV["GITHUB_REPOSITORY"]
}
end
vps.vm.provider :digital_ocean do |provider, override|
override.ssh.private_key_path = "~/.ssh/id_rsa"
override.vm.box = "digital_ocean"
override.vm.box_url = "https://github.com/devopsgroup-io/vagrant-digitalocean/raw/master/box/digital_ocean.box"
override.nfs.functional = false
provider.private_networking = true
provider.monitoring = true
provider.token = ENV["DIGITALOCEAN_ACCESS_TOKEN"]
provider.image = "lamp-16-04"
provider.region = ENV["DIGITALOCEAN_REGION"]
provider.size = "1gb"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment