Skip to content

Commit

Permalink
Update readme and example init
Browse files Browse the repository at this point in the history
  • Loading branch information
thespad committed Jul 31, 2022
1 parent 04365c7 commit c7a8f29
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 15 deletions.
115 changes: 105 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ In this repository we will be going over two basic methods of making a Mod along

One of the core ideas to remember when creating a Mod is that it can only contain a single image layer, the examples below will show you how to add files standardly and how to run complex logic to assemble the files in a build layer to copy them over into this single layer.

### Mod Types

We now support "hybrid" mods, targeting both s6 v2 and v3. All currently supported Linuxserver base images are using s6 v3, however, older pinned images, forked versions, etc. may still be using v2. To support both cases, simply include both sets of files (as below) in your mod, the built-in mod logic will pick the appropriate files to run. v2 mods will run on v3 base images for the forseeable future but we will not provide support for that configuration.

### Docker Mod Simple - just add scripts

In this repository you will find the `Dockerfile` containing:
Expand All @@ -70,12 +74,103 @@ COPY root/ /

For most users this will suffice and anything in the root/ folder of the repository will be added to the end users Docker container / path.

The most common paths to leverage for Linuxserver images will be:
#### Legacy (v2) mods

The most common paths to leverage for Linuxserver images are as follows. Assuming a mod name of `universal-mymod`:

```text
.
└── root
└── etc
├── cont-init.d
│ ├── 95-apt-get
│ └── 98-universal-mymod -- This is the init logic script that runs before the services in the container. It needs to be `chmod +x` and is run ordered by filename.
└── services.d
└── mymod
└── run -- This is the script that runs in the foreground for persistent services. It needs to be `chmod +x`.
```

* root/etc/cont-init.d/<98-script-name> - Contains init logic scripts that run before the services in the container start these should exit 0 and are ordered by filename
* root/etc/services.d/`yourservice`/run - Contains scripts that run in the foreground for persistent services IE NGINX
* root/etc/services.d/yourservice/run - Contains scripts that run in the foreground for persistent services IE NGINX
* root/defaults - Contains base config files that are copied/modified on first spinup

#### New (v3) mods

The most common paths to leverage for Linuxserver images are as follows. Assuming a mod name of `universal-mymod`:

```text
.
└── root
└── etc
└── s6-overlay
└── s6-rc.d
├── init-mods-end
│ └── dependencies.d
│ └── init-mods-universal-mymod
├── init-mods-package-install
│ └── dependencies.d
│ └── init-mods-universal-mymod
├── init-mods-universal-mymod
│ ├── dependencies.d
│ │ └── init-mods
│ ├── run -- This is the init logic script that runs before the services in the container. It needs to be `chmod +x`.
│ ├── type -- This should container the string `oneshot`.
│ └── up -- This should contain the absolute path to `run` e.g. `/etc/s6-overlay/s6-rc.d/init-mods-universal-mymod/run`.
├── svc-mods-universal-mymod
│ ├── dependencies.d
│ │ └── init-services
│ ├── run -- This is the script that runs in the foreground for persistent services. It needs to be `chmod +x`.
│ └── type -- This should contain the string `longrun`.
└── user
└── contents.d
├── init-mods-universal-mymod
└── svc-mods-universal-mymod
```

Note: For `oneshot` scripts you can alternatively omit the `run` file entirely and use the [execlineb](https://skarnet.org/software/execline/execlineb.html) syntax in `up` if your requirements are simple enough.

#### Installing Packages

v3 mods make use of a single package install process for all mods to minimise the amount of calls to external endpoints and speed up the mod init process. If you need to install repo packages you should append them to `/mod-repo-packages-to-install.list` for repo packages or `/mod-pip-packages-to-install.list` for pip packages and the mod handler will install them for you. Make sure to handle both Ubuntu and Alpine package names if your mod needs to support both e.g.

```bash
#!/usr/bin/with-contenv bash

## Ubuntu
if [ -f /usr/bin/apt ]; then
echo "\
dnsutils \
net-tools \
iputils-ping \
traceroute" >> /mod-repo-packages-to-install.list

fi
# Alpine
if [ -f /sbin/apk ]; then
echo "\
bind-tools \
net-tools" >> /mod-repo-packages-to-install.list
fi
```

If your mod needs to take additional config steps *after* the packages have been installed, add a second `oneshot` script and make it depend on `init-mods-package-install` e.g.

```text
.
└── root
└── etc
└── s6-overlay
└── s6-rc.d
└── init-mods-universal-mymod-postinstall
├── dependencies.d
│ └── init-mods-package-install
├── run
├── type
└── up
```

Services will always run last, controlled by their dependency on `init-services`.

The example files in this repo contain a script to install sshutil and a service file to run the installed utility.

### Docker Mod Complex - Sky is the limit
Expand All @@ -87,14 +182,14 @@ In this repository you will find the `Dockerfile.complex` containing:
FROM ghcr.io/linuxserver/baseimage-alpine:3.12 as buildstage

RUN \
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** grab rclone ****" && \
mkdir -p /root-layer && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** grab rclone ****" && \
mkdir -p /root-layer && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"

# copy local files
COPY root/ /root-layer/
Expand Down
7 changes: 2 additions & 5 deletions root/etc/cont-init.d/98-vpn-config
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/with-contenv bash

# Determine if setup is needed
if [ ! -f /usr/local/lib/python***/dist-packages/sshuttle ] && \
[ -f /usr/bin/apt ]; then
if [ -f /usr/bin/apt ]; then
## Ubuntu
apt-get update
apt-get install --no-install-recommends -y \
Expand All @@ -12,8 +10,7 @@ if [ ! -f /usr/local/lib/python***/dist-packages/sshuttle ] && \
python3-pip
pip3 install sshuttle
fi
if [ ! -f /usr/lib/python***/site-packages/sshuttle ] && \
[ -f /sbin/apk ]; then
if [ -f /sbin/apk ]; then
# Alpine
apk add --no-cache \
iptables \
Expand Down
Empty file.
Empty file.
25 changes: 25 additions & 0 deletions root/etc/s6-overlay/s6-rc.d/init-mods-universal-sshvpn/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/with-contenv bash

if [ -f /usr/bin/apt ]; then
## Ubuntu
echo "\
iptables \
openssh-client \
python3 \
python3-pip" >> /mod-repo-packages-to-install.list
fi

if [ -f /sbin/apk ]; then
# Alpine
echo "\
iptables \
openssh \
python3 \
py3-pip" >> /mod-repo-packages-to-install.list
fi

echo "\
sshuttle" >> /mod-pip-packages-to-install.list

chown -R root:root /root
chmod -R 600 /root/.ssh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
oneshot
1 change: 1 addition & 0 deletions root/etc/s6-overlay/s6-rc.d/init-mods-universal-sshvpn/up
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/etc/s6-overlay/s6-rc.d/init-mods-universal-sshvpn/run
Empty file.
3 changes: 3 additions & 0 deletions root/etc/s6-overlay/s6-rc.d/svc-mods-universal-sshvpn/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/with-contenv bash

sshuttle --dns --remote root@${HOST}:${PORT} 0/0 -x 172.17.0.0/16
1 change: 1 addition & 0 deletions root/etc/s6-overlay/s6-rc.d/svc-mods-universal-sshvpn/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun
Empty file.
Empty file.
Empty file modified root/etc/services.d/sshvpn/run
100644 → 100755
Empty file.

0 comments on commit c7a8f29

Please sign in to comment.