Dec 31, 2022 2 min read

The Working Developer's Guide to Running Startup Scripts in an S6-Overlay Docker Container

The Working Developer's Guide to Running Startup Scripts in an S6-Overlay Docker Container
Table of Contents

Need to run a quick init script in s6? This is the guide for you! How to add a custom adhoc "oneshot" startup script in a Docker container using the s6-overlay system.

So you've got a Docker container and you want to add a custom, one-off initialization script that runs whenever the container starts. The only thing is that instead of using the standard systemd init system that you're accustomed to in typical Linux environments, you find that this Docker container instead uses s6!

You've searched everywhere on running a startup script in s6, but so far all you've found are a bunch of wikis describing the operation of s6 and they go on for hundreds of pages. You're a developer, you work for a living, you don't have time to read all of that for this one Bash script you need to run! So what do you do? In today's tutorial, I'll show you how to define a "oneshot" (what s6 calls a startup/one-off/ad-hoc script) in s6-rc to run your Bash script.

💡
Note that while this guide mentions Docker containers, it is more generalizable to any Linux distribution using s6.

How to Add a Oneshot Startup/Initialization Script in s6-rc

  1. Create a directory defining your service in /etc/s6-overlay/s6-rc.d/. In s6-rc lingo, this is known as the "source definition directory":
mkdir /etc/s6-overlay/s6-rc.d/<scriptNameHere>

For example, in my case, I created a service to restore IP tables when my Docker container was reloaded:

mkdir /etc/s6-overlay/s6-rc.d/iptableRestoreOneshot
  1. Define a type for this service by creating a file called "type" inside your new directory. Since we're creating a oneshot script, inside the file we'll just write "oneshot":
nano /etc/s6-overlay/s6-rc.d/iptableRestoreOneshot/type

Contents of /etc/s6-overlay/s6-rc.d/iptableRestoreOneshot/type:
oneshot

  1. Create an "up" script to call your Bash script:
nano /etc/s6-overlay/s6-rc.d/iptableRestoreOneshot/up

Contents of /etc/s6-overlay/s6-rc.d/iptableRestoreOneshot/up:

foreground { echo "Calling restoreIPtables.sh..." }
/usr/local/bin/restoreIPtables.sh
  1. Add the name of the directory that we just created (in my example, "iptableRestoreOneshot") to the user bundle in /etc/s6-overlay/s6-rc.d/user/contents.d/. Note that this is simply a blank file:
touch /etc/s6-overlay/s6-rc.d/user/contents.d/iptableRestoreOneshot

That's it! When your Docker container starts, your oneshot script will be run.

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to The Engineer's Workshop.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.