Merge pull request #196 from linuxserver/universal-docker-in-docker-dev

universal-dind: initial release
This commit is contained in:
saarg 2021-04-07 07:03:00 +02:00 committed by GitHub
commit b4956e94a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 172 additions and 79 deletions

View File

@ -3,9 +3,9 @@ name: Build Image
on: [push, pull_request, workflow_dispatch]
env:
ENDPOINT: "linuxserver/mods" #don't modify
BASEIMAGE: "replace_baseimage" #replace
MODNAME: "replace_modname" #replace
ENDPOINT: "linuxserver/mods"
BASEIMAGE: "universal"
MODNAME: "docker-in-docker"
jobs:
build:
@ -15,16 +15,29 @@ jobs:
- name: Build image
run: |
docker build --no-cache -t ${{ github.sha }} .
# Set version
if [ -z ${COMPOSE_TAG+x} ]; then COMPOSE_TAG=$(curl -sX GET "https://api.github.com/repos/linuxserver/docker-docker-compose/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]'); fi
if [ -z ${COMPOSE_ALPINE_TAG+x} ]; then COMPOSE_ALPINE_TAG=$(curl -sX GET "https://api.github.com/repos/linuxserver/docker-docker-compose/releases" | jq -r 'first(.[] | select(.prerelease==true)) | .tag_name'); fi
COMPOSE_VERSION=$(echo "$COMPOSE_TAG" | sed 's|-ls.*||g')
echo "COMPOSE_VERSION=${COMPOSE_VERSION}" >> $GITHUB_ENV
COMPOSE_ALPINE_VERSION="$(echo ${COMPOSE_ALPINE_TAG} | sed 's|-ls.*||g' | sed 's|alpine-||g')"
if [ "$COMPOSE_VERSION" != "$COMPOSE_ALPINE_VERSION" ]; then echo "ubuntu and alpine versions are different; exiting!" && exit 1; else echo "ubuntu and alpine versions are the same, continuing with build"; fi
if [ -z ${DOCKER_RELEASE+x} ]; then DOCKER_RELEASE=$(curl -sX GET "https://api.github.com/repos/moby/moby/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]' | sed 's|^v||'); fi
if curl -fSsL "https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_RELEASE}.tgz" >/dev/null && curl -fSsL "https://download.docker.com/linux/static/stable/armhf/docker-${DOCKER_RELEASE}.tgz" >/dev/null && curl -fSsL "https://download.docker.com/linux/static/stable/aarch64/docker-${DOCKER_RELEASE}.tgz" >/dev/null; then echo "Docker tarballs exist, proceeding"; else echo "Docker tarballs are missing, exiting!" && exit 1; fi
echo "COMBINED_TAG=${DOCKER_RELEASE}-${COMPOSE_VERSION}" >> $GITHUB_ENV
# Build image
docker build --no-cache --build-arg COMPOSE_TAG=${COMPOSE_TAG} --build-arg COMPOSE_ALPINE_TAG=${COMPOSE_ALPINE_TAG} --build-arg DOCKER_RELEASE=${DOCKER_RELEASE} -t ${{ github.sha }} .
- name: Tag image
if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) }}
run: |
docker tag ${{ github.sha }} ${ENDPOINT}:${BASEIMAGE}-${MODNAME}
docker tag ${{ github.sha }} ${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}
docker tag ${{ github.sha }} ${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}-${{ github.sha }}
docker tag ${{ github.sha }} ${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ github.sha }}
docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}
docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}
docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}-${{ github.sha }}
docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ github.sha }}
- name: Credential check
if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) }}
run: |
@ -38,25 +51,25 @@ jobs:
echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions."
exit 1
fi
- name: Login to GitHub Container Registry
if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) && env.CR_USER && env.CR_PAT }}
run: |
echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin
- name: Push tags to GitHub Container Registry
if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) && env.CR_USER && env.CR_PAT }}
run: |
docker push ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}
docker push ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}-${{ github.sha }}
docker push ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ github.sha }}
docker push ghcr.io/${ENDPOINT}:${BASEIMAGE}-${MODNAME}
- name: Login to DockerHub
if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) && env.DOCKERUSER && env.DOCKERPASS }}
run: |
echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin
- name: Push tags to DockerHub
if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) && env.DOCKERUSER && env.DOCKERPASS }}
run: |
docker push ${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}
docker push ${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ env.COMBINED_TAG }}-${{ github.sha }}
docker push ${ENDPOINT}:${BASEIMAGE}-${MODNAME}-${{ github.sha }}
docker push ${ENDPOINT}:${BASEIMAGE}-${MODNAME}

View File

@ -1,6 +1,52 @@
FROM scratch
## Buildstage ##
ARG DOCKER_RELEASE
ARG COMPOSE_TAG="latest"
ARG COMPOSE_ALPINE_TAG="alpine"
LABEL maintainer="username"
FROM ghcr.io/linuxserver/docker-compose:amd64-${COMPOSE_TAG} as compose-amd64
FROM ghcr.io/linuxserver/docker-compose:arm32v7-${COMPOSE_TAG} as compose-arm32
FROM ghcr.io/linuxserver/docker-compose:arm64v8-${COMPOSE_TAG} as compose-arm64
FROM ghcr.io/linuxserver/docker-compose:amd64-${COMPOSE_ALPINE_TAG} as compose-alpine-amd64
FROM ghcr.io/linuxserver/docker-compose:arm32v7-${COMPOSE_ALPINE_TAG} as compose-alpine-arm32
FROM ghcr.io/linuxserver/docker-compose:arm64v8-${COMPOSE_ALPINE_TAG} as compose-alpine-arm64
FROM ghcr.io/linuxserver/baseimage-alpine:3.13 as buildstage
RUN \
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** retrieve latest version ****" && \
if [ -z ${DOCKER_RELEASE+x} ]; then \
DOCKER_RELEASE=$(curl -sX GET "https://api.github.com/repos/moby/moby/releases/latest" \
| awk '/tag_name/{print $4;exit}' FS='[""]' \
| sed 's|^v||'); \
fi && \
echo "**** grab docker ****" && \
mkdir -p /root-layer/docker-tgz && \
curl -fo \
/root-layer/docker-tgz/docker_x86_64.tgz -L \
"https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_RELEASE}.tgz" && \
curl -fo \
/root-layer/docker-tgz/docker_armv7l.tgz -L \
"https://download.docker.com/linux/static/stable/armhf/docker-${DOCKER_RELEASE}.tgz" && \
curl -fo \
/root-layer/docker-tgz/docker_aarch64.tgz -L \
"https://download.docker.com/linux/static/stable/aarch64/docker-${DOCKER_RELEASE}.tgz"
# copy local files
COPY root/ /
COPY --from=compose-amd64 /usr/local/bin/docker-compose /root-layer/docker-compose-ubuntu/docker-compose_x86_64
COPY --from=compose-arm32 /usr/local/bin/docker-compose /root-layer/docker-compose-ubuntu/docker-compose_armv7l
COPY --from=compose-arm64 /usr/local/bin/docker-compose /root-layer/docker-compose-ubuntu/docker-compose_aarch64
COPY --from=compose-alpine-amd64 /usr/local/bin/docker-compose /root-layer/docker-compose-alpine/docker-compose_x86_64
COPY --from=compose-alpine-arm32 /usr/local/bin/docker-compose /root-layer/docker-compose-alpine/docker-compose_armv7l
COPY --from=compose-alpine-arm64 /usr/local/bin/docker-compose /root-layer/docker-compose-alpine/docker-compose_aarch64
COPY root/ /root-layer/
## Single layer deployed image ##
FROM scratch
LABEL maintainer="aptalca"
# Add files from buildstage
COPY --from=buildstage /root-layer/ /

View File

@ -1,23 +0,0 @@
## Buildstage ##
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"
# copy local files
COPY root/ /root-layer/
## Single layer deployed image ##
FROM scratch
LABEL maintainer="username"
# Add files from buildstage
COPY --from=buildstage /root-layer/ /

View File

@ -1,17 +1,14 @@
# Rsync - Docker mod for openssh-server
# Docker-in-docker (dind) - Docker mod for Ubuntu and Alpine based images
This mod adds rsync to openssh-server, to be installed/updated during container start.
This mod adds docker-in-docker (dind) to Ubuntu and Alpine based images, to be installed/updated during container start.
Main advantage is that all docker images, containers, volumes, etc. will reside inside the container and will be sandboxed from the host's docker environment.
Main disadvantage is that it requires the container to run with `privileged`.
In openssh-server docker arguments, set an environment variable `DOCKER_MODS=linuxserver/mods:openssh-server-rsync`
## How to enable:
In the container's docker arguments,
* Set an environment variable `DOCKER_MODS=linuxserver/mods:universal-docker-in-docker`
* Set the `privileged` option for the container
If adding multiple mods, enter them in an array separated by `|`, such as `DOCKER_MODS=linuxserver/mods:openssh-server-rsync|linuxserver/mods:openssh-server-mod2`
Docker data root will reside under `/config/var/lib/docker`.
# Mod creation instructions
* Fork the repo, create a new branch based on the branch `template`.
* Edit the `Dockerfile` for the mod. `Dockerfile.complex` is only an example and included for reference; it should be deleted when done.
* Inspect the `root` folder contents. Edit, add and remove as necessary.
* Edit this readme with pertinent info, delete these instructions.
* Finally edit the `.github/workflows/BuildImage.yml`. Customize the build branch, and the vars for `BASEIMAGE` and `MODNAME`.
* Ask the team to create a new branch named `<baseimagename>-<modname>`. Baseimage should be the name of the image the mod will be applied to. The new branch will be based on the `template` branch.
* Submit PR against the branch created by the team.
If adding multiple mods, enter them in an array separated by `|`, such as `DOCKER_MODS=linuxserver/mods:universal-docker-in-docker|linuxserver/mods:universal-mod2`

View File

@ -0,0 +1,57 @@
#!/usr/bin/with-contenv bash
ABC_USER=$(id -nu ${PUID:-911})
mkdir -p /config/{logs/dockerd,var/lib/docker}
chown -R ${ABC_USER}:${ABC_USER} /config/logs
echo "**** installing docker and docker compose ****"
if [ -f /usr/bin/apt ]; then
DISTRONAME="ubuntu"
apt-get update && \
apt-get install -y \
btrfs-progs \
ca-certificates \
curl \
e2fsprogs \
iptables \
openssh-client \
openssl \
pigz \
xfsprogs \
xz-utils
else
DISTRONAME="alpine"
apk add --no-cache \
btrfs-progs \
curl \
e2fsprogs \
e2fsprogs-extra \
ip6tables \
iptables \
openssl \
pigz \
xfsprogs \
xz
fi
ARCH=$(uname -m)
if [ -f "/docker-compose-${DISTRONAME}/docker-compose_${ARCH}" ] ; then
echo "Copying over docker and docker-compose binaries"
mv "/docker-compose-${DISTRONAME}/docker-compose_${ARCH}" /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
rm -rf /docker-compose-ubuntu /docker-compose-alpine
tar xf /docker-tgz/docker_${ARCH}.tgz \
--strip-components=1 -C \
/usr/local/bin/
rm -rf /docker-tgz
else
echo "**** docker and docker-compose already installed, skipping ****"
fi
# delete PID if exists
find /run /var/run -iname 'docker*.pid' -delete || :
# create docker group and add abc to it
groupadd -f docker
if ! id -nG ${ABC_USER} | grep -q "docker"; then
usermod -aG docker ${ABC_USER}
fi

View File

@ -1,27 +0,0 @@
#!/usr/bin/with-contenv bash
# Determine if setup is needed
if [ ! -f /usr/local/lib/python***/dist-packages/sshuttle ] && \
[ -f /usr/bin/apt ]; then
## Ubuntu
apt-get update
apt-get install --no-install-recommends -y \
iptables \
openssh-client \
python3 \
python3-pip
pip3 install sshuttle
fi
if [ ! -f /usr/lib/python***/site-packages/sshuttle ] && \
[ -f /sbin/apk ]; then
# Alpine
apk add --no-cache \
iptables \
openssh \
py3-pip \
python3
pip3 install sshuttle
fi
chown -R root:root /root
chmod -R 600 /root/.ssh

View File

@ -0,0 +1,6 @@
#!/usr/bin/with-contenv bash
ABC_USER=$(id -nu ${PUID:-911})
exec \
s6-setuidgid ${ABC_USER} s6-log n30 s10000000 S30000000 T !"gzip -nq9" /config/logs/dockerd

View File

@ -0,0 +1,27 @@
#!/usr/bin/with-contenv bash
## dind hack from https://github.com/moby/moby/blob/master/hack/dind
export container=docker
if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then
mount -t securityfs none /sys/kernel/security || {
echo 'Could not mount /sys/kernel/security.'
echo 'AppArmor detection and --privileged mode might break.'
}
fi
# Mount /tmp (conditionally)
if ! mountpoint -q /tmp; then
mount -t tmpfs none /tmp
fi
# cgroup v2: enable nesting
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
# move the init process (PID 1) from the root group to the /init group,
# otherwise writing subtree_control fails with EBUSY.
mkdir -p /sys/fs/cgroup/init
echo 1 > /sys/fs/cgroup/init/cgroup.procs
# enable controllers
sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
> /sys/fs/cgroup/cgroup.subtree_control
fi
exec 2>&1 /usr/local/bin/dockerd \
--data-root "/config/var/lib/docker"

View File

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
sshuttle --dns --remote root@${HOST}:${PORT} 0/0 -x 172.17.0.0/16