Docker setup relies on host mapped ports and OpenSSH being available on the host

In our setup, a dedicated IP address for boringproxy is served from another network interface than the Docker host system’s.

This setup is now working for us:

diff --git a/Dockerfile b/Dockerfile
index 90afd94..8131cd9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,16 +17,20 @@ RUN if [[ "ORIGIN" == 'remote' ]] ; then git clone --depth 1 --branch "${BRANCH}
 COPY go.* ./
 RUN go mod download
 COPY . .
+COPY ./default_logo.png ./logo.png
 
 RUN cd cmd/boringproxy && CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} \
        go build -ldflags "-X main.Version=${VERSION}" \
        -o boringproxy
 
-FROM scratch
-EXPOSE 80 443
+FROM alpine:latest
+EXPOSE 22 80 443
 WORKDIR /storage
 
+RUN apk add --update --no-cache openssh shadow
+RUN usermod -p '*' root
+
 COPY --from=builder /build/cmd/boringproxy/boringproxy /
+COPY entrypoint.sh /
 
-ENTRYPOINT ["/boringproxy"]
-CMD ["version"]
\ No newline at end of file
+ENTRYPOINT ["/entrypoint.sh"]

With entrypoint.sh being chmod +x -v entrypoint.sh’ed and reading as:

#!/bin/sh

ssh-keygen -A

exec /usr/sbin/sshd -D -e &
exec /boringproxy "$@"

wait -n
  
exit $?

And everything coming together through an environment

IPV4=
IPV6=
ADMIN_DOMAIN=
ACME_EMAIL=
USER=root

and a Compose:

version: '3.7'

services:

  server:
    build:
      context: ./context/boringproxy
    image: boringproxy
    command: "server -admin-domain ${ADMIN_DOMAIN} -acme-email ${ACME_EMAIL} -accept-ca-terms -cert-dir /storage/certmagic -print-login -public-ip ${IPV4}"
    network_mode: bridge
    ports:
      - "${IPV4}:22:22"
      - "${IPV4}:80:80"
      - "${IPV4}:443:443"
      - "${IPV6}:22:22"
      - "${IPV6}:80:80"
      - "${IPV6}:443:443"
    volumes:
      - /etc/ssl/certs/:/etc/ssl/certs/:ro
      - ./.state/ssh:/root/.ssh
      - ./.state/sshd:/etc/ssh
      - ./.state/storage:/storage
    environment:
      ADMIN_DOMAIN: ${ADMIN_DOMAIN}
      ACME_EMAIL: ${ACME_EMAIL}
      USER: ${USER}

This is missing out, how sshd_config in the /etc/ssh mount came about: docker cp’ed from a container without that host-mapped volume, and then edited, and put back in place.

This is a more “container-native” BoringProxy setup, which does not make assumptions about its host, but to have a separate IP address available for itself. This must be present as a separate network interface on the host system to bind the ports to.

It is not a perfect container setup, as we wouldn’t want to run multiple processes in the same container. Yet the previous experiment with such

did not work out very well. The error when not having its local tunnels available through 127.0.0.1 could probably be circumvented with a custom IP of the SSH server provided to the server command, or a so-called ambassador container (netcat), which could listen on all three desired ports, and forward them respectively to the others.