Despliegue de una aplicación en Laravel 7 en Ubuntu & Nginx.

Despliegue de una aplicación en Laravel 7 en Ubuntu & Nginx

He decidido crear mi portafolio en Laravel 7. Quiero que la página principal sea una landing page y que toda la información en ella se pueda cambiar a través del panel de administración. No es el punto. Llegamos al despliegue. Encontré un par de buenos tutoriales sobre cómo hacerlo en un servidor completo con todas las complicaciones. No soy muy fuerte en despliegue, soy más de frontend que de fullstack. Si puedo programar y probar en PHP, aún no he llegado a gestionar servidores, etc. Pero tuve que aprender.

Ahora vamos a recorrer todos los pasos, desde el inicio a través de SSH hasta tener un sitio web funcional. Intentaremos evitar todos los escollos.

Es posible que encuentres instrucciones similares en Internet. Después de todo, yo las encontré. Aunque no en un solo lugar y no sin la ayuda de StackOverflow, y probablemente no en ruso. Pasé un tiempo investigando. Así que decidí simplificarte la vida.

Todo lo haremos con un droplet en DigitalOcean. Esto no es obligatorio, puedes elegir cualquier alojamiento. Cuando llegues a un servidor funcional con Ubuntu, vuelve aquí. Para aquellos que decidan hacerlo en DigitalOcean, también habrá consejos sobre la configuración del dominio. Además, un enlace de referencia para $100..

Todos los pasos específicos de DigitalOcean se darán en notas al pie similares.

Empecemos.

TL;DR (solo los comandos principales)

Creamos el usuario

  • ssh root@[IP-de-tu-droplet]
  • adduser laravel
  • usermod -aG sudo laravel
  • su laravel

Agregamos su SSH

  • mkdir ~/.ssh
  • chmod 700 ~/.ssh
  • vim ~/.ssh/authorized_keys
  • Insertamos la clave pública
  • chmod 600 ~/.ssh/authorized_keys

Cortafuegos

  • sudo ufw allow OpenSSH
  • sudo ufw enable
  • sudo ufw status

Nginx

  • sudo apt update
  • sudo apt install -y nginx
  • sudo ufw allow 'Nginx HTTP'
  • sudo ufw status

MySQL

  • sudo apt install -y mysql-server
  • sudo mysql_secure_installation, NYNNY
  • sudo mysql
  • ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
  • SELECT user,authentication_string,plugin,host FROM mysql.user;
  • FLUSH PRIVILEGES;
  • exit

PHP

  • sudo apt update

  • sudo apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https

  • sudo apt-add-repository ppa:ondrej/php

  • sudo apt update

  • 7.3: sudo apt install -y php7.3-fpm php7.3-mysql

  • 7.4: sudo apt install -y php7.4-fpm php7.4-mysql

  • sudo vim /etc/nginx/sites-available/

Configuración básica:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name ;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ .php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }

        location ~ /.ht {
                deny all;
        }
}

Solo la configuración HTTP para Laravel:

servidor {
    escuchar 80;
    escuchar [::]:80;

    raíz /var/www/html//public;
    índice index.php index.html index.htm index.nginx-debian.html;

    server_name ;

    ubicación / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    ubicación ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    ubicación ~ /.ht {
        negar todo;
    }
}

Configuración de HTTPS para Laravel:

servidor {
    escuchar 80;
    escuchar [::]:80;

    server_name  www.;
    return 301 https://$server_name$request_uri;
}

servidor {
    escuchar 443 ssl http2;
    escuchar [::]:443 ssl http2;
    server_name  www.;
    raíz /var/www/html//public;

    ssl_certificate /etc/letsencrypt/live//fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live//privkey.pem;

    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    índice index.php index.html index.htm index.nginx-debian.html;

    charset utf-8;

    ubicación / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    ubicación ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    ubicación ~ /.ht {
            negar todo;
    }

    ubicación ~ /.well-known {
            permitir todo;
    }
}

  • sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
  • sudo unlink /etc/nginx/sites-enabled/default
  • sudo nginx -t
  • sudo systemctl reload nginx

Laravel

  • 7.3: sudo apt install -y php7.3-mbstring php7.3-xml composer unzip

  • 7.4: sudo apt install -y php7.4-mbstring php7.4-xml composer unzip

  • mysql -u root -p

  • CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

  • GRANT ALL ON laravel.* TO 'root'@'localhost' IDENTIFIED BY '';

  • FLUSH PRIVILEGES;

  • exit

  • cd /var/www/html

  • sudo mkdir -p

  • sudo chown laravel:laravel

  • cd ./

  • git clone . / git clone -b --single-branch .

  • composer install

  • vim .env

APP_NAME=Laravel
APP_ENV=producción
APP_KEY=
APP_DEBUG=false
APP_URL=http://

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

  • php artisan migrate

  • php artisan key:generate

  • sudo chown -R $USER:www-data storage

  • sudo chown -R $USER:www-data bootstrap/cache

  • chmod -R 775 storage

  • chmod -R 775 bootstrap/cache

HTTPS

  • sudo add-apt-repository ppa:certbot/certbot

  • sudo apt install -y python-certbot-nginx

  • sudo certbot certonly --webroot --webroot-path=/var/www/html//public -d -d www.

  • sudo nginx -t

  • sudo ufw allow 'Nginx HTTPS'

  • sudo ufw status

  • sudo systemctl reload nginx

Creamos un droplet en DigitalOcean y registramos una nueva clave SSH

Confío en que encontrarás la manera de registrarte en DigitalOcean. No es fácil, con muchas verificaciones y demás. Si tienes problemas de red al verificar con documentos, intenta hacerlo con una VPN, debería ayudar.

En el menú superior, hacemos clic en Crear->Droplets. Seleccionamos Ubuntu.

Una vez que te registres, recibirás $100 en tu cuenta. Pero no te engañes. Solo tienes 60 días para gastarlos. Lo cual es muy poco. Puedes, como yo, querer usar un plan más caro, y luego, cuando empiecen a entrar dinero real, cambiar a uno más barato. Te lo digo de inmediato, no funcionará. Puedes aumentar, pero no disminuir. Así están las cosas. Yo elijo Estándar->$5.

Elijo la región más cercana a nosotros Fráncfort. Red VPC->default-fra1

Haremos la autenticación a través de SSH. Hacemos clic en Nueva clave SSH. Si no tienes SSH, a la derecha hay una guía muy sencilla. Abrimos la terminal bash, pegamos ssh-keygen. Luego accedemos al archivo con la clave pública /Users/<Ваше имя пользователя>/.ssh/id_rsa.pub (o simplemente cat ~/\.ssh/id_rsa.pub), copiamos el contenido y lo pegamos en la ventana a la izquierda. Puedes elegir el nombre.

Inventamos un nombre de host para el droplet.

Hacemos clic en Crear Droplet

Creamos un nuevo usuario

  • ssh root@[IP-de-tu-droplet]
  • ¿Estás seguro de que deseas continuar con la conexión (sí/no/[huella dactilar])? yes
  • Ingresa tu contraseña de SSH
  • Creamos el usuario laravel: adduser laravel
  • Ingresa la contraseña y otra información (yo solo ingreso el nombre completo)
  • Agregamos el usuario al grupo sudo: usermod -aG sudo laravel

SSH para el nuevo usuario

  • Cambiamos al nuevo usuario: su laravel

Todas las acciones a partir de aquí, hasta el final del artículo, las realizamos en nombre del usuario laravel. Por lo tanto, si te interrumpiste, vuelve a ingresar e introduce su laravel

  • mkdir ~/.ssh
  • chmod 700 ~/.ssh
  • vim ~/.ssh/authorized_keys

Hemos abierto el archivo en Vim. Si no estás familiarizado con él, puedes trabajar en Nano, es tu elección.

Los comandos más básicos de Vim

Para usar el editor Vim a lo largo del artículo, solo necesitas saber lo siguiente.

  • En Vim hay diferentes modos: modo normal (Normal mode), en el que ingresas comandos y seleccionas modos, y otros.
  • Para salir de cualquier modo y entrar en modo normal, simplemente presiona Esc
  • Navegar: puedes simplemente usar las flechas
  • Salir sin guardar <Normal mode>: :q!
  • Salir y guardar <Normal mode>: :wq
  • Entrar en modo de inserción de texto <Normal mode>: i (de inglés insert)
  • Insertamos nuestra clave pública (que hicimos arriba)
  • Proteger de cambios: chmod 600 ~/.ssh/authorized_keys

Instalamos el firewall

  • Vemos todas las configuraciones disponibles: sudo ufw app list
  • Permitimos OpenSSH (de lo contrario, nos bloqueará): sudo ufw allow OpenSSH
  • Iniciamos el firewall: sudo ufw enable, y
  • Verificando: sudo ufw status

Estado: activo

Para                         Acción      Desde
--                         ------      ----
OpenSSH                    PERMITIR    En cualquier lugar
OpenSSH (v6)               PERMITIR    En cualquier lugar (v6)

Todo está en orden.

Instalamos Nginx

Durante la instalación a veces te preguntarán "¿Estás seguro?" Responde y (solo si estás seguro).

  • sudo apt update
  • sudo apt install nginx

Agregamos Nginx a la configuración del firewall

  • sudo ufw app list
  • sudo ufw allow 'Nginx HTTP'
  • sudo ufw status

Estado: activo

Para                         Acción      Desde
--                         ------      ----
OpenSSH                    PERMITIR    En todas partes
Nginx HTTP                 PERMITIR    En todas partes
OpenSSH (v6)               PERMITIR    En todas partes (v6)
Nginx HTTP (v6)            PERMITIR    En todas partes (v6)

Acceda a su IP. Si todo va bien, debería ver lo siguiente.

Despliegue de una aplicación en Laravel 7 en Ubuntu & Nginx

Instalando MySQL

  • sudo apt install mysql-server
  • Ejecutamos el script automático de protección sudo mysql_secure_installation

Responda a las preguntas planteadas. Si no sabe qué responder, aquí hay opciones recomendadas:

  • Plugin de validación de contraseña — N

  • ¿Eliminar usuarios anónimos? — Y

  • ¿Prohibir el acceso remoto a root? — N

  • ¿Eliminar la base de datos de prueba y el acceso a ella? — N

  • ¿Recargar las tablas de privilegios ahora? — Y

  • Entramos en MySQL: sudo mysql

  • Revisamos los métodos de acceso: SELECT user,authentication_string,plugin,host FROM mysql.user;

  • Establecemos una contraseña para root: ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';

  • Revisamos los métodos de acceso de nuevo: SELECT user,authentication_string,plugin,host FROM mysql.user;

  • Aplicamos los cambios y salimos de MySQL: FLUSH PRIVILEGES; y exit

  • Ahora, para ingresar a MySQL, debe usar mysql -u root -p e introducir la contraseña

Instalamos PHP

Usaremos un repositorio externo de Ondřej Surý

  • sudo apt update
  • sudo apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https
  • sudo apt-add-repository ppa:ondrej/php
  • sudo apt update

Ahora seleccionamos. Para Laravel 7 se puede elegir PHP 7.3 o 7.4. La diferencia será solo en los números 3 y 4.

  • 7.3: sudo apt install -y php7.3-fpm php7.3-mysql
  • 7.4: sudo apt install -y php7.4-fpm php7.4-mysql

PHP FastCGI Process Manager (fpm) trabaja con solicitudes PHP. mysql, por supuesto, es para trabajar con MySQL.

A partir de ahora haré todo con la versión 7.4.

Configuramos Nginx

  • sudo vim /etc/nginx/sites-available/

En lugar de "<Su dominio>" escriba el dominio (por ejemplo, mysite.ru), que desea utilizar en el futuro. Si aún no tiene uno, escriba cualquier cosa, luego repita las acciones en este capítulo para su dominio cuando lo elija.

Escribimos lo siguiente:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name ;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ .php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }

        location ~ /.ht {
                deny all;
        }
}

Si eligió la versión 7.3 en lugar de php7.4-fpm.sock escriba php7.4-fpm.sock.

Escuchamos el puerto 80 en server_name, cuando recibimos una solicitud en la raíz /var/www/html tomamos el archivo index. Si después server_name hay algo, buscamos ese archivo. Si no lo encontramos, lanzamos un 404. Si termina en .php, lo pasamos a través de fpm. Si hay .ht, lo prohibimos (403).

  • Hacemos un enlace de sites-available en sites-enabled: sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
  • Eliminamos el enlace a default: sudo unlink /etc/nginx/sites-enabled/default
  • Comprobamos errores: sudo nginx -t
  • Reiniciamos: sudo systemctl reload nginx

Verificamos el funcionamiento:

  • sudo vim /var/www/html/info.php
  • Escribimos: <php phpinfo();
  • Accedemos a <Su IP>/info.php

Debería ver algo similar:

Despliegue de una aplicación en Laravel 7 en Ubuntu & Nginx

Ahora este archivo se puede eliminar: sudo rm /var/www/html/info.php

Instalamos Laravel

  • 7.3: sudo apt install php7.3-mbstring php7.3-xml composer unzip

  • 7.4: sudo apt install php7.4-mbstring php7.4-xml composer unzip

  • Entramos en MySQL: mysql -u root -p

  • Creamos una base de datos con el nombre laravel: CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

  • Otorgamos acceso root a laravel: GRANT ALL ON laravel.* TO 'root'@'localhost' IDENTIFIED BY '';

  • FLUSH PRIVILEGES;

  • exit

  • cd /var/www/html

  • Creamos una carpeta para el proyecto: sudo mkdir -p

  • Le otorgamos al usuario laravel permisos sobre el proyecto: sudo chown laravel:laravel

A continuación, necesitamos transferir el proyecto. Por ejemplo, clonándolo desde Github.

  • cd ./
  • git clone .

Deben tenerse en cuenta que, si no ha guardado los archivos estáticos (por ejemplo, de /public) en Github, evidentemente no los tendrá. Yo, por ejemplo, para resolver esto, creé una rama separada deploy, desde la que ya cloné: git clone -b --single-branch ..

  • Instalamos las dependencias: composer install
  • Creamos .env: vim .env

La versión básica se ve así:

APP_NAME=Laravel
APP_ENV=producción
APP_KEY=
APP_DEBUG=false
APP_URL=http://

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

Si copias tu .env, reemplaza APP_ENV por production, APP_DEBUG por false y escribe las configuraciones correctas para MySQL.

  • Migramos la base de datos: php artisan migrate
  • Generamos el código: php artisan key:generate

Cambiamos los permisos:

  • sudo chown -R $USER:www-data storage
  • sudo chown -R $USER:www-data bootstrap/cache
  • chmod -R 775 storage
  • chmod -R 775 bootstrap/cache

Lo último que queda es reconfigurar Nginx para Laravel:

sudo vim /etc/nginx/sites-available/

servidor {
    escuchar 80;
    escuchar [::]:80;

    raíz /var/www/html//public;
    índice index.php index.html index.htm index.nginx-debian.html;

    server_name ;

    ubicación / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    ubicación ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    ubicación ~ /.ht {
        negar todo;
    }
}

Como la vez pasada, si elegiste la versión 7.3 en lugar de php7.4-fpm.sock escriba php7.4-fpm.sock.

Configuración del dominio en DigitalOcean

Todo es realmente muy sencillo. Compras un dominio (en cualquier lugar), vas a DigitalOcean en Crear->Domains/DNS. En el campo Añadir un dominio escribes este dominio, haces clic en añadir. Luego, accedes a la configuración del dominio y en el campo HOSTNAME escribes @. Seleccionas el proyecto y haces clic en Crear registro.
Ahora ve al sitio donde compraste el dominio, busca allí 'Servidores DNS' (o algo similar) y escribe los servidores de DigitalOcean (específicamente ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com). Ahora tendrás que esperar un poco (o mucho) hasta que estas configuraciones sean aceptadas. ¡Listo!
El único problema es que tu sitio solo se abrirá como HTTP. Para tener HTTPS, pasamos a la siguiente parte.

Configuramos HTTPS

Instalamos certbot y le pasamos el nombre del dominio (en formato mysite.ru) y el nombre del dominio con www (www.mysite.ru).

  • sudo add-apt-repository ppa:certbot/certbot
  • sudo apt install python-certbot-nginx
  • sudo certbot certonly --webroot --webroot-path=/var/www/html//public -d -d www.

Ahora es necesario reconfigurar Nginx (no olvides poner tus valores):

servidor {
    escuchar 80;
    escuchar [::]:80;

    server_name  www.;
    return 301 https://$server_name$request_uri;
}

servidor {
    escuchar 443 ssl http2;
    escuchar [::]:443 ssl http2;
    server_name  www.;
    raíz /var/www/html//public;

    ssl_certificate /etc/letsencrypt/live//fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live//privkey.pem;

    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    índice index.php index.html index.htm index.nginx-debian.html;

    charset utf-8;

    ubicación / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    ubicación ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    ubicación ~ /.ht {
            negar todo;
    }

    ubicación ~ /.well-known {
            permitir todo;
    }
}

Creo que ya entendiste qué necesitas cambiar para PHP 7.3.

En realidad, aquí todo es sencillo. Simplemente redirigimos todas las solicitudes de HTTP (puerto 80) a HTTPS (puerto 443). Y allá hacemos lo mismo que antes, pero con cifrado.

Solo queda establecer los permisos en el firewall:

  • sudo nginx -t
  • sudo ufw app list
  • sudo ufw allow 'Nginx HTTPS'
  • sudo ufw status
  • sudo systemctl reload nginx

Ahora todo debería funcionar como se espera.

[Дополнительно] Установка Node.js

Si en algún momento necesitas ejecutar comandos npm directamente en el servidor, debes instalar Node.js.

  • sudo apt update
  • sudo apt install -y nodejs npm
  • nodejs -v

Eso es todo, me detuve en esta etapa. En principio, estoy satisfecho con el resultado. Puede que me mude de DigitalOcean a algún lugar más cerca de Rusia y más barato. Pero como ya pasé por todos los procesos de verificación en el sitio y lo hice allí, me mostré con su ejemplo. Además, sus 100 dólares de inicio son una gran plataforma para entrenar.

P.S. Un agradecimiento especial al autor de este gist, que sirvió de base para todas las acciones mencionadas anteriormente. En algunos puntos no funciona para Laravel 7, eso lo corregí.

P.P.S. Si eres un ingeniero destacado que piensa en comandos de bash, por favor, no seas muy crítico. Puede que este artículo te parezca básico, pero me habría alegrado encontrar algo así cuando lo necesitaba. Si tienes sugerencias para mejorar, estoy completamente "a favor".

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster