<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Infernal Error</title><description>Oh my god the server is on fire</description><link>https://infernalerror.com/</link><language>en</language><item><title>Use Docker Compose to simplify your Docker environment configuration</title><link>https://infernalerror.com/posts/docker-compose/docker-compose/</link><guid isPermaLink="true">https://infernalerror.com/posts/docker-compose/docker-compose/</guid><description>Docker Compose makes it easy to configure your docker environment and store those configurations in a single file that can be backed up and version-controlled, and run in a consistent manner every single time. The more services you add, the more convenient the compose file becomes.</description><pubDate>Mon, 30 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Why use Docker Compose&lt;/h1&gt;
&lt;p&gt;Docker Compose is a container orchestration tool you can use to configure the entirety of your application&apos;s Docker environment inside a single declarative config file, including multiple containers, networking, and volume mounts for persistent data. It is a self-documenting alternative to running individual &apos;Docker Run&apos; commands.&lt;/p&gt;
&lt;p&gt;Using Docker Compose, you create a single YAML formatted configuration file named &apos;docker-compose.yml&apos; by default. Inside that file lives what are essentially a collection of parameters that function much like Docker Run commands, complete with the containers you want to create, images they should be created from, environment variables that should be set, and more. You can then execute a single command against this file which creates your containers and your desired environment for them all at once. Likewise, you can pull updated images for all of your containers or tear down the entire stack all at once as needed. You can even version control your docker compose file using a tool like Git. With Docker Compose, your documentation &lt;em&gt;is&lt;/em&gt; your configuration, and it&apos;s all in one place.&lt;/p&gt;
&lt;h1&gt;Installing Docker Compose&lt;/h1&gt;
&lt;p&gt;Installing the docker compose plugin in easy. Once you&apos;ve installed the Docker Engine and Docker CLI, you&apos;ll generally just use your Linux distro&apos;s package manager to install the docker compose plugin. For Ubuntu or other Debian-based distro, just run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install docker-compose-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For other distributions, see the documentation on installing docker compose here:&lt;/p&gt;
&lt;p&gt;Install the Compose plugin&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.docker.com/compose/install/linux/&quot;&gt;How to install Docker Compose on Linux&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;The Docker Compose File&lt;/h1&gt;
&lt;p&gt;The Docker Compose file itself is very straightforward. It&apos;s in YAML format, so indentation should be consistent, using either two spaces or four. Let&apos;s take a look at an example compose file for a single MSSQL Server container.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3.8&apos; 
services:
    mssqlserver:
        image: mcr.microsoft.com/mssql/server:2019-latest
        environment:
            - ACCEPT_EULA=Y
            - MSSQL_SA_PASSWORD=&amp;lt;YourStrong!Passw0rd&amp;gt;
        ports:
            - &apos;1433:1433&apos;
        volumes:
            - &apos;&amp;lt;host_directory&amp;gt;/data:/var/opt/mssql/data&apos;
            - &apos;&amp;lt;host_directory&amp;gt;/log:/var/opt/mssql/log&apos;
            - &apos;&amp;lt;host_directory&amp;gt;/secrets:/var/opt/mssql/secrets&apos;
            

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A docker-compose.yml file with configuration for a single container&lt;/p&gt;
&lt;p&gt;The newest version of Docker Compose adapted the Compose Specification for Docker Compose files. In this newest specification, the &lt;code&gt;Version:&lt;/code&gt; property is not requred.&lt;/p&gt;
&lt;p&gt;Every compose file should begin with the same two lines*. The rest are dependent on your desired configuration.&lt;/p&gt;
&lt;p&gt;The first is the &lt;code&gt;version:&lt;/code&gt; property. This defines the compose file version. At the time of writing this is &apos;3.8&apos;*.&lt;/p&gt;
&lt;p&gt;The second is the &lt;code&gt;services:&lt;/code&gt; property. This is the top level of your compose file, under which you&apos;ll configure each required container/service.&lt;/p&gt;
&lt;p&gt;The third property is the name of your first service, in this case &lt;code&gt;mssqlserver:&lt;/code&gt;. This is an arbitrary friendly name you choose to identify your service.&lt;/p&gt;
&lt;p&gt;The fourth property and so on map directly to docker run commands you may be familiar with. This also makes it easy to translate between docker run commands and their docker compose file counterparts. At the end of a docker run command you will have the image and version tag you want to pull and use for your container. In compose, we use the &lt;code&gt;image:&lt;/code&gt; property, then the value will be the same as it would be in a docker run command, in this case &lt;code&gt;mcr.microsoft.com/mssql/server:2019-latest&lt;/code&gt;. This will pull the MSSQL server image from Microsoft, and due to the &lt;code&gt;2019-latest&lt;/code&gt; tag, it will pull the newest version of 2019 specifically.&lt;/p&gt;
&lt;p&gt;The fifth property is &lt;code&gt;environment:&lt;/code&gt; In a docker run command, you would specify each environment variable in with an &lt;code&gt;-e&lt;/code&gt; option, followed by the environment variable in KEY:VALUE format, for each environment variable you wish to set. In compose, we simply define the &lt;code&gt;environment:&lt;/code&gt; property once, then list each environment variable in KEY:VALUE format in list form underneath. So &lt;code&gt;-e &apos;ACCEPT_EULA=Y&apos; -e &apos;MSSQL_SA_PASSWORD=&amp;lt;YourStrong!Passw0rd&amp;gt;&apos;&lt;/code&gt; becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
    - ACCEPT_EULA=Y
    - MSSQL_SA_PASSWORD=&amp;lt;YourStrong!Passw0rd&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The sixth property is &lt;code&gt;ports:&lt;/code&gt; In a docker run command, you&apos;d specify any host port to container port mappings with the &lt;code&gt;-p&lt;/code&gt; option, followed by a single mapping in &lt;code&gt;hostport:containerport&lt;/code&gt; format, for each port you&apos;d like to expose. In compose, we define the &lt;code&gt;ports:&lt;/code&gt; property once, then list each port mapping in &lt;code&gt;hostport:containerport&lt;/code&gt; format in a list underneath that property. So &lt;code&gt;-p 1433:1433&lt;/code&gt; becomes&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ports:
    - &apos;1433:1433&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final property in our example docker compose file is &lt;code&gt;volumes:&lt;/code&gt; and this is where you&apos;ll define host directories that you want to map to container directories in order to persist your data. In a docker run command, you&apos;d specify your bind mounts with the &lt;code&gt;-v&lt;/code&gt; switch, followed by a single mapping in &lt;code&gt;hostdirectory:containerdirectory&lt;/code&gt; format, for each bind mound you&apos;d like to create. In compose, we define the &lt;code&gt;volumes:&lt;/code&gt; property once, then list each bind mount in &lt;code&gt;hostdirectory:containerdirectory&lt;/code&gt; format in a list underneath that property.  So&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-v &amp;lt;host_directory&amp;gt;/data:/var/opt/mssql/data&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-v &amp;lt;host_directory&amp;gt;/log:/var/opt/mssql/log&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-v &amp;lt;host_directory&amp;gt;/secrets:/var/opt/mssql/secrets&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volumes:
    - &apos;&amp;lt;host_directory&amp;gt;/data:/var/opt/mssql/data&apos;
    - &apos;&amp;lt;host_directory&amp;gt;/log:/var/opt/mssql/log&apos;
    - &apos;&amp;lt;host_directory&amp;gt;/secrets:/var/opt/mssql/secrets&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are many more properties you can set in your docker-compose.yml file, but these are all we need to get started with this container. If you&apos;d like to look into other example files and see all the possible configurations you can make, check out the official compose file v3 reference sheet here:&lt;/p&gt;
&lt;p&gt;[&lt;/p&gt;
&lt;p&gt;Compose file version 3 reference&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.docker.com/compose/compose-file/compose-file-v3/?ref=blog.infernalerror.com&quot;&gt;Compose file reference&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;The docker compose command&lt;/h1&gt;
&lt;p&gt;Now that we&apos;ve created our docker-compose.yml file, we can run a single command against that file that will pull all the necessary images, create any appropriate docker networks, create and start each container we&apos;ve configured along with all our port mappings and bind mounts.&lt;/p&gt;
&lt;p&gt;First, we&apos;ll need to open a terminal and change directory into the one which contains our docker-compose.yml file. Then we can run any docker compose commands we want, and docker compose will look in the current directory for our docker-compose.yml file and execute the command against it.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This command will create and/or start our entire environment as defined in our compose file. The &lt;code&gt;-d&lt;/code&gt; option will run the containers in &quot;detached mode&quot;, which will essentially run our containers in the background. Generally speaking this is the command you&apos;ll use to start your entire docker stack.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This command will do the same thing as &lt;code&gt;docker compose up -d&lt;/code&gt; except it will run your containers in the foreground, with the full output of each container&apos;s logs displayed interactively in your shell. This is useful if you&apos;d like to troubleshoot issues with your containers and get a centralized look at all their logs in one place.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;docker compose down&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This command tears down your entire docker environment, stopping your containers as well as removing them, their images, and any volumes or networks you&apos;ve created for them.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;docker compose pull&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This command pulls any images associated with the services you&apos;ve defined in your docker-compose.yml file but doesn&apos;t start the containers.&lt;/p&gt;
&lt;p&gt;In addition to docker compose commands, you can also run all the same docker commands against your docker environment.&lt;/p&gt;
&lt;h1&gt;Updating your containers&lt;/h1&gt;
&lt;p&gt;Docker compose makes updating your containers a breeze. simply run &lt;code&gt;docker compose pull&lt;/code&gt; against your compose file and docker will pull the latest version you&apos;ve tagged for each service in your compose file, but won&apos;t disrupt any running containers. Then you can run &lt;code&gt;docker compose up -d&lt;/code&gt; while your containers are running and it will recreate the containers which have new images that have been pulled. Any containers that are already on the most up-to-date image will not restart. This process can easily be added as a scheduled task using a tool like cron for automated container updates.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Summary&lt;/h1&gt;
&lt;p&gt;Docker Compose makes it easy to configure your docker environment and store those configurations in a single file that can be backed up and version-controlled, and run in a consistent manner every single time. The more services you add, the more convenient the compose file becomes.&lt;/p&gt;
&lt;hr /&gt;
</content:encoded><category>Software</category><category>docker</category><category>software</category><category>self-hosting</category></item></channel></rss>