diff --git a/Dockerfile b/Dockerfile index 3fe9da2f..e91f5829 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,11 +23,46 @@ RUN set -xe && \ export COMMIT_SHA=${COMMIT_SHA:-$(git describe --always --dirty)} && \ go build $(if [ -n "${FEATURES}" ]; then echo "-tags ${FEATURES}"; fi) -ldflags "-s -w -X github.com/drakkan/sftpgo/version.commit=${COMMIT_SHA} -X github.com/drakkan/sftpgo/version.date=`date -u +%FT%TZ`" -v -o sftpgo +# install gosu +ENV GOSU_VERSION 1.12 + +RUN set -eux; \ +# save list of currently installed packages for later so we can clean up + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends ca-certificates wget; \ + if ! command -v gpg; then \ + apt-get install -y --no-install-recommends gnupg2 dirmngr; \ + elif gpg --version | grep -q '^gpg (GnuPG) 1\.'; then \ +# "This package provides support for HKPS keyservers." (GnuPG 1.x only) + apt-get install -y --no-install-recommends gnupg-curl; \ + fi; \ + rm -rf /var/lib/apt/lists/*; \ + \ + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ + wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ + wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ + \ +# verify the signature + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ + gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ + command -v gpgconf && gpgconf --kill all || :; \ + rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ + \ +# clean up fetch dependencies + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ + chmod +x /usr/local/bin/gosu; \ +# verify that the binary works + gosu --version; \ + gosu nobody true + FROM debian:buster-slim -RUN apt-get update && apt-get install --no-install-recommends -y ca-certificates mime-support && apt-get clean - -SHELL ["/bin/bash", "-c"] +RUN apt-get update && apt-get install --no-install-recommends -y ca-certificates mime-support && rm -rf /var/lib/apt/lists/* RUN mkdir -p /etc/sftpgo /var/lib/sftpgo /usr/share/sftpgo /srv/sftpgo @@ -37,12 +72,13 @@ RUN groupadd --system -g 1000 sftpgo && \ --comment "SFTPGo user" --uid 1000 sftpgo # Install some optional packages used by SFTPGo features -RUN apt-get update && apt-get install --no-install-recommends -y git rsync && apt-get clean +RUN apt-get update && apt-get install --no-install-recommends -y git rsync && apt-get clean && rm -rf /var/lib/apt/lists/* COPY --from=builder /workspace/sftpgo.json /etc/sftpgo/sftpgo.json COPY --from=builder /workspace/templates /usr/share/sftpgo/templates COPY --from=builder /workspace/static /usr/share/sftpgo/static COPY --from=builder /workspace/sftpgo /usr/local/bin/ +COPY --from=builder /usr/local/bin/gosu /usr/local/bin/ # Log to the stdout so the logs will be available using docker logs ENV SFTPGO_LOG_FILE_PATH="" @@ -55,11 +91,14 @@ RUN sed -i "s|\"users_base_dir\": \"\",|\"users_base_dir\": \"/srv/sftpgo/data\" sed -i "s|\"backups\"|\"/srv/sftpgo/backups\"|" /etc/sftpgo/sftpgo.json && \ sed -i "s|\"bind_address\": \"127.0.0.1\",|\"bind_address\": \"\",|" /etc/sftpgo/sftpgo.json -RUN chown -R sftpgo:sftpgo /etc/sftpgo && chown sftpgo:sftpgo /var/lib/sftpgo /srv/sftpgo +COPY ./docker/scripts/entrypoint.sh /docker-entrypoint.sh + +RUN chown -R sftpgo:sftpgo /etc/sftpgo && chown sftpgo:sftpgo /var/lib/sftpgo /srv/sftpgo && \ + chmod 755 /docker-entrypoint.sh WORKDIR /var/lib/sftpgo -USER 1000:1000 VOLUME [ "/var/lib/sftpgo", "/srv/sftpgo" ] -CMD sftpgo serve +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["sftpgo", "serve"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine index c9e2e9b8..6f178cbc 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -28,9 +28,7 @@ RUN set -xe && \ FROM alpine:3.12 -RUN apk add --update --no-cache ca-certificates tzdata bash mailcap - -SHELL ["/bin/bash", "-c"] +RUN apk add --update --no-cache ca-certificates tzdata bash mailcap su-exec # set up nsswitch.conf for Go's "netgo" implementation # https://github.com/gliderlabs/docker-alpine/issues/367#issuecomment-424546457 @@ -39,7 +37,7 @@ RUN test ! -e /etc/nsswitch.conf && echo 'hosts: files dns' > /etc/nsswitch.conf RUN mkdir -p /etc/sftpgo /var/lib/sftpgo /usr/share/sftpgo /srv/sftpgo RUN addgroup -g 1000 -S sftpgo && \ - adduser -u 1000 -h /var/lib/sftpgo -s /sbin/nologin -G sftpgo -S -D -H sftpgo + adduser -u 1000 -h /var/lib/sftpgo -s /sbin/nologin -G sftpgo -S -D -H -g "SFTPGo user" sftpgo # Install some optional packages used by SFTPGo features RUN apk add --update --no-cache rsync git @@ -60,11 +58,14 @@ RUN sed -i "s|\"users_base_dir\": \"\",|\"users_base_dir\": \"/srv/sftpgo/data\" sed -i "s|\"backups\"|\"/srv/sftpgo/backups\"|" /etc/sftpgo/sftpgo.json && \ sed -i "s|\"bind_address\": \"127.0.0.1\",|\"bind_address\": \"\",|" /etc/sftpgo/sftpgo.json -RUN chown -R sftpgo:sftpgo /etc/sftpgo && chown sftpgo:sftpgo /var/lib/sftpgo /srv/sftpgo +COPY ./docker/scripts/entrypoint-alpine.sh /docker-entrypoint.sh + +RUN chown -R sftpgo:sftpgo /etc/sftpgo && chown sftpgo:sftpgo /var/lib/sftpgo /srv/sftpgo && \ + chmod 755 /docker-entrypoint.sh WORKDIR /var/lib/sftpgo -USER 1000:1000 VOLUME [ "/var/lib/sftpgo", "/srv/sftpgo" ] -CMD sftpgo serve +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["sftpgo", "serve"] diff --git a/docker/README.md b/docker/README.md index ec4cbeed..57d08e24 100644 --- a/docker/README.md +++ b/docker/README.md @@ -98,6 +98,11 @@ docker run --name some-sftpgo \ -d "drakkan/sftpgo:tag" ``` +Alternately you can set the following environment variables: + +- `SFTPGO_PUID`, sets the numeric user ID to use +- `SFTPGO_PGID`, sets the numeric group ID to use + ## Image Variants The `sftpgo` images comes in many flavors, each designed for a specific use case. The `edge` and `edge-alpine`tags are updated after each new commit. diff --git a/docker/scripts/entrypoint-alpine.sh b/docker/scripts/entrypoint-alpine.sh new file mode 100755 index 00000000..5862b45f --- /dev/null +++ b/docker/scripts/entrypoint-alpine.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +SFTPGO_PUID=${SFTPGO_PUID:-1000} +SFTPGO_PGID=${SFTPGO_PGID:-1000} + +if [ "$1" = 'sftpgo' ]; then + if [ "$(id -u)" = '0' ]; then + for DIR in "/etc/sftpgo" "/var/lib/sftpgo" "/srv/sftpgo" + do + DIR_UID=$(stat -c %u ${DIR}) + DIR_GID=$(stat -c %g ${DIR}) + if [ ${DIR_UID} != ${SFTPGO_PUID} ] || [ ${DIR_GID} != ${SFTPGO_PGID} ]; then + echo `date +%Y-%m-%dT%H:%M:%S` - "entrypoint, change owner for ${DIR} uid: ${SFTPGO_PUID} gid: ${SFTPGO_PGID}" + if [ ${DIR} = "/etc/sftpgo" ]; then + chown -R ${SFTPGO_PUID}:${SFTPGO_PGID} ${DIR} + else + chown ${SFTPGO_PUID}:${SFTPGO_PGID} ${DIR} + fi + fi + done + echo `date +%Y-%m-%dT%H:%M:%S` - "entrypoint, run as uid: ${SFTPGO_PUID} gid: ${SFTPGO_PGID}" + exec su-exec ${SFTPGO_PUID}:${SFTPGO_PGID} "$@" + fi + + exec "$@" +fi + +exec "$@" \ No newline at end of file diff --git a/docker/scripts/entrypoint.sh b/docker/scripts/entrypoint.sh new file mode 100755 index 00000000..8d5d07c7 --- /dev/null +++ b/docker/scripts/entrypoint.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +SFTPGO_PUID=${SFTPGO_PUID:-1000} +SFTPGO_PGID=${SFTPGO_PGID:-1000} + +if [ "$1" = 'sftpgo' ]; then + if [ "$(id -u)" = '0' ]; then + getent passwd ${SFTPGO_PUID} > /dev/null + HAS_PUID=$? + getent group ${SFTPGO_PGID} > /dev/null + HAS_PGID=$? + if [ ${HAS_PUID} -ne 0 ] || [ ${HAS_PGID} -ne 0 ]; then + echo `date +%Y-%m-%dT%H:%M:%S.%3N` - "entrypoint, prepare to run as uid: ${SFTPGO_PUID} gid: ${SFTPGO_PGID}" + if [ ${HAS_PGID} -ne 0 ]; then + echo `date +%Y-%m-%dT%H:%M:%S.%3N` - "entrypoint, set GID to: ${SFTPGO_PGID}" + groupmod -g ${SFTPGO_PGID} sftpgo + fi + if [ ${HAS_PUID} -ne 0 ]; then + echo `date +%Y-%m-%dT%H:%M:%S.%3N` - "entrypoint, set UID to: ${SFTPGO_PUID}" + usermod -u ${SFTPGO_PUID} sftpgo + fi + chown -R ${SFTPGO_PUID}:${SFTPGO_PGID} /etc/sftpgo + chown ${SFTPGO_PUID}:${SFTPGO_PGID} /var/lib/sftpgo /srv/sftpgo + fi + echo `date +%Y-%m-%dT%H:%M:%S.%3N` - "entrypoint, run as uid: ${SFTPGO_PUID} gid: ${SFTPGO_PGID}" + exec gosu ${SFTPGO_PUID}:${SFTPGO_PGID} "$@" + fi + + exec "$@" +fi + +exec "$@" \ No newline at end of file