Bitbucket Database with SQL Server
Before starting with the actual Bitbucket server, we need to configure and setup the DB. This generally consists of the following high level building blocks:
- Database Engine
- Initialization Side Car
- SQL scripts for DB creation and optionally schema definitions if required
- Database Engine Docker Volume initialization
It is worth noting that all the init will do is execute a single sql file exec command, something that when done manually is extremely simple.
sqlclient -h [host] -u [user] -p [password] -f some.sql
Database Script Runner
One easy way to accomplish this is using a generic Database engine specific script runner that we then use to allow execution of any arbitrary script.
version: '3.3'
services:
db-script-sqlserver:
image: infra/db-script-sqlserver:1.0.0
build:
context: .
network: host
args:
ARG_ART_URL: http://d1i-doc-ngbuild:3001
extra_hosts:
- "d1i-doc-ngbuild:172.22.90.2"
FROM infra/ubuntu/focal:1.0.0
ARG ARG_ART_URL
RUN sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y curl netcat dos2unix gnupg \
&& apt-get clean \
&& rm /etc/apt/sources.list
COPY msprod.list.base /etc/apt/sources.list.d/msprod.list.base
# first MS key and sources, then ubuntu, then the actual install
# https://packages.microsoft.com/config/ubuntu/20.04/prod.list
RUN curl $ARG_ART_URL/repository/apt-keys/microsoft/microsoft.asc | apt-key add - \
&& sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.d/msprod.list.base > /etc/apt/sources.list.d/msprod.list \
&& sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& apt-get update \
&& ACCEPT_EULA=Y apt-get install -y mssql-tools unixodbc-dev \
&& apt-get clean \
&& rm /etc/apt/sources.list \
&& rm /etc/apt/sources.list.d/msprod.list
ENV PATH="$PATH:/opt/mssql-tools/bin"
# actual code itself
COPY sqlserver-init.sh /init/sqlserver-init.sh
RUN chmod +x /init/sqlserver-init.sh \
&& dos2unix /init/sqlserver-init.sh
COPY init.sh /init/init.sh
RUN chmod +x /init/init.sh \
&& dos2unix /init/init.sh
RUN curl $ARG_ART_URL/repository/dml/docker/tools/wait-for -o /init/wait-for \
&& dos2unix /init/wait-for \
&& chmod +x /init/wait-for
ENTRYPOINT ["/init/init.sh"]
#!/bin/bash
./init/wait-for $SQL_SERVER_HOST:1433 -t 300 -- /init/sqlserver-init.sh
deb [arch=amd64,armhf,arm64] APT_URL/repository/apt-proxy-ubuntu-focal-microsoft/ focal main
#!/bin/bash
# sleeping due to wait for having available port but sql server not yet available
echo "Giving SQL Server time to init after port availability"
sleep 30
echo "Assuming SQL Server is now started to init"
sqlcmd -S $SQL_SERVER_HOST -U sa -P "$SA_PASSWORD" -i /init/script.sql
printf "\nScript Execution Completed\n\n"
As we are using SQL Server for our db script runner, we need to install the Microsoft linux based client connectivity tools via our Ubuntu package manager. However, those are located on https://packages.microsoft.com/config/ubuntu/20.04/ and not the default package manager locations. To ensure we follow our core guidelines for availability, we will leverage our created APT proxy that was setup during the initial Seed Installation (see aptRepositories.groovy). As with the other APT proxy we follow the same command wrapping approach and a customized msprod.list.base file - this time though a double wrapping approach.
# first MS key and sources, then ubuntu, then the actual install
# https://packages.microsoft.com/config/ubuntu/20.04/prod.list
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
&& sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.d/msprod.list.base > /etc/apt/sources.list.d/msprod.list \
&& sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& apt-get update \
&& ACCEPT_EULA=Y apt-get install -y mssql-tools unixodbc-dev \
&& apt-get clean \
&& rm /etc/apt/sources.list \
&& rm /etc/apt/sources.list.d/msprod.list
Another element that is worth noting is the usage again of wait-for for side car setups. While we are waiting for the SQL Server process itself on its defined port of 1433, we have to introduce another wait inside the actual sqlserver-init.sh file. This is due to the SQL Server port being made available BUT the underlying database engine still starting up.
Microsoft SQL Server Image
The next challenge is taking control of the SQL Server Dockerfile. Unfortunately that is not quite as easy as the other public Dockerfiles located at https://github.com/Microsoft/mssql-docker.
# mssql-server-linux
# Maintainers: Microsoft Corporation (LuisBosquez and twright-msft on GitHub)
# GitRepo: https://github.com/Microsoft/mssql-docker
# Base OS layer: Latest Ubuntu LTS.
FROM ubuntu:16.04
# Default SQL Server TCP/Port.
EXPOSE 1433
# Copy all SQL Server runtime files from build drop into image.
COPY ./install /
# Run SQL Server process.
CMD [ "/opt/mssql/bin/sqlservr" ]
The above file is the one that microsoft recommends for docker usage via mcr.microsoft.com/mssql/server:2019-latest. However, Looking at available packages for MS SQL Server for Linux Ubuntu available here https://packages.microsoft.com/ubuntu/20.04/, we identified the ability to install SQL by hand via package manager to their latest supported version of Ubuntu focal 20.04. As such we were able to properly take control of this image from scratch as well.
version: '3.3'
services:
sqlserver:
image: infra/mssql/2019:1.0.0
build:
context: .
network: host
args:
ARG_ART_URL: http://d1i-doc-ngbuild:3001
extra_hosts:
- "d1i-doc-ngbuild:172.22.90.2"
FROM infra/ubuntu/focal:1.0.0
ARG ARG_ART_URL
RUN sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y curl gnupg gnupg1 gnupg2 \
&& apt install -y software-properties-common systemd vim -y \
&& apt-get clean \
&& rm /etc/apt/sources.list
COPY mssql.list.base /etc/apt/sources.list.d/mssql.list.base
RUN sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.base > /etc/apt/sources.list \
&& curl $ARG_ART_URL/repository/apt-keys/microsoft/microsoft.asc | apt-key add - \
&& sed -e "s|APT_URL|${ARG_ART_URL}|" /etc/apt/sources.list.d/mssql.list.base > /etc/apt/sources.list.d/mssql.list \
&& apt-get update \
&& ACCEPT_EULA=Y apt-get install -y mssql-server \
&& apt-get clean \
&& rm /etc/apt/sources.list.d/mssql.list \
&& rm /etc/apt/sources.list
ENTRYPOINT /opt/mssql/bin/sqlservr
deb [arch=amd64,armhf,arm64] APT_URL/repository/apt-proxy-ubuntu-focal-microsoft-mssql/ focal main
Building and Running
First step is building the DB script runner that we will then use as a side car to the database. And of course our main SQL Server image.
docker-compose -f images/db-script-sqlserver/docker-compose.yml build
docker-compose -f images/sqlserver/docker-compose.yml build
#docker login docker-private.acme.com
images/docker-push.sh infra/db-script-sqlserver:1.0.0 docker-private.acme.com
images/docker-push.sh infra/mssql/2019:1.0.0 docker-private.acme.com
To start the DB we will be using the following compose.
version: '3.3'
services:
sqlserver:
image: infra/mssql/2019:1.0.0
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=yourStrong(!)Password
ports:
- 1433:1433
hostname: d1i-doc-dbss01
volumes:
- sqlserver-data:/var/opt/mssql
- sqlserver-backup:/custom/bak
networks:
- ops-network
networks:
ops-network:
name: ops-network
volumes:
sqlserver-data:
name: sqlserver-data
sqlserver-backup:
name: sqlserver-backup
Simply start a SQL Server instance so we can get ready for config and connect.
# start DB
docker-compose -f composed/docker-compose-sqlserver.yml up --no-start
docker-compose -f composed/docker-compose-sqlserver.yml start
Next is the compose using our generic MS SQL Server script runner. Through the compose we are mounting bitbucket-sqlserver-init.sql into the runner as script.sql to be able to create the initial Database for bitbucket.
version: '3.3'
services:
db-script-sqlserver:
image: infra/db-script-sqlserver:1.0.0
environment:
- SQL_SERVER_HOST=d1i-doc-dbss01
- SA_PASSWORD=yourStrong(!)Password
volumes:
- ./db/bitbucket-sqlserver-init.sql:/init/script.sql
networks:
- ops-network
networks:
ops-network:
name: ops-network
CREATE DATABASE bitbucket
GO
USE bitbucket
GO
ALTER DATABASE bitbucket SET ALLOW_SNAPSHOT_ISOLATION ON
GO
ALTER DATABASE bitbucket SET READ_COMMITTED_SNAPSHOT ON
GO
ALTER DATABASE bitbucket COLLATE SQL_Latin1_General_CP1_CS_AS
GO
SET NOCOUNT OFF
GO
USE master
GO
CREATE LOGIN bitbucketuser WITH PASSWORD=N'ZeCodeIzGood', DEFAULT_DATABASE=bitbucket, CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
ALTER AUTHORIZATION ON DATABASE::bitbucket TO bitbucketuser
GO
Run the compose.
docker-compose -f composed/docker-compose-bitbucket-sqlserver-init.yml up
The end result is our new pre-initialized database volume that contains the database and user information required for the Bitbucket instance.
> docker volume ls
DRIVER VOLUME NAME
local sqlserver-backup
local sqlserver-data
local nexus-data