Testing SQLServer and PHP locally in 2021
I’ve recently been working on overhauling the test database fixture system in CakePHP . My goals are to separate fixture schema management from fixture data management. By doing this applications will more easily be able to use their existing schema management to generate their test database. This project has entailed fixing many differences between the database servers that CakePHP supports. While I can easily install SQLite, MySQL and Postgres locally via apt
SQLServer is a different animal.
Docker to the rescue
Thankfully we’re in 2021 and Microsoft has invested the time to make SQLServer functional on Linux and Docker makes running SQLServer much easier than ever before. The pdo_sqlsrv
extension is complicated to install on linux, but thankfully Docker can make that easier too. So how does all this magic work? I wasn’t able to find a single reference guide after searching through google, stackoverflow and countless abandoned GitHub projects. From those sources, I was able to cobble together a solution. That I would like to share so other have a less confusing journey.
Getting SQLServer
First thing we need to do is get the SQLServer image. We can use docker pull
to get it:
- docker pull mcr.microsoft.com/mssql/server:2017-latest
Before we run this container, we need to setup a docker ‘network’. This is required so that our database and PHP containers can talk to each other. While you could do this with docker-compose
I didn’t want to use more tools:
- docker network create --driver bridge sqlserver-net
Now we can run our container to get SQLServer running in the background.
- docker run -e "ACCEPT_EULA=Y" \
- -e "SA_PASSWORD=p@ssw0rd" \
- -p 1433:1433 \
- --name sql1 \
- -h sql1 \
- --network sqlserver-net \
- -d mcr.microsoft.com/mssql/server:2017-latest
This will run the SQLServer container and attach it to the sqlserver-net
network we created. We’re also giving this container a name so that we can kill it and restart it later more eaisly with docker kill sql1
and docker start sql1
. Before our database is usable for testing, we’ll need to get a REPL in SQLServer so we can create a database or run ad-hoc queries:
- # Get in to the container.
- docker exec -it sql1 bash
- # Get a REPL for SQLServer
- /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "p@ssw0rd"
Getting PHP with pdo_sqlsrv
I chose to use PHP7.4 as I couldn’t get 7.2 to compile and I needed to test with one of the lower versions of PHP that CakePHP supports. I used the following docker image:
- FROM ubuntu:18.04
- ARG DEBIAN_FRONTEND=noninteractive
- # UPDATE PACKAGES
- RUN apt-get update
- # INSTALL SYSTEM UTILITIES
- RUN apt-get install -y \
- apt-utils \
- curl \
- git \
- apt-transport-https \
- software-properties-common \
- g++ \
- build-essential \
- dialog
- # INSTALL locales
- RUN apt-get install -qy language-pack-en-base \
- && locale-gen en_US.UTF-8
- ENV LANG en_US.UTF-8
- ENV LC_ALL en_US.UTF-8
- # INSTALL PHP & LIBRARIES
- RUN add-apt-repository -y ppa:ondrej/php
- RUN apt-get update
- RUN apt-get --no-install-recommends --no-install-suggests --yes --quiet install \
- php-pear \
- php7.4 \
- php7.4-common \
- php7.4-mbstring \
- php7.4-dev \
- php7.4-xml \
- php7.4-cli \
- php7.4-mbstring \
- php7.4-curl \
- php7.4-xml \
- php7.4-zip \
- php7.4-odbc \
- php7.4-intl
- # INSTALL ODBC DRIVER & TOOLS
- RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
- RUN curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
- RUN apt-get update
- RUN ACCEPT_EULA=Y apt-get install -y \
- msodbcsql17 \
- mssql-tools \
- unixodbc \
- unixodbc-dev
- RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
- RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
- RUN exec bash
- # INSTALL & LOAD SQLSRV DRIVER & PDO
- RUN pecl install sqlsrv
- RUN echo ";priority=20\nextension=sqlsrv.so" > /etc/php/7.4/cli/conf.d/20-sqlsrv.ini
- RUN pecl install pdo_sqlsrv
- RUN echo ";priority=30\nextension=pdo_sqlsrv.so" > /etc/php/7.4/cli/conf.d/30-pdo_sqlsrv.ini
- WORKDIR /src
- CMD ["/bash"]
You should be able to change the 7.4
into an 8.0
pretty easily and have everything work, but I haven’t tried. Once you build the image with:
- docker build -t php-sqlsrv -f sqlserver.Dockerfile .
You can run it with:
- docker run --rm -it --network sqlserver-net -v $(pwd):/src php-sqlsrv bash
You should now have a basic PHP installation able to communicate with a SQLServer database.
> The pdo_sqlsrv extension is complicated to install on linux
Did you try the guides from https://www.microsoft.com/en-us/sql-server/developer-get-started/php/ubuntu?rtc=1?
Marc Würth on 5/26/21
I didn’t use this exact guide, but I used one similar to it and ran into version conflicts between unixodbc and mssql-tools. It could be a problem related to using a 20.10 based distro.
mark story on 6/8/21