<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin George</title>
    <description>The latest articles on DEV Community by Kevin George (@kgeorge314).</description>
    <link>https://dev.to/kgeorge314</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F317616%2F0f8e3085-4407-467a-8f53-f3f4990b7285.jpg</url>
      <title>DEV Community: Kevin George</title>
      <link>https://dev.to/kgeorge314</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kgeorge314"/>
    <language>en</language>
    <item>
      <title>Containers | Building a local TSQL development environment</title>
      <dc:creator>Kevin George</dc:creator>
      <pubDate>Mon, 10 Feb 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/kgeorge314/containers-building-a-local-development-environment-4818</link>
      <guid>https://dev.to/kgeorge314/containers-building-a-local-development-environment-4818</guid>
      <description>&lt;p&gt;Docker-Compose, Flyway and a T-SQL runner to help you get up and running with a local development environment.&lt;/p&gt;

&lt;p&gt;In my introductory posts on &lt;a href="https://dev.to/kgeorge314/containers-quick-start-sql-server-containers-41c3"&gt;docker&lt;/a&gt; and &lt;a href="https://dev.to/kgeorge314/containers-quickstart-docker-compose-for-sql-server-2opi"&gt;docker-compose&lt;/a&gt;. We managed to set up an empty SQL Server container, but in the real world, that is not very useful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay great - we can create SQL Server containers now let us build on that to create a ready-to-go development environment with &lt;code&gt;docker-compose up&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let us take a moment to talk about the objective. We need a SQL Server, a database and something to deploy code to it (build). We will define a service (an instance of a container) in our compose file for each of these tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8RXDUcKO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-02-10-building-a-sql-dev-environment/local-development-environment.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8RXDUcKO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-02-10-building-a-sql-dev-environment/local-development-environment.png" alt="local-environment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Containers used:&lt;/p&gt;

&lt;p&gt;SQL Server using image &lt;code&gt;mcr.microsoft.com/mssql/server&lt;/code&gt;A simple T-SQL Script runner &lt;code&gt;aletasystems/tsqlrunner&lt;/code&gt;Flyway for Build/Deployment &lt;code&gt;boxfuse/flyway&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Flyway cannot create a database it expects the database to exist before deploying the code. This is why we use &lt;a href="https://github.com/aleta-systems/aletasystems.images.tsqlrunner"&gt;&lt;code&gt;aletasystems/tsqlrunner&lt;/code&gt;&lt;/a&gt; which is a custom-image based on &lt;code&gt;mcr.microsoft.com/mssql-tools&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL Server
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We have configured our SQL-Server as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running on port 14333&lt;/li&gt;
&lt;li&gt;Username &lt;code&gt;sa&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Password is set in a &lt;code&gt;.env&lt;/code&gt; file&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Initialise
&lt;/h2&gt;

&lt;p&gt;We now need to initialise SQL server using the container &lt;code&gt;aletasystems/tsqlrunner&lt;/code&gt;.Our initialisation process is really simple, execute a create database script against the master database.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;First a quick tour on how &lt;code&gt;aletasystems/tsqlrunner&lt;/code&gt; works&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your compose file, you map a local directory containing TSQL files to the containers &lt;code&gt;/tsqlscripts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The local directory follows the convention of &lt;code&gt;databasename\tsql-filename.sql&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The runner will first run the scripts in &lt;code&gt;master\filename&lt;/code&gt; (in alphabetical order)&lt;/li&gt;
&lt;li&gt;Then process each database and script (again in alphabetical order)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this information, we place a create database TSQL script file (&lt;code&gt;create-db.sql&lt;/code&gt;) in &lt;code&gt;./path2initsqlfiles/master&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We now add &lt;code&gt;inittools&lt;/code&gt; service to our &lt;code&gt;docker-compose&lt;/code&gt; file, we configure it as below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The SQL Server it connects to is the &lt;code&gt;db&lt;/code&gt; service we defined earlier&lt;/li&gt;
&lt;li&gt;It users the username &lt;code&gt;sa&lt;/code&gt; and password (&lt;em&gt;again it is taken from our &lt;code&gt;.env&lt;/code&gt; file&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;We give it the path to the SQL Scripts to run.
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;We will use flyway to deploy our code, but you can plugin an alternative that suits your need. I found flyway the easiest to work with, it is a fantastic tool and I hope to write/talk about it in the future.&lt;/p&gt;

&lt;p&gt;I won’t get into too much detail about how flyway works as that deserves it own post, but if you are interested you can read &lt;a href="https://flywaydb.org/getstarted/how"&gt;How Flyway works&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The basics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt; shows flyway where the &lt;code&gt;SQL&lt;/code&gt; &amp;amp; &lt;code&gt;conf&lt;/code&gt; folder are&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;command&lt;/code&gt; tells it what we want to do along with the various parameters&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

Some useful commands:&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To re-run flyway with the latest changes to source code &lt;code&gt;docker-compose restart flyway&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To view the flyway log &lt;code&gt;docker-compose logs -f flyway&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How did we control order?
&lt;/h2&gt;

&lt;p&gt;We used the &lt;code&gt;depends_on&lt;/code&gt; property to tell each service what it depends on. This is not exactly true, as it is (&lt;em&gt;and from what I understand&lt;/em&gt;) the moment a service comes online, docker believes it is ready - which can be problematic as SQL Server takes a few seconds to become accessible.&lt;/p&gt;

&lt;p&gt;It is therefore important that your services have a retry/delay mechanism built-in. Flyway has an additional parameter &lt;code&gt;-connectRetries=60&lt;/code&gt; and &lt;code&gt;aletasystems/tsqlrunner&lt;/code&gt; has a &lt;a href="https://github.com/aleta-systems/aletasystems.images.tsqlrunner/blob/e4d5471434587aa15166f9beda20a61aced5daaa/tooling/execute-sql-scripts.sh#L5-L10"&gt;modest retry mechanism&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>sqlserver</category>
      <category>tutorial</category>
      <category>dockercompose</category>
    </item>
    <item>
      <title>Tools | Data Tools and Software</title>
      <dc:creator>Kevin George</dc:creator>
      <pubDate>Wed, 22 Jan 2020 11:28:14 +0000</pubDate>
      <link>https://dev.to/kgeorge314/tools-data-tools-and-software-1gmj</link>
      <guid>https://dev.to/kgeorge314/tools-data-tools-and-software-1gmj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"To the man who only has a hammer, everything he encounters begins to look like a nail." - &lt;em&gt;Abraham Maslow&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Today's Data Engineer requires a variety of tools for their day to day tasks, which vary from working with source control to containers. The objective of this post is to share with you the various tools that I use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrated Development Environment (IDE)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code IDE's
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Visual Studio 2019 community (latest) &lt;a href="https://visualstudio.microsoft.com/vs/community/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Visual Studio Code &lt;a href="https://code.visualstudio.com/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SQL Server Data Tools (latest) &lt;a href="https://docs.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt?view=sql-server-2017"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Database IDE's
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;SQL Server Management Studio (&lt;em&gt;SSMS&lt;/em&gt;) (latest) &lt;a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-2017"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Azure Data Studio (latest) &lt;a href="https://docs.microsoft.com/en-us/sql/azure-data-studio/download"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MySQL WorkBench (latest) &lt;a href="https://www.mysql.com/products/workbench/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;pgAdmin-4 (&lt;em&gt;for Postgresql&lt;/em&gt;) &lt;a href="https://www.pgadmin.org/download/pgadmin-4-windows/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Oracle Sql Developer &lt;a href="https://www.oracle.com/technetwork/developer-tools/sql-developer/overview/index-097090.html"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MongoDB Compass (&lt;em&gt;appropriate version&lt;/em&gt;) &lt;a href="https://www.mongodb.com/download-center/compass"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PAID License&lt;/strong&gt; Multi-platform &lt;code&gt;|&lt;/code&gt; DataGrip &lt;a href="https://www.jetbrains.com/datagrip/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  RealTime Data analytics's
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Azure Service Bus Explorer &lt;code&gt;ServiceBusExplorer-*.*.*zip&lt;/code&gt; &lt;a href="https://github.com/paolosalvatori/ServiceBusExplorer/releases"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Data Science Tools
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;R-Studio &lt;a href="https://www.rstudio.com/products/rstudio/download/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anaconda &lt;a href="https://www.anaconda.com/download/"&gt;here&lt;/a&gt; - This is a collection of DS tools&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  SDK's &amp;amp; Plugins
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;.Net&lt;/code&gt; core &lt;a href="https://www.microsoft.com/net/download"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Python 2.7.x&lt;/code&gt; &lt;a href="https://www.python.org/downloads/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Python 3.x&lt;/code&gt; (latest) &lt;a href="https://www.python.org/downloads/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NodeJS&lt;/code&gt; (latest) &lt;a href="https://nodejs.org/en/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Docker&lt;/code&gt; &lt;a href="https://store.docker.com/editions/community/docker-ce-desktop-windows"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;minikube&lt;/code&gt; &lt;a href="https://kubernetes.io/docs/setup/minikube/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Azure Storage Emulator &lt;a href="https://go.microsoft.com/fwlink/?LinkId=717179&amp;amp;clcid=0x409"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Azure Cosmos DB Emulator &lt;a href="https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  DevOps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;AzurePowershell RM &lt;a href="https://www.microsoft.com/web/handlers/webpi.ashx/getinstaller/WindowsAzurePowershellGet.3f.3f.3fnew.appids"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Az CLI module  &lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Chocolatey &lt;a href="https://chocolatey.org/install"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;flywaydb Community Edition &lt;a href="https://flywaydb.org/download/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Utilities
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Notepad++ (latest) &lt;a href="https://notepad-plus-plus.org/download/v7.5.9.html"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DiffTool Winmerge &lt;a href="http://winmerge.org/downloads/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;cmder &lt;a href="http://cmder.net/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git &lt;a href="https://git-scm.com/download/win"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Powershell Modules
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;dbatools &lt;a href="https://dbatools.io/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;posh-git &lt;a href="http://dahlbyk.github.io/posh-git/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MicrosoftPowerBIMgmt &lt;a href="https://github.com/microsoft/powerbi-powershell"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;~AzureRM Powershell Module (&lt;em&gt;see above under DevOps&lt;/em&gt;)~&lt;/li&gt;
&lt;li&gt;Azure AZ Powershell Module &lt;a href="https://github.com/Azure/azure-powershell"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Useful Websites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://statisticsparser.com/"&gt;https://statisticsparser.com/&lt;/a&gt; - SQL Server &lt;code&gt;SET STATISTICS *&lt;/code&gt; parser&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.brentozar.com/pastetheplan/"&gt;https://www.brentozar.com/pastetheplan/&lt;/a&gt; - Share SQL Server Execution Plans&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jsoneditoronline.org/"&gt;https://jsoneditoronline.org/&lt;/a&gt; - Edit JSON Files easily without worrying about escapes.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.kloth.net/services/nslookup.php"&gt;http://www.kloth.net/services/nslookup.php&lt;/a&gt; - DNS Lookup Site&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackedit.io/"&gt;https://stackedit.io/&lt;/a&gt; - Online Markdown Editor.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://colab.research.google.com/"&gt;https://colab.research.google.com/&lt;/a&gt; - Google Colab (Jupyter notebook like Google Docs)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Slack Communities
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;SQL Server Slack Community &lt;a href="https://dbatools.io/slack"&gt;https://dbatools.io/slack&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Powershell Slack Community &lt;a href="http://slack.poshcode.org/"&gt;http://slack.poshcode.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Octopus Deploy Slack Community &lt;a href="https://octopus.com/slack"&gt;https://octopus.com/slack&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Personal Notes
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Azure Data Studio
&lt;/h4&gt;

&lt;p&gt;Currently, I have a love-hate relationship with Azure Data Studio (&lt;em&gt;Previously SqlOps Studio&lt;/em&gt;). While it has a long way to go, the features such as inbuilt graphs, exports, &lt;em&gt;temperamental&lt;/em&gt; auto-complete and plugins - do differentiate it slightly, however, I do have to push myself to use it and when I do, I usually end up back in SSMS to do some serious work.&lt;/p&gt;

&lt;h4&gt;
  
  
  JetBrains DataGrip
&lt;/h4&gt;

&lt;p&gt;Whilst it is an excellent tool with good support for connecting to multiple systems, I have not been able to justify the need for it - this is probably attributed to the fact that I work mostly on SQL Server and Microsoft Tech.&lt;/p&gt;

&lt;h4&gt;
  
  
  Visual Studio Code
&lt;/h4&gt;

&lt;p&gt;This is one of the IDE's I turn to on a regular basis, whether it is to blog (Jekyll), script (Powershell, Shell, Batch), develop (Python, C#), document (Markdown), Infrastructure (Azure ARM, Docker) - VSCode has a plugin for it. &lt;em&gt;It even has extensions for Data but I always go to SSMS - 'old habits die hard'&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My Plugin List:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Requires &lt;code&gt;code&lt;/code&gt; to be part of your &lt;code&gt;PATH&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;code --install-extension Compulim.vscode-azure-storage-utility
code --install-extension DavidAnson.vscode-markdownlint
code --install-extension eamodio.gitlens
code --install-extension eriklynd.json-tools
code --install-extension fcrespo82.markdown-table-formatter
code --install-extension formulahendry.azure-storage-explorer
code --install-extension msazurermtools.azurerm-vscode-tools
code --install-extension ms-azuretools.vscode-azureappservice
code --install-extension ms-azuretools.vscode-azurefunctions
code --install-extension ms-azuretools.vscode-azurestorage
code --install-extension ms-azuretools.vscode-azureterraform
code --install-extension ms-azuretools.vscode-cosmosdb
code --install-extension mshdinsight.azure-hdinsight
code --install-extension ms-kubernetes-tools.vscode-kubernetes-tools
code --install-extension ms-mssql.mssql
code --install-extension ms-python.python
code --install-extension ms-toolsai.vscode-ai
code --install-extension ms-vscode.azure-account
code --install-extension ms-vscode.azurecli
code --install-extension ms-vscode.csharp
code --install-extension ms-vscode.PowerShell
code --install-extension ms-vscode.Theme-MarkdownKit
code --install-extension ms-vscode.vscode-azureextensionpack
code --install-extension ms-vsts.team
code --install-extension PeterJausovec.vscode-docker
code --install-extension redhat.vscode-yaml
code --install-extension Summer.azure-event-hub-explorer
code --install-extension usqlextpublisher.usql-vscode-ext
code --install-extension VisualStudioOnlineApplicationInsights.application-insights
code --install-extension vsciot-vscode.azure-iot-edge
code --install-extension vsciot-vscode.azure-iot-toolkit
code --install-extension wmontalvo.vsc-jsonsnippets
code --install-extension yzane.markdown-pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>tools</category>
      <category>azure</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>Containers | QuickStart Docker Compose for SQL Server</title>
      <dc:creator>Kevin George</dc:creator>
      <pubDate>Tue, 21 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/kgeorge314/containers-quickstart-docker-compose-for-sql-server-2opi</link>
      <guid>https://dev.to/kgeorge314/containers-quickstart-docker-compose-for-sql-server-2opi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;‘Visual Studio Code + Compose File + Docker Plugin = Amazing’&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my previous post, &lt;a href="https://dev.to/kgeorge314/containers-quick-start-sql-server-containers-41c3"&gt;introduction to docker&lt;/a&gt; we looked at how to get, start, stop and remove containers by running the various &lt;code&gt;docker&lt;/code&gt; commands. Today, we will look at how to use &lt;code&gt;docker-compose&lt;/code&gt;, followed by how easy it is to use with &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt; + &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker"&gt;vscode-docker extension&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Introduction to &lt;code&gt;docker-compose&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Dockers documentation on &lt;a href="https://docs.docker.com/compose/"&gt;docker-compose&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compose is a tool for defining and running multi-container Docker applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note: &lt;code&gt;docker-compose&lt;/code&gt; will only work with &lt;strong&gt;Linux&lt;/strong&gt; containers. (At the moment).&lt;/p&gt;

&lt;p&gt;Let us now break down the &lt;code&gt;docker run&lt;/code&gt; command into a compose file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -d -p 14333:1433 --name myDocker --hostname myDocker -e sa_password='$3cureP@ssw0rd' -e ACCEPT_EULA=Y microsoft/mssql-server-linux&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Recapping, we have a &lt;code&gt;Microsoft/mssql-server-linux&lt;/code&gt; container named &lt;code&gt;myDocker&lt;/code&gt;, running SQL Server on port &lt;code&gt;14333&lt;/code&gt; with the &lt;code&gt;SA&lt;/code&gt; password as &lt;code&gt;$3cureP@ssw0rd&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let me explain what each line means, in a simplistic way.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;version: '3'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Version of Docker-Compose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;services:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A list Services in the container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;____ db:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A container named &lt;code&gt;db&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;________ image: microsoft/mssql-server-linux&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The image that this services will use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;________ environment:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A list of environment variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;____________ SA_PASSWORD: $3cureP@ssw0rd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The environment variable &lt;code&gt;SA_PASSWORD&lt;/code&gt; with its value as &lt;code&gt;$3cureP@ssw0rd&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;____________ ACCEPT_EULA: Y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The environment variable &lt;code&gt;ACCEPT_EULA&lt;/code&gt; with its value as &lt;code&gt;Y&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;________ ports:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A list of ports exposed by this container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;____________ - '14333:1433'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The mapping of container-port:1433 to 14333&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;_Spaces are important in &lt;code&gt;YML&lt;/code&gt; files which is why I have used &lt;code&gt;_&lt;/code&gt; to represent them here.&lt;/p&gt;

&lt;p&gt;Now that we have an understanding of the basics, how do we run a compose file?&lt;/p&gt;

&lt;h4&gt;
  
  
  Running a &lt;code&gt;docker-compose&lt;/code&gt; file
&lt;/h4&gt;

&lt;p&gt;To run a docker-compose file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To run &lt;code&gt;docker-compose -f "path\to\docker-compose.yml" up -d --build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To tear-down &lt;code&gt;docker-compose -f "path\to\docker-compose.yml" down&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;to restart, well it is &lt;code&gt;down&lt;/code&gt; and &lt;code&gt;up&lt;/code&gt; :)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now a screencast of how to run a &lt;code&gt;docker-compose&lt;/code&gt; file in VS Code&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nI2niqfF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-21-Introduction-to-docker-compose/docker-compose-up.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nI2niqfF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-21-Introduction-to-docker-compose/docker-compose-up.gif" alt="docker-compose-up"&gt;&lt;/a&gt;&lt;a href="https://datastories.aletasystems.com/assets/images/Posts/2020-01-21-Introduction-to-docker-compose/docker-compose-up.mp4"&gt;mp4 version&lt;/a&gt;(Ps: &lt;em&gt;I used &lt;a href="https://www.screentogif.com/"&gt;screentogif&lt;/a&gt; to make these&lt;/em&gt;)&lt;/p&gt;

&lt;h4&gt;
  
  
  Environment Variables in &lt;code&gt;docker-compose&lt;/code&gt; file
&lt;/h4&gt;

&lt;p&gt;If you recall, in the above screencast there was an error &lt;code&gt;Invalid interpolation format for "environment" option in service "db": "$3cureP@ssw0rd"&lt;/code&gt;. With a compose file you can use variables in the format of &lt;code&gt;${variable_name}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; You don’t want to hard-code the password into your Docker-Compose file but would like it to be taken from a &lt;code&gt;.env&lt;/code&gt; file (&lt;em&gt;ideally it is not part of source-control&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;docker-compose&lt;/code&gt; file you replace the &lt;em&gt;hard-code&lt;/em&gt; password with a variable &lt;code&gt;${SQL_SERVER_PASSWORD}&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Then you create a file name &lt;code&gt;.env&lt;/code&gt; in the same folder as the &lt;code&gt;docker-compose&lt;/code&gt; file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now when you run &lt;code&gt;docker-compose up&lt;/code&gt; it will automatically substitute the value of &lt;code&gt;$3cureP@ssw0rd&lt;/code&gt; into &lt;code&gt;${SQL_SERVER_PASSWORD}&lt;/code&gt; and as a bonus docker will automatically escape the &lt;code&gt;$&lt;/code&gt; and change to &lt;code&gt;$$&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A snippet to run this code-example.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>docker</category>
      <category>sqlserver</category>
      <category>tutorial</category>
      <category>dockercompose</category>
    </item>
    <item>
      <title>Containers | Quick Start SQL Server Containers</title>
      <dc:creator>Kevin George</dc:creator>
      <pubDate>Tue, 14 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/kgeorge314/containers-quick-start-sql-server-containers-41c3</link>
      <guid>https://dev.to/kgeorge314/containers-quick-start-sql-server-containers-41c3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;‘It works on my machine’, ‘What version are you using’, ‘check your config’ - &lt;em&gt;another developer&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D36qfNO7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-14-Introduction-to-docker/Container-Components.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D36qfNO7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-14-Introduction-to-docker/Container-Components.png" alt="container-components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Components
&lt;/h4&gt;

&lt;p&gt;Let me try and explain the graphic above&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Container Registry: A place where container-images are hosted and can be downloaded onto your local docker instance. A common public repository is &lt;a href="https://hub.docker.com/"&gt;docker-hub&lt;/a&gt;. You can also have private container repositories, lookup &lt;a href="https://azure.microsoft.com/en-us/services/container-registry/"&gt;azure container registry&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docker on your machine, for illustrative purposes I have broken it down into two parts 

&lt;ol&gt;
&lt;li&gt;a local repository of &lt;code&gt;container images&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a space that represents running containers, an &lt;code&gt;instance of a container&lt;/code&gt;. You can have multiple instances of a container running&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The docker engine can run in either Windows or Linux mode but not both simultaneously (at the moment), this is important as you cannot run a Linux SQL Server side by side with a windows SQL server or more realistically, you cannot use a windows-SQL-server with a Linux Web server. This is one of the reasons you will see that I tend to use Linux containers over windows.&lt;/p&gt;

&lt;h4&gt;
  
  
  Container WorkFlow
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W3pnm3Kk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-14-Introduction-to-docker/Container-Stages.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W3pnm3Kk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-14-Introduction-to-docker/Container-Stages.png" alt="container-components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We &lt;strong&gt;Get&lt;/strong&gt; the container image 

&lt;ol&gt;
&lt;li&gt;for windows &lt;code&gt;microsoft/mssql-server-windows-developer&lt;/code&gt; by running &lt;code&gt;docker pull microsoft/mssql-server-windows-developer:latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;for linux &lt;code&gt;microsoft/mssql-server-linux&lt;/code&gt; by running &lt;code&gt;docker pull microsoft/mssql-server-linux:latest&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run&lt;/strong&gt; (&lt;em&gt;start&lt;/em&gt;) the container &lt;code&gt;docker run -d -p 14333:1433 --name myDocker --hostname myDocker -e SA_PASSWORD='$3cureP@ssw0rd' -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer&lt;/code&gt;

&lt;ol&gt;
&lt;li&gt;for windows &lt;code&gt;docker run -d -p 14333:1433 --name myDocker --hostname myDocker -e SA_PASSWORD='$3cureP@ssw0rd' -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;for linux &lt;code&gt;docker run -d -p 14333:1433 --name myDocker --hostname myDocker -e SA_PASSWORD='$3cureP@ssw0rd' -e ACCEPT_EULA=Y microsoft/mssql-server-linux&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;using SSMS Server &lt;code&gt;localhost,14333&lt;/code&gt; , &lt;code&gt;sa&lt;/code&gt; , &lt;code&gt;$3cureP@ssw0rd&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;using Powershell &lt;code&gt;Invoke-Sqlcmd -ServerInstance "localhost,14333" -Database master -Username sa -Password '$3cureP@ssw0rd' -Query 'SELECT DB_NAME() as DatabaseName'&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop&lt;/strong&gt; the container &lt;code&gt;docker stop myDocker&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start&lt;/strong&gt; (Resume/Restart) the container &lt;code&gt;docker start myDocker&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destroy&lt;/strong&gt; the container &lt;code&gt;docker rm myDocker --force&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Linux or Windows is not based on your OS but on the runtime version of docker-desktop as illustrated below, you can see &lt;code&gt;switch to windows containers&lt;/code&gt; indicates I am currently running in &lt;code&gt;Linux&lt;/code&gt; container mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LFBRvnsq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-14-Introduction-to-docker/docker-desktop-configuration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LFBRvnsq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datastories.aletasystems.com/assets/images/Posts/2020-01-14-Introduction-to-docker/docker-desktop-configuration.png" alt="container-components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parameters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Docker Reference&lt;/em&gt; &lt;a href="https://docs.docker.com/engine/reference/commandline/run/"&gt;&lt;code&gt;docker run&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;-p 14333:1433 | --expose&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;-p&lt;/code&gt; defines the port mapping between the host machine and the container. For example, an &lt;code&gt;httpd&lt;/code&gt; image exposes port 80, and similarly, the &lt;code&gt;mssql-server-windows-developer&lt;/code&gt; exposes &lt;code&gt;1433&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reason I mapped port 14333 to 1433 is that on my machine I have a SQL Server Developer Edition installed and running. If I bind to 1433:1433 then there would have been a port conflict between the docker instance and the local SQL Server instance.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;--name myDocker&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;A friendly name for your container that allows you to run commands such as &lt;code&gt;docker inspect myDocker&lt;/code&gt; vs &lt;code&gt;docker inspect &amp;lt;ContainerGuidID&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;--hostname myDocker&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;This is the value of the hostname which I needed specifically for &lt;code&gt;JDBC URL&lt;/code&gt;. Please note that you can use &lt;code&gt;localhost&lt;/code&gt; / &lt;code&gt;127.0.0.1&lt;/code&gt; too&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;--env | -e&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;-e&lt;/code&gt; is a docker parameter for environment variables, the two variables exposed by the &lt;code&gt;mssql-server-windows-developer&lt;/code&gt; image are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SA_PASSWORD&lt;/code&gt;: it sets the &lt;code&gt;sa&lt;/code&gt; password. (the password matches complexity requirements).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ACCEPT_EULA&lt;/code&gt;: a flag to indicate you accept the EULA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;--volume&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;Simplistically, using &lt;code&gt;--volume&lt;/code&gt; allows you to share a folder between host and container.&lt;/p&gt;

&lt;p&gt;A few reasons you would do this are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to persist my &lt;code&gt;.mdf&lt;/code&gt; files to my local disk.&lt;/li&gt;
&lt;li&gt;I have a &lt;code&gt;.bak&lt;/code&gt; / &lt;code&gt;.mdf&lt;/code&gt; file that is shared between developers&lt;/li&gt;
&lt;li&gt;I need to use &lt;code&gt;BULK INSERT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Any other reason that requires me to share files between the host and container instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Host: &lt;code&gt;C:\DockerPersistedStorage\Containers\myDocker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;--volume 'C:\DockerPersistedStorage':'C:\DockerPersistedStorage'&lt;/code&gt; would map &lt;code&gt;'C:\DockerPersistedStorage'&lt;/code&gt; on your host machine to &lt;code&gt;'C:\DockerPersistedStorage'&lt;/code&gt; on the Docker instance.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;--volume 'C:\DockerPersistedStorage':'/path/on/linux/file/system/DockerPersistedStorage'&lt;/code&gt; would map &lt;code&gt;'C:\DockerPersistedStorage'&lt;/code&gt; on your host machine to &lt;code&gt;'/path/on/linux/file/system/DockerPersistedStorage'&lt;/code&gt; on the Docker instance.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>sqlserver</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
