summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Spek <p.spek@tyil.nl>2021-06-04 17:30:16 +0200
committerPatrick Spek <p.spek@tyil.nl>2021-06-04 17:32:52 +0200
commit180965a27dc698bc0b3b3571ddb895c37abc83dd (patch)
tree1fc2a1f2632e4677511e9304e5ee54b090900e8d
parentb22190416684e8ed57aa380c89083985eb0d9a4b (diff)
Add post on docker-compose with openrc
-rw-r--r--src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md b/src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md
new file mode 100644
index 0000000..76fe272
--- /dev/null
+++ b/src/_posts/2021-06-04-managing-docker-compose-projects-with-openrc.md
@@ -0,0 +1,195 @@
+---
+layout: post
+tags: Gentoo Openrc Docker DockerCompose
+title: Managing Docker Compose with OpenRC
+social:
+ email: mailto:~tyil/public-inbox@lists.sr.ht&subject=managing docker compose with openrc
+description: >
+ A quick overview of the method I've used to manage docker-compose based
+ projects/services with OpenRC.
+---
+
+On one of my machines, I host a couple services using `docker-compose`. I
+wanted to start/restart/stop these using the default init/service manager used
+on the machine, `openrc`. This would allow them to start/stop automatically
+with Docker (which coincides with the machine powering on or off,
+respectively).
+
+I've set this up through a single `docker-compose` meta-service. To add new
+`docker-compose` projects to be managed, all I need to do for `openrc`
+configuration is creating a symlink, and configure the path to the
+`docker-compose.yaml` file.
+
+The meta-service lives at `/etc/init.d/docker-compose`, just like all other
+services managed by `openrc`. This file is quite straightforward. To start off,
+a number of variables are set and exported.
+
+{% highlight sh %}
+name="$RC_SVCNAME"
+description="OpenRC script for managing the $name docker-compose project"
+
+# Set default values
+DOCKER_COMPOSE="${DOCKER_COMPOSE:-docker-compose} $DOCKER_COMPOSE_ARGS"
+
+COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-$name}"
+
+# Export all variables used by docker-compose CLI
+export COMPOSE_PROJECT_NAME
+export COMPOSE_FILE
+export COMPOSE_PROFILES
+export COMPOSE_API_VERSION
+export DOCKER_HOST
+export DOCKER_TLS_VERIFY
+export DOCKER_CERT_PATH
+export COMPOSE_HTTP_TIMEOUT
+export COMPOSE_TLS_VERSION
+export COMPOSE_CONVERT_WINDOWS_PATHS
+export COMPOSE_PATH_SEPARATOR
+export COMPOSE_FORCE_WINDOWS_HOST
+export COMPOSE_IGNORE_ORPHANS
+export COMPOSE_PARALLEL_LIMIT
+export COMPOSE_INTERACTIVE_NO_CLI
+export COMPOSE_DOCKER_CLI_BUILD
+{% endhighlight %}
+
+One of the services I use is also configured with its own `external` network. I
+want it to be created if it doesn't exist, to ensure that the service can start
+up properly. I do *not* want it to be removed, so I left that out.
+
+{% highlight sh %}
+# Set up (external) networks
+for name in "${DOCKER_NETWORKS[@]}"
+do
+ # Create the network if needed
+ if ! docker network ls | awk '{ print $2 }' | grep -q "$name"
+ then
+ einfo "Creating docker network '$name'"
+ docker network create "$name" > /dev/null
+ fi
+
+ # Expose some variables for the networks
+ network_id="DOCKER_NETWORK_${name}_ID"
+
+ declare -gx DOCKER_NETWORK_${name}_ID="$(docker network ls | awk '$2 == "'"$name"'" { print $1 }')"
+ declare -gx DOCKER_NETWORK_${name}_GATEWAY="$(docker network inspect "${!network_id}" | jq -r '.[0].IPAM.Config[0].Gateway')"
+
+ unset network_id
+done
+{% endhighlight %}
+
+And lastly, there's the four simple functions to declare dependencies,
+configure how to `start` or `stop`, and how to get the `status` of the service.
+
+{% highlight sh %}
+depend() {
+ need docker
+}
+
+start() {
+ $DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" up -d
+}
+
+status() {
+ $DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" ps
+}
+
+stop() {
+ $DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" down
+}
+{% endhighlight %}
+
+Now, to actually create a service file to manage a `docker-compose` project, a
+symlink must be made. I'll take my
+[`botamusique`](https://github.com/azlux/botamusique) service as an example.
+
+{% highlight text %}
+ln -s /etc/init.d/docker-compose /etc/init.d/botamusique
+{% endhighlight %}
+
+This service can't start just yet, as there's no `$COMPOSE_PROJECT_DIRECTORY`
+configured for it yet. For this, a similarly named file should be made in
+`/etc/conf.d`. In here, any variable used by the service can be configured.
+
+{% highlight text %}
+$EDITOR /etc/conf.d/botamusique
+{% endhighlight %}
+
+In my case, it only pertains the `$COMPOSE_PROJECT_DIRECTORY` variable.
+
+{% highlight sh %}
+COMPOSE_PROJECT_DIRECTORY="/var/docker-compose/botamusique"
+{% endhighlight %}
+
+And that's it. For additional `docker-compose` projects I need to make only a
+symlink and a configuration file. If I discover a bug or nuisance, only a
+single file needs to be altered to get the benefit on all the `docker-compose`
+services.
+
+For reference, here's the full `/etc/init.d/docker-compose` file.
+
+{% highlight sh %}
+#!/sbin/openrc-run
+# Copyright 2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+name="$RC_SVCNAME"
+description="OpenRC script for managing the $name docker-compose project"
+
+# Set default values
+DOCKER_COMPOSE="${DOCKER_COMPOSE:-docker-compose} $DOCKER_COMPOSE_ARGS"
+
+COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-$name}"
+
+# Export all variables used by docker-compose CLI
+export COMPOSE_PROJECT_NAME
+export COMPOSE_FILE
+export COMPOSE_PROFILES
+export COMPOSE_API_VERSION
+export DOCKER_HOST
+export DOCKER_TLS_VERIFY
+export DOCKER_CERT_PATH
+export COMPOSE_HTTP_TIMEOUT
+export COMPOSE_TLS_VERSION
+export COMPOSE_CONVERT_WINDOWS_PATHS
+export COMPOSE_PATH_SEPARATOR
+export COMPOSE_FORCE_WINDOWS_HOST
+export COMPOSE_IGNORE_ORPHANS
+export COMPOSE_PARALLEL_LIMIT
+export COMPOSE_INTERACTIVE_NO_CLI
+export COMPOSE_DOCKER_CLI_BUILD
+
+# Set up (external) networks
+for name in "${DOCKER_NETWORKS[@]}"
+do
+ # Create the network if needed
+ if ! docker network ls | awk '{ print $2 }' | grep -q "$name"
+ then
+ einfo "Creating docker network '$name'"
+ docker network create "$name" > /dev/null
+ fi
+
+ # Expose some variables for the networks
+ network_id="DOCKER_NETWORK_${name}_ID"
+
+ declare -gx DOCKER_NETWORK_${name}_ID="$(docker network ls | awk '$2 == "'"$name"'" { print $1 }')"
+ declare -gx DOCKER_NETWORK_${name}_GATEWAY="$(docker network inspect "${!network_id}" | jq -r '.[0].IPAM.Config[0].Gateway')"
+
+ unset network_id
+done
+
+depend() {
+ need docker
+}
+
+start() {
+ $DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" up -d
+}
+
+status() {
+ $DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" ps
+}
+
+stop() {
+ $DOCKER_COMPOSE --project-directory "$COMPOSE_PROJECT_DIRECTORY" down
+}
+{% endhighlight %}