도커 Laravel Sail에 MSSQL 연결 설치하기

서세윤·2025년 2월 24일

진짜.. 3일의 지옥..

챗지피티 말을 곧이곧대로 믿은 나의 멍청함이 시작이었다..

챗지피티프롬프트는 아래와 같았다

"나는 도커를 사용중이며 라라벨을 Sail을 이용해 설치 후 Start를 하고있어. 그런데, Sail에서 데이터베이스는 Mssql을 지원하지 않아. 너가 도와줬으면 해. Php 8.2버전을 사용하고있어"

라는 질문으로 시작했다

수정 결과를 가져와서 Dockerfile , docker-compose.yml , docker-compose.override.yml 등 뭐 이것저것 수정하라고 시키던데, 다 해봤다...
그런데 진짜 절대 절대 절대 안되고, 나사하나 빠진것마냥 이상했다...

결국 난 하나하나 찾아보면서 왜 하는지, 뭐때문에 하는지 찾아보고 공부하면서 했다..
(물론.. 서버 명령 설치 등 하나하나 공부하기엔 너무 걸려서, 기본적으로 필요한 설치등은 여전히 챗지피티 도움을 받긴했다)

그렇게 내가 3일간 삽질한 결과물을 공유도록 하겠다


난 교육계열에 입사하게 되었고
현재 이직 1개월 반이 지났다.

나에겐 꽤 생소한 MSSQL을 사용중이었고, 윈도우서버 + 클래식asp를 사용중인 굉장히 레거시한 회사였다.

그러나 팀장님은 젊음의 피가 흐르는 팀장님이었고
LMS를 자체 개발하기로 결정
여러가지 스택을 결정하게 되었으며

나 또한 이참에 가지고 싶었던 기술 스택을 적극 어필하게 되었다.

그렇게 결정한 스택은 nextjs + laravel + mssql이다

디비는 어쩔수 없이 mssql을 사용할 수 밖에 없었으며 백엔드 경우 개인적으로 .NET를 하고싶었으나, 팀장님의 라라벨 사랑으로 라라벨을 하게되었다

추가로, 학교나 관공서 특성의 SPA(과거엔 iframe으로..)을 위해 + SSR을 위해 nextjs를 사용
그렇게
nextjs + laravel + mssql 스택이 완성되었다

nextjs는 설치도 쉽고 금방 되었지만
laravel + mssql이 진짜 고역이었다..

내가 먼저 설치하고 설치방법을 공유해주기 위해 정리중이었는데,
생각은 시작은 composer , php 설치하는게 귀찮고, 이미 많이 사용해본 sail을 통해 설치하자는 나의 고착화된 생각이 시작이었다..

아래는 결과만 공유하도록 하겠다

(참고) wsl의 뜻은 window sub-system for linux 이다. 즉, 윈도우에서 사용하는 리눅스
1. wsl 설치
파워쉘 관리자 실행 후

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

명령어 실행
2.vm 기능 열기
파워쉘 관리자 실행 후 (실행중이라면 그대로 이어서)

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

3.우분투 설치
파워쉘 관리자 실행 후 (실행중이라면 그대로 이어서)

wsl --list --online 
wsl --install --d Ubuntu
설치완료 후
wsl.exe -d Ubuntu (name과 password 입력) // 추후에 사용됩니다

4.도커 설치
https://www.docker.com/products/docker-desktop/
설치 시 하이퍼 사용으로 설치하기

5.도커 우분투의 wsl 활성화
4번까지 모두 완료했다면,
도커 접속 후
설정 > Resources > WSL integration > Ubuntu 활성화

6.wsl 접속
첫 접속이라면

wsl -s Ubuntu

입력

wsl

입력 하면 wsl 접근 완료

7.업데이트

sudo apt-get update

8.라라벨 설치

cd /home/디렉토리(username)
접근 후 
curl -s https://laravel.build/lmsApi | bash

9.sail 명령어 활성화

vi ~/.bashrc
후

alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'

를 제일 하단에 넣은 후 저장

보통 ./vender/bin/sail 뭐 이런식으로 sail을 실행해야하지만, 위를 통해 바로 sail 명령어로만 가능

10.sail 설치

sail up

11.도커 파일 셋팅 준비

sail artisan sail:publish

실행 후 ./docker/8.4 등 도커 컨테이너 버전에 맞는 파일 생성 확인
publish를 하는 이유는 기본적으로 Dockerfile은 vendor에 속해있다.
vendor에 속해있으면, 추 후 composer update등 할때 새롭게 초기화 되기때문에 vendor밖으로 꺼내야 한다.

  1. Dockerfile에 mssql 설치 구문 추가
FROM ubuntu:24.04

LABEL maintainer="Taylor Otwell"

ARG WWWGROUP
ARG NODE_VERSION=22
ARG MYSQL_CLIENT="mysql-client"
ARG POSTGRES_VERSION=17

WORKDIR /var/www/html

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
ENV SUPERVISOR_PHP_USER="sail"
ENV ACCEPT_EULA=Y

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

RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
    echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
    echo "Acquire::BrokenProxy    true;" >> /etc/apt/apt.conf.d/99custom

RUN apt-get update && apt-get upgrade -y \
    && mkdir -p /etc/apt/keyrings \
    && apt-get install -y gnupg2 gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \
    && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \
    && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
    && apt-get update \
    && apt-get install -y php8.4-cli php8.4-dev \
       php8.4-pgsql php8.4-sqlite3 php8.4-gd \
       php8.4-curl php8.4-mongodb \
       php8.4-imap php8.4-mysql php8.4-mbstring \
       php8.4-xml php8.4-zip php8.4-bcmath php8.4-soap \
       php8.4-intl php8.4-readline \
       php8.4-ldap \
       php8.4-msgpack php8.4-igbinary php8.4-redis php8.4-swoole \
       php8.4-memcached php8.4-pcov php8.4-imagick php8.4-xdebug

# MSSQL 관련 추가 부분
RUN apt-get install -y unixodbc unixodbc-dev \
    && curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | tee /etc/apt/keyrings/microsoft.gpg > /dev/null \
    && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/microsoft.gpg] https://packages.microsoft.com/ubuntu/24.04/prod noble main" | tee /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 \
    && echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> /etc/profile \
    && echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc \
    && apt-get install -y php8.4-odbc \
    && pecl install sqlsrv pdo_sqlsrv \
    && echo "extension=sqlsrv.so" > /etc/php/8.4/cli/conf.d/20-sqlsrv.ini \
    && echo "extension=pdo_sqlsrv.so" > /etc/php/8.4/cli/conf.d/20-pdo_sqlsrv.ini

# 기타 설정 유지
RUN curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
    && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
    && apt-get update \
    && apt-get install -y nodejs \
    && npm install -g npm \
    && npm install -g pnpm \
    && npm install -g bun \
    && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \
    && echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
    && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \
    && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
    && apt-get update \
    && apt-get install -y yarn \
    && apt-get install -y $MYSQL_CLIENT \
    && apt-get install -y postgresql-client-$POSTGRES_VERSION \
    && apt-get -y autoremove \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

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

RUN userdel -r ubuntu
RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail

COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/8.4/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container

EXPOSE 80/tcp

ENTRYPOINT ["start-container"]

도커파일 내용이다.
앵간한 내용은 챗지피티의 도움을 받았기에.. 내용 뜻은 잘 모르지만 정상작동한다..

사실 제일 고생한 내용인데
챗지피티 한테 물어보면 ./docker/sail/Dockerfile 만들고 + docker-compose.override.yml 을 만든다음, laravel.test의 build context를 './docker/sail/Dockerfile'로 오버라이드 하라고 한다. 그리고 내용을 ./docker/sail/Dockerfile에 채워넣으라고 하는데,
이건 챗지피티가 sail의 시스템을 잘 이해하지못하고 있기에 발생하는 에러..
sail의 경우 기본적으로 설치시 도움주는 구문이 이미 설정이 되어있고, sail build를 하면 해당 dockerfile을 참조 할 뿐더러, overrid파일 경우 나는 붙여지는 형태인줄 알고 그대로 진행했지만, 알고보니 덮어씌우는 행위였다..
그러니 기존 sail을 위한 도커파일은 실행이 되지않고.. 그러니 당연히 sail app이미지가 실행안되고 혼자 불이 꺼져있엇던 것이었다...
이것때문에 다른게 문제인 줄 알고 다 수정해봣는데 ㅜㅜ 아니었다...
공부쫌 할걸..

아무튼 이어 가자면..

  1. docker-compose.yml에 mssql 설치구문 추가
services:
    laravel.test:
        build:
            context: './docker/8.4'
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: 'sail-8.4/app'
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
            - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
            IGNITION_LOCAL_SITES_PATH: '${PWD}'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mssql
            # - redis
            # - meilisearch
            # - mailpit
            # - selenium
    mssql:
        image: mcr.microsoft.com/mssql/server:2019-latest
        container_name: mssql
        ports:
            - "1433:1433"
        environment:
            MSSQL_SA_PASSWORD: "YourStrong!Passw0rd"
            ACCEPT_EULA: "Y"
        volumes:
            - mssql_data:/var/opt/mssql
        networks:
            - sail
    # mysql:
    #     image: 'mysql/mysql-server:8.0'
    #     ports:
    #         - '${FORWARD_DB_PORT:-3306}:3306'
    #     environment:
    #         MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
    #         MYSQL_ROOT_HOST: '%'
    #         MYSQL_DATABASE: '${DB_DATABASE}'
    #         MYSQL_USER: '${DB_USERNAME}'
    #         MYSQL_PASSWORD: '${DB_PASSWORD}'
    #         MYSQL_ALLOW_EMPTY_PASSWORD: 1
    #     volumes:
    #         - 'sail-mysql:/var/lib/mysql'
    #         - './docker/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
    #     networks:
    #         - sail
    #     healthcheck:
    #         test:
    #             - CMD
    #             - mysqladmin
    #             - ping
    #             - '-p${DB_PASSWORD}'
    #         retries: 3
    #         timeout: 5s
    # redis:
    #     image: 'redis:alpine'
    #     ports:
    #         - '${FORWARD_REDIS_PORT:-6379}:6379'
    #     volumes:
    #         - 'sail-redis:/data'
    #     networks:
    #         - sail
    #     healthcheck:
    #         test:
    #             - CMD
    #             - redis-cli
    #             - ping
    #         retries: 3
    #         timeout: 5s
    # meilisearch:
    #     image: 'getmeili/meilisearch:latest'
    #     ports:
    #         - '${FORWARD_MEILISEARCH_PORT:-7700}:7700'
    #     environment:
    #         MEILI_NO_ANALYTICS: '${MEILISEARCH_NO_ANALYTICS:-false}'
    #     volumes:
    #         - 'sail-meilisearch:/meili_data'
    #     networks:
    #         - sail
    #     healthcheck:
    #         test:
    #             - CMD
    #             - wget
    #             - '--no-verbose'
    #             - '--spider'
    #             - 'http://127.0.0.1:7700/health'
    #         retries: 3
    #         timeout: 5s
    # mailpit:
    #     image: 'axllent/mailpit:latest'
    #     ports:
    #         - '${FORWARD_MAILPIT_PORT:-1025}:1025'
    #         - '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025'
    #     networks:
    #         - sail
    # selenium:
    #     image: selenium/standalone-chromium
    #     extra_hosts:
    #         - 'host.docker.internal:host-gateway'
    #     volumes:
    #         - '/dev/shm:/dev/shm'
    #     networks:
    #         - sail
networks:
    sail:
        driver: bridge
volumes:
    # sail-mysql:
    #     driver: local
    # sail-redis:
    #     driver: local
    # sail-meilisearch:
    #     driver: local
    mssql_data:
        driver: local

기본적으로 sail에는 redis, meilisearch, mailpit, selenium이 제공되지만,아직은 아무고토 쓰지않을 예정이기에 다 주석..

이 후
14. ./config/database.php 수정
DB_CONNECTION의 환경변수를 sqlsrv로 변경,
connections 부분의 sqlsrv 키 값을

        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', 'laravel'),
            'username' => env('DB_USERNAME', 'sa'),
            'password' => env('DB_PASSWORD', 'Manuel@Passw0rd'),
            'charset' => env('DB_CHARSET', 'utf8'),
            'prefix' => '',
            'prefix_indexes' => true,
            // 'encrypt' => env('DB_ENCRYPT', 'yes'),
            'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
        ],

로 수정하였다

  1. .env 수정
    디비 컨넥션 설정 부분을
DB_CONNECTION=sqlsrv
DB_HOST=mssql  # docker-compose에서 정의한 MSSQL 컨테이너 이름
DB_PORT=1433
DB_DATABASE=laravel
DB_USERNAME=sa
DB_PASSWORD=YourStrong!Passw0rd
DB_ENCRYPTION=no
DB_TRUST_SERVER_CERTIFICATE=true

로 수정하였다.

  1. sail 재빌딩 후 실행
    이후
sail down --rmi all -v //sail 다운 후 컨테이너등 제거 (초기화)
sail build --no-cache //Dockerfile을 새롭게 빌드
sail up -d //백그라운드로 sail up

하게 되면 mssql이 정상적으로 붙고 작동하게 된다.

이상
다른분들은 나처럼 고생안했으면 좋겠다...

profile
개잡부..

0개의 댓글