Skip to content

Commit

Permalink
Merge pull request #5 from dubo-dubon-duponey/work
Browse files Browse the repository at this point in the history
Work
  • Loading branch information
dubo-dubon-duponey committed Dec 19, 2019
2 parents 4636abe + da5d81b commit d86b90d
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 39 deletions.
12 changes: 12 additions & 0 deletions .github/FUNDING.yml
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: [dubo-dubon-duponey] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
104 changes: 104 additions & 0 deletions DEVELOP.md
@@ -0,0 +1,104 @@
# Hackers zone

## Build from source

### TL;DR

```bash
VENDOR=you
IMAGE_NAME=super_image
IMAGE_TAG=sometag
./build.sh
```

### The what

This image is built using `dubodubonduponey/base:builder-$DEBIAN_DATE` and its runtime uses `dubodubonduponey/base:runtime-$DEBIAN_DATE`.

Both these images are built upon `dubodubonduponey/debian:$DEBIAN_DATE`, a debootstrapped version of Debian Buster, built from a Debian snapshot at `$DEBIAN_DATE`.

At the time of this writing, `DEBIAN_DATE` evaluates to `2019-12-01`, and is updated every 15 days.

You can find out more here:

* https://github.com/dubo-dubon-duponey/docker-debian for the debootstrapped Debian base
* https://github.com/dubo-dubon-duponey/docker-base for the builder and runtime images

These images provide very little - they are (mostly) barebone Buster with metadata and some ONBUILD
Docker syntactic sugar (metadata, user creation, entrypoint).

Let me repeat: you have very little reason to go and add anything up there.

### Configuration reference

```bash
# Controls to which registry your image gets pushed (default to Docker Hub if left unspecified)
REGISTRY="registry-1.docker.io"

# "Vendor" name of the image (eg: `REGISTRY/VENDOR/IMAGE`)
VENDOR="dubodubonduponey"

# Image name (as in `REGISTRY/VENDOR/IMAGE`)
IMAGE_NAME="super_image"

# Tag name to publish
IMAGE_TAG="v1"

# Image metadata (applied through labels)
TITLE="My super image title"
DESCRIPTION="My super image description"

# Platforms you want to target (note: certain platforms may be unavailable for the underlying software)
PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6}"

# Base debian image date to use (from our own base images)
DEBIAN_DATE=2019-12-01

# Controls which user-id to assign to the in-container user
BUILD_UID=2000
```

### Behavior control

```bash
# Do NOT push the built image if left empty (useful for debugging) - default to true
PUSH=
# Do NOT use buildkit cache if left empty - default to true
CACHE=

```

## Develop

### TL;DR

Hack away.

Be sure to run `./test.sh` before submitting anything.

### Philosophy

* keep it simple
* entrypoint should be kept self-contained
* minimize runtime dependencies
* base images should be kept dead simple
* one process per container (letsencrypt refresh being the only exception)
* unrelated ops should go elsewhere
* advanced logging infrastructure does not belong inside a container
* no init system, failing containers should fail, exit, and be handled from the outside
* keep it secure
* no root
* no write
* no cap
* use existing infrastructure
* runnable artifacts go to:
* `/boot/bin` (read-only)
* configuration goes to:
* `/config` (read-only)
* certificates go to:
* `/certs` (read-write)
* persistent application data goes to:
* `/data` (read-write)
* volatile data go to:
* `/tmp` (read-write)
* only use chroot if you really REALLY need root first
23 changes: 17 additions & 6 deletions Dockerfile
Expand Up @@ -36,20 +36,32 @@ WORKDIR /build/librespot
RUN git checkout $LIBRESPOT_VER
RUN cargo build -Z unstable-options --release --out-dir /dist/boot/bin --no-default-features --features alsa-backend

COPY --from=builder-healthcheck /dist/boot/bin /dist/boot/bin

RUN rm /dist/boot/bin/liblibrespot.rlib
RUN chmod 555 /dist/boot/bin/*

WORKDIR /dist/boot/lib/
RUN cp /usr/lib/"$(gcc -dumpmachine)"/libasound.so.2 .
COPY --from=builder-healthcheck /dist/boot/bin /dist/boot/bin
RUN chmod 555 /dist/boot/bin/*

#######################
# Running image
#######################
# hadolint ignore=DL3006
FROM $RUNTIME_BASE

USER root

ARG DEBIAN_FRONTEND="noninteractive"
ENV TERM="xterm" LANG="C.UTF-8" LC_ALL="C.UTF-8"
RUN apt-get update -qq \
&& apt-get install -qq --no-install-recommends \
libasound2=1.1.8-1 \
&& apt-get -qq autoremove \
&& apt-get -qq clean \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/* \
&& rm -rf /var/tmp/*

USER dubo-dubon-duponey

COPY --from=builder --chown=$BUILD_UID:root /dist .

ENV NAME=Sproutify
Expand All @@ -58,7 +70,6 @@ ENV HEALTHCHECK_URL="http://127.0.0.1:$PORT/?action=getInfo"

EXPOSE $PORT/tcp

VOLUME /data
VOLUME /tmp

HEALTHCHECK --interval=30s --timeout=30s --start-period=10s --retries=1 CMD http-health || exit 1
50 changes: 24 additions & 26 deletions README.md
Expand Up @@ -34,12 +34,13 @@ This is useful in the following scenarios:
The following is the most straight-forward example, using host networking:

```bash
docker run -d \
docker run -d --rm \
--name "spot" \
--env "NAME=Super Name For Your Spotify Connect Endpoint" \
--net host \
--device /dev/snd \
--volume /tmp \
--group-add audio \
--device /dev/snd \
--net host \
--cap-drop ALL \
--read-only \
dubodubonduponey/librespot:v1
Expand All @@ -49,34 +50,23 @@ docker run -d \

### Networking

Since the Spotify Connect protocol uses bonjour for discovery, you have to use host networking, or alternatively mac-(or ip)-vlan.

### Configuration reference

#### Runtime

You may specify the following environment variables at runtime:

* `NAME` (eg: `Totale Croquette`) controls the "name" under which your endpoint will appear in Spotify

You can also tweak the following for control over which internal ports are being used:

* `PORT` (eg: `10042`) controls the port used by the http command endpoint
You need to run this in `host` or `mac(or ip)vlan` networking (because of mDNS).

Of course using any privileged port for that would require CAP_NET_BIND_SERVICE and a `--user=root` (not recommended...).
### Additional arguments

Finally, any additional arguments provided when running the image will get fed to the `librespot` binary.
Any additional arguments when running the image will get fed to the `librespot` binary.

This is specifically relevant if you need to select a different alsa device, card or mixer, or use another librespot option.

Here is an example:
```bash
docker run -d \
docker run -d --rm \
--name "spot" \
--env "NAME=Super Name For Your Spotify Connect Endpoint" \
--net host \
--device /dev/snd \
--volume /tmp \
--group-add audio \
--device /dev/snd \
--net host \
--cap-drop ALL \
--read-only \
dubodubonduponey/librespot:v1 \
Expand All @@ -92,10 +82,18 @@ docker run --rm \
--help
```

#### Build time
### Custom configuration

You may specify the following environment variables at runtime:

* `NAME` (eg: `Totale Croquette`) controls the "name" under which your endpoint will appear in Spotify

You can also tweak the following for control over which internal ports are being used:

* `PORT` (eg: `10042`) controls the port used by the http command endpoint

Of course using any privileged port for that would require `CAP_NET_BIND_SERVICE` and a `--user=root` (not recommended...).

You can rebuild the image using the following build arguments:
## Moar?

* `BUILD_UID`

So to control which user-id to assign to the in-container user (default is 2000).
See [DEVELOP.md](DEVELOP.md)
9 changes: 2 additions & 7 deletions runtime/boot/entrypoint.sh
Expand Up @@ -4,15 +4,10 @@ set -o errexit -o errtrace -o functrace -o nounset -o pipefail
NAME=${NAME:-no name}
PORT=${PORT:-10042}

# Ensure the certs folder is writable
[ -w "/data" ] || {
>&2 printf "/data is not writable. Check your mount permissions.\n"
exit 1
}

# Ensure the folder is writable
[ -w "/tmp" ] || {
>&2 printf "/tmp is not writable. Check your mount permissions.\n"
exit 1
}

exec librespot --cache /data/cache --name "$NAME" --bitrate 320 --device-type speaker --zeroconf-port "$PORT" "$@"
exec librespot --cache /tmp/cache --name "$NAME" --bitrate 320 --device-type speaker --zeroconf-port "$PORT" "$@"

0 comments on commit d86b90d

Please sign in to comment.