Skip to content

Commit

Permalink
[1.x] Adds Microsoft SQL Server
Browse files Browse the repository at this point in the history
  • Loading branch information
Italo Israel Baeza Cabrera committed Aug 17, 2024
1 parent 039c2ad commit 321f30b
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 5 deletions.
14 changes: 14 additions & 0 deletions bin/sail
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function display_help {
echo " ${GREEN}sail mysql${NC} Start a MySQL CLI session within the 'mysql' container"
echo " ${GREEN}sail mariadb${NC} Start a MySQL CLI session within the 'mariadb' container"
echo " ${GREEN}sail psql${NC} Start a PostgreSQL CLI session within the 'pgsql' container"
echo " ${GREEN}sail sqlsrv${NC} Start a Microsoft SQL Server CLI session within the 'sqlsrv' container"
echo " ${GREEN}sail redis${NC} Start a Redis CLI session within the 'redis' container"
echo
echo "${YELLOW}Debugging:${NC}"
Expand Down Expand Up @@ -500,6 +501,19 @@ elif [ "$1" == "psql" ]; then
sail_is_not_running
fi

# Initiate a Microsoft SQL Server CLI terminal session within the "sqlsrv" container...
elif [ "$1" == "sqlsrv" ]; then
shift 1

if [ "$EXEC" == "yes" ]; then
ARGS+=(exec)
[ ! -t 0 ] && ARGS+=(-T)
ARGS+=(sqlcmd bash -c)
ARGS+=("sqlcmd -No -d \${MSSQL_DB_NAME} -P \${MSSQL_PASSWORD} -U \${MSSQL_USER}")
else
sail_is_not_running
fi

# Initiate a Bash shell within the application container...
elif [ "$1" == "shell" ] || [ "$1" == "bash" ]; then
shift 1
Expand Down
92 changes: 92 additions & 0 deletions database/sqlsrv/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env bash

# If there is a command, execute it.
if [ "$#" -ne 0 ]; then
exec "$@"
fi

SQLCMD="/opt/mssql-tools/bin/sqlcmd"

if [ -f /opt/mssql-tools18/bin/sqlcmd ]; then
SQLCMD="/opt/mssql-tools18/bin/sqlcmd"
fi

echo "Laravel Sail: Starting Microsoft SQL Server for init scripts."

# Start SQL Server
/opt/mssql/bin/sqlservr -mSQLCMD -f -c -x &

# Function to check if SQL Server is ready
sql_server_is_ready() {
$SQLCMD -No -U sa -P "${MSSQL_SA_PASSWORD}" -Q "SELECT 1" &> /dev/null
return $?
}

# Wait until SQL Server is ready
until sql_server_is_ready; do
echo "Laravel Sail: Waiting for SQL Server to be available..."
sleep 2
done

SQL_INIT=$(cat <<-EOSQL
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = "$MSSQL_DB_NAME") BEGIN
CREATE DATABASE $MSSQL_DB_NAME;
END
GO
IF NOT EXISTS (SELECT name FROM master.sys.server_principals WHERE name = "$MSSQL_USER") BEGIN
CREATE LOGIN $MSSQL_USER WITH
PASSWORD = "$MSSQL_PASSWORD",
DEFAULT_DATABASE = $MSSQL_DB_NAME,
CHECK_EXPIRATION = OFF,
CHECK_POLICY = OFF;
END
GO
IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE name = "$MSSQL_USER") BEGIN
CREATE USER $MSSQL_USER FOR LOGIN $MSSQL_USER;
ALTER ROLE db_owner ADD MEMBER $MSSQL_USER;
END
GO
EOSQL
)

echo "Laravel Sail: Initializing ${MSSQL_DB_NAME} database for ${MSSQL_USER}."

## Set the engine default user and database name
$SQLCMD -No -U sa -No -P "${MSSQL_SA_PASSWORD}" -Q "${SQL_INIT}"

SQL_INIT_TESTING=$(cat <<-EOSQL
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = "testing") BEGIN
CREATE DATABASE testing;
END
GO
IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE name = "testing") BEGIN
CREATE USER testing FOR LOGIN testing WITH
PASSWORD = "",
DEFAULT_DATABASE = "testing",
CHECK_EXPIRATION = OFF,
CHECK_POLICY = OFF;
ALTER ROLE db_datareader ADD MEMBER testing;
ALTER ROLE db_datawriter ADD MEMBER testing;
ALTER ROLE db_ddladmin ADD MEMBER testing;
END
GO
EOSQL
)

echo "Laravel Sail: Initializing testing database."

## Create the testing database if it doesn't exists
$SQLCMD -No -U sa -P "${MSSQL_SA_PASSWORD}" -Q "${SQL_INIT_TESTING}"

echo "Laravel Sail: Stopping Microsoft SQL Server for init scripts."

# Kill the server
pkill sqlservr

echo "Laravel Sail: Starting Microsoft SQL Server."

# Start it again.
exec /opt/mssql/bin/sqlservr
18 changes: 18 additions & 0 deletions runtimes/8.0/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=20
ARG POSTGRES_VERSION=13
ARG SQLSRV_VERSION=5.11.1
ARG ACCEPT_EULA="N"

WORKDIR /var/www/html

Expand Down Expand Up @@ -48,6 +50,22 @@ RUN apt-get update \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN if [ "$ACCEPT_EULA" = "Y" ]; then \
curl -sS https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc \
&& curl -sS https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& apt-get install -y mssql-tools18 unixodbc-dev \
&& echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc \
&& pecl install sqlsrv pdo_sqlsrv-$SQLSRV_VERSION \
&& printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/8.0/mods-available/sqlsrv.ini \
&& printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/8.0/mods-available/pdo_sqlsrv.ini \
&& phpenmod sqlsrv pdo_sqlsrv \
&& bash -c "source ~/.bashrc" \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \
fi

RUN update-alternatives --set php /usr/bin/php8.0

RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.0
Expand Down
18 changes: 18 additions & 0 deletions runtimes/8.1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=20
ARG POSTGRES_VERSION=15
ARG SQLSRV_VERSION=5.12.0
ARG ACCEPT_EULA="N"

WORKDIR /var/www/html

Expand Down Expand Up @@ -49,6 +51,22 @@ RUN apt-get update \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN if [ "$ACCEPT_EULA" = "Y" ]; then \
curl -sS https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc \
&& curl -sS https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& apt-get install -y mssql-tools18 unixodbc-dev \
&& echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc \
&& pecl install sqlsrv pdo_sqlsrv-$SQLSRV_VERSION \
&& printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/8.1/mods-available/sqlsrv.ini \
&& printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/8.1/mods-available/pdo_sqlsrv.ini \
&& phpenmod sqlsrv pdo_sqlsrv \
&& bash -c "source ~/.bashrc" \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \
fi

RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1

RUN groupadd --force -g $WWWGROUP sail
Expand Down
18 changes: 18 additions & 0 deletions runtimes/8.2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ LABEL maintainer="Taylor Otwell"
ARG WWWGROUP
ARG NODE_VERSION=20
ARG POSTGRES_VERSION=15
ARG SQLSRV_VERSION=5.12.0
ARG ACCEPT_EULA="N"

WORKDIR /var/www/html

Expand Down Expand Up @@ -50,6 +52,22 @@ RUN apt-get update \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN if [ "$ACCEPT_EULA" = "Y" ]; then \
curl -sS https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc \
&& curl -sS https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& apt-get install -y mssql-tools18 unixodbc-dev \
&& echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc \
&& pecl install sqlsrv pdo_sqlsrv-$SQLSRV_VERSION \
&& printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/8.2/mods-available/sqlsrv.ini \
&& printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/8.2/mods-available/pdo_sqlsrv.ini \
&& phpenmod sqlsrv pdo_sqlsrv \
&& bash -c "source ~/.bashrc" \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \
fi

RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2

RUN groupadd --force -g $WWWGROUP sail
Expand Down
18 changes: 18 additions & 0 deletions runtimes/8.3/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ ARG WWWGROUP
ARG NODE_VERSION=20
ARG MYSQL_CLIENT="mysql-client"
ARG POSTGRES_VERSION=15
ARG SQLSRV_VERSION=5.12.0
ARG ACCEPT_EULA="N"

WORKDIR /var/www/html

Expand Down Expand Up @@ -51,6 +53,22 @@ RUN apt-get update \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN if [ "$ACCEPT_EULA" = "Y" ]; then \
curl -sS https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc \
&& curl -sS https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& apt-get install -y mssql-tools18 unixodbc-dev \
&& echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc \
&& pecl install sqlsrv pdo_sqlsrv-$SQLSRV_VERSION \
&& printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/8.3/mods-available/sqlsrv.ini \
&& printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/8.3/mods-available/pdo_sqlsrv.ini \
&& phpenmod sqlsrv pdo_sqlsrv \
&& bash -c "source ~/.bashrc" \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \
fi

RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.3

RUN groupadd --force -g $WWWGROUP sail
Expand Down
31 changes: 28 additions & 3 deletions src/Console/Concerns/InteractsWithDockerComposeServices.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Laravel\Sail\Console\Concerns;

use RuntimeException;
use Symfony\Component\Process\Process;
use Symfony\Component\Yaml\Yaml;
use function str_replace;

trait InteractsWithDockerComposeServices
{
Expand All @@ -16,6 +18,7 @@ trait InteractsWithDockerComposeServices
'mysql',
'pgsql',
'mariadb',
'sqlsrv',
'redis',
'memcached',
'meilisearch',
Expand Down Expand Up @@ -99,7 +102,7 @@ protected function buildDockerCompose(array $services)
// Merge volumes...
collect($services)
->filter(function ($service) {
return in_array($service, ['mysql', 'pgsql', 'mariadb', 'redis', 'meilisearch', 'typesense', 'minio']);
return in_array($service, ['mysql', 'pgsql', 'mariadb', 'sqlsrv', 'redis', 'meilisearch', 'typesense', 'minio']);
})->filter(function ($service) use ($compose) {
return ! array_key_exists($service, $compose['volumes'] ?? []);
})->each(function ($service) use (&$compose) {
Expand Down Expand Up @@ -131,7 +134,8 @@ protected function replaceEnvVariables(array $services)

if (in_array('mysql', $services) ||
in_array('mariadb', $services) ||
in_array('pgsql', $services)) {
in_array('pgsql', $services) ||
in_array('sqlsrv', $services)) {
$defaults = [
'# DB_HOST=127.0.0.1',
'# DB_PORT=3306',
Expand All @@ -148,7 +152,7 @@ protected function replaceEnvVariables(array $services)
if (in_array('mysql', $services)) {
$environment = preg_replace('/DB_CONNECTION=.*/', 'DB_CONNECTION=mysql', $environment);
$environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=mysql", $environment);
}elseif (in_array('pgsql', $services)) {
} elseif (in_array('pgsql', $services)) {
$environment = preg_replace('/DB_CONNECTION=.*/', 'DB_CONNECTION=pgsql', $environment);
$environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=pgsql", $environment);
$environment = str_replace('DB_PORT=3306', "DB_PORT=5432", $environment);
Expand All @@ -158,6 +162,27 @@ protected function replaceEnvVariables(array $services)
}

$environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=mariadb", $environment);
} elseif (in_array('sqlsrv', $services)) {
$confirm = $this->confirm(
"To install Microsoft SQL Server 2022 x64, EULA acceptance is required. Accept? \n" .
'The Microsoft SQL Server EULA is available at: https://mcr.microsoft.com/product/mssql/server/about'
);

if (!$confirm) {
throw new RuntimeException('Cannot install Microsoft SQL Server without accepting the EULA.');
}

$environment = preg_replace('/DB_CONNECTION=.*/', "DB_CONNECTION=sqlsrv", $environment);
$environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=sqlsrv", $environment);
$environment = str_replace('DB_PORT=3306', "DB_PORT=1433", $environment);

if (!preg_match('/ACCEPT_EULA=(.*)/', $environment)) {
$environment = str_replace('DB_CONNECTION=sqlsrv', "DB_CONNECTION=sqlsrv\nACCEPT_EULA=Y", $environment);
}

if (!preg_match('/DB_ROOT_PASSWORD=(.*)/', $environment)) {
$environment = str_replace('DB_CONNECTION=sqlsrv', "DB_CONNECTION=sqlsrv\nDB_ROOT_PASSWORD=p@ssw0rd", $environment);
}
}

$environment = str_replace('DB_USERNAME=root', "DB_USERNAME=sail", $environment);
Expand Down
6 changes: 4 additions & 2 deletions src/Console/PublishCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ public function handle()
'./vendor/laravel/sail/runtimes/8.1',
'./vendor/laravel/sail/runtimes/8.0',
'./vendor/laravel/sail/database/mysql',
'./vendor/laravel/sail/database/pgsql'
'./vendor/laravel/sail/database/pgsql',
'./vendor/laravel/sail/database/sqlsrv',
],
[
'./docker/8.3',
'./docker/8.2',
'./docker/8.1',
'./docker/8.0',
'./docker/mysql',
'./docker/pgsql'
'./docker/pgsql',
'./docker/sqlsrv',
],
file_get_contents($this->laravel->basePath('docker-compose.yml'))
)
Expand Down
1 change: 1 addition & 0 deletions stubs/docker-compose.stub
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ services:
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
ACCEPT_EULA: '${ACCEPT_EULA}'
image: sail-8.3/app
extra_hosts:
- 'host.docker.internal:host-gateway'
Expand Down
22 changes: 22 additions & 0 deletions stubs/sqlsrv.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
sqlsrv:
image: 'mcr.microsoft.com/mssql/server:2022-latest'
ports:
- '${FORWARD_DB_PORT:-1433}:1433'
environment:
MSSQL_DB_NAME: '${DB_DATABASE}'
MSSQL_USER: '${DB_USERNAME}'
MSSQL_SA_PASSWORD: '${DB_ROOT_PASSWORD}'
MSSQL_PASSWORD: '${DB_PASSWORD}'
ACCEPT_EULA: '${ACCEPT_EULA}'
volumes:
- 'sail-sqlsrv:/var/opt/mssql'
- './vendor/laravel/sail/database/sqlsrv/entrypoint.sh:/entrypoint.sh'
entrypoint: "/entrypoint.sh"
networks:
- sail
healthcheck:
test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-No", "-U", "sa", "-P", "${MSSQL_SA_PASSWORD}", "-Q", "\"SELECT 1\"", "-b", "-o", "/dev/null"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s

0 comments on commit 321f30b

Please sign in to comment.