Laravel Sail SQL Server en remoto

Configurar el acceso desde Laravel a una segunda base de datos, en SQL Server Express en un servidor remoto.

Primero configuramos la instancia de SQL Server para que sea accesible de forma remota:

Acceso a SQL Server con usuario y contraseña

Con Microsoft SQL Server Management Studio, propiedades del servidor -> Security -> Server authentication, activamos la opción SQL Server and Windows Authentication Mode.

A continuación reiniciamos el servicio SQL Server(SQLEXPRESS), desde Servicios de Windows o desde SQL Server Configuration Manager.

Creamos un usuario y contraseña para acceder a SQL Server:

Establecemos el nombre de usuario (Login name), y marcamos la opción SQL Server authenticacion. A continuación establecemos una contraseña segura y desmarcamos la opción Enforce password policy

Configurar el Firewall de Windows

A continuación abrimos el Firewall de Windows, Configuración Avanzada y creamos una nueva Regla de Entrada, de puerto, TCP, 2021, por no usar el puerto por defecto 1433, por motivos de seguridad.

Las siguientes pantallas las dejamos por defecto «Permitir conexión» y en la siguiente todas las opciones marcadas, en la última pantalla ponemos el nombre que queramos, por ejemplo, SQL Server remote.

Si vamos a acceder desde fuera de la red doméstica debemos añadir un puerto NAT TCP

Permitir a SQL Server recibir llamadas remotas

En el SQL Server Configuration Manager, en la opción SQL Server Network Configuration -> Protocols for SQLEXPRESS activamos TCP/IP

Y configuramos para leer las direcciones IP, pudiendo seleccionar una IP en concreto y marcar como Habilitado, o si tenemos la dirección IP por DHCP, podemos seleccionar la ultima opción IPAll, y establecer el puerto que estamos utilizando, en este caso 2021.

A continuación reiniciamos el servicio SQL Server (SQLEXPRESS)

Conectar a la BBDD en remoto

Ahora ya podemos acceder al servidor de forma remota, para comprobarlo desde el Microsoft SQL Server Management Studio, especificando ip,puerto usuario y contraseña.

Preparar el archivo Dockerfile

Publicamos el archivo Dockerfile:

sail artisan sail:publish

Este comando crea los archivos Dockerfile en la raíz del proyecto. Modificamos el correspondiente a la versión que estamos utilizando, la que especifica docker-compose.yml

En la configuración del Dockerfile he añadido la configuración necesaria para instalar los drivers para que Linux acceda a SQL Server, unixodbc, msodbcsql17, mssql-tools, sqlsrv, pdo_sqlsrv. La parte en negrita es la que se ha añadido.

FROM ubuntu:20.04

LABEL maintainer="Taylor Otwell"

ARG WWWGROUP
ARG NODE_VERSION=16
ARG POSTGRES_VERSION=13

WORKDIR /var/www/html

ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC

SHELL ["/bin/bash", "-c"]

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update \
    && apt-get install -y unixodbc \
    && apt-get install -y unixodbc-dev \
    && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 dnsutils \
    && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \
    && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu focal main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
    && apt-get update \
...
    && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
    && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt focal-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
    && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
    && curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && apt-get install -y yarn \
    && apt-get install -y mysql-client \
    && apt-get install -y postgresql-client-$POSTGRES_VERSION \
    && ACCEPT_EULA=Y apt-get install -y msodbcsql17 \
    && ACCEPT_EULA=Y apt-get install -y mssql-tools \
    && apt-get install -y gcc \
       musl-dev \
       make \
    && apt-get -y autoremove \
...
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail

RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
RUN source ~/.bashrc

RUN pecl install sqlsrv
RUN pecl install pdo_sqlsrv

RUN printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/8.0/mods-available/sqlsrv.ini
RUN printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/8.0/mods-available/pdo_sqlsrv.ini
RUN phpenmod sqlsrv pdo_sqlsrv

COPY start-container /usr/local/bin/start-container
...

A continuación recompilamos el Dockerfile

sail build --no-cache

Segunda BD en Laravel

Configuramos en el archivo .env los datos de acceso para una segunda Base de Datos.

...
DB_HOST_SS=10.20.10.120
DB_PORT_SS=2021
DB_DATABASE_SS=NOM_BD
DB_USERNAME_SS=usuario
DB_PASSWORD_SS=contraseña
...

Y los leemos desde la configuración de bases de datos de Laravel config\database.php

        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST_SS', 'localhost'),
            'port' => env('DB_PORT_SS', '1433'),
            'database' => env('DB_DATABASE_SS', 'forge'),
            'username' => env('DB_USERNAME_SS', 'forge'),
            'password' => env('DB_PASSWORD_SS', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
            // 'encrypt' => env('DB_ENCRYPT', 'yes'),
            // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
        ],

Para testear si funciona la conexión, podemos establecer una ruta en routes\web.php



Route::get('/pruebaBD', function() {
    dd(DB::connection('sqlsrv')->getPdo());
});

Una vez que está todo funcionando, podemos acceder a esa base de datos de distintas maneras, incluso utilizando Eloquent

$users = DB::connection('mysql2')->select(...);

...

Schema::connection('mysql2')->create('some_table', function($table)
{
    $table->increments('id'):
});

...

class SomeModel extends Eloquent {

    protected $connection = 'mysql2';

}

...

class SomeController extends BaseController {

    public function someMethod()
    {
        $someModel = new SomeModel;

        $someModel->setConnection('mysql2');

        $something = $someModel->find(1);

        return $something;
    }

}

Referencias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *