Docker: Refactor images to be more compatible with prod environments #411 #468

You should now be able to provide UMASK, UID and GID as environment variables
when using our production images. Work in progress.
This commit is contained in:
Michael Mayer 2020-10-04 11:23:01 +02:00
parent 78f2470421
commit 9826e57149
8 changed files with 142 additions and 27 deletions

1
.gitignore vendored
View file

@ -16,6 +16,7 @@
*.log
*.db
*.db-journal
docker-compose.override.yml
# Binaries for programs and plugins
*.exe

View file

@ -1,4 +1,4 @@
FROM photoprism/development:20200825
FROM photoprism/development:20201004
# Set up project directory
WORKDIR "/go/src/github.com/photoprism/photoprism"

View file

@ -20,6 +20,8 @@ services:
security_opt:
- seccomp:unconfined
- apparmor:unconfined
# Uncomment and edit the following line to set a specific user / group id:
# user: "1000:1000"
depends_on:
- photoprism-db
ports:

View file

@ -57,7 +57,8 @@ RUN apt-get update && apt-get upgrade && \
apache2-utils \
seccomp \
libseccomp-dev \
libseccomp2
libseccomp2 \
fonts-roboto
# Install Chromium Browser via .deb
RUN add-apt-repository -y ppa:xalt7x/chromium-deb-vaapi
@ -91,18 +92,21 @@ RUN apt-get update && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set default https://en.wikipedia.org/wiki/Umask
RUN umask 0000
# Install and configure NodeJS Package Manager (npm)
ENV NODE_ENV production
RUN npm install --unsafe-perm=true --allow-root -g npm testcafe chromedriver
RUN npm config set cache ~/.cache/npm
# Install Go
ENV GOLANG_VERSION 1.15
ENV GOLANG_VERSION 1.15.2
RUN set -eux; \
\
url="https://golang.org/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz"; \
wget -O go.tgz "$url"; \
echo "2d75848ac606061efe52a8068d0e647b35ce487a15bb52272c427df485193602 *go.tgz" | sha256sum -c -; \
echo "b49fda1ca29a1946d6bb2a5a6982cf07ccd2aba849289508ee0f9918f6bb4552 *go.tgz" | sha256sum -c -; \
tar -C /usr/local -xzf go.tgz; \
rm go.tgz; \
export PATH="/usr/local/go/bin:$PATH"; \
@ -112,24 +116,36 @@ RUN set -eux; \
ENV GOPATH /go
ENV GOBIN $GOPATH/bin
ENV PATH $GOBIN:/usr/local/go/bin:/root/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV TMPDIR /tmp
ENV GO111MODULE on
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
# Download TensorFlow model and test files
RUN rm -rf /tmp/* && mkdir -p /tmp/photoprism
RUN wget "https://dl.photoprism.org/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip
RUN wget "https://dl.photoprism.org/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip
RUN wget "https://dl.photoprism.org/fixtures/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip
RUN rm -rf /tmp/* && mkdir -p /tmp/photoprism && \
wget "https://dl.photoprism.org/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip && \
wget "https://dl.photoprism.org/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip && \
wget "https://dl.photoprism.org/fixtures/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip
# Install additional tools for development
RUN env GO111MODULE=off /usr/local/go/bin/go get -u github.com/psampaz/go-mod-outdated
RUN env GO111MODULE=off /usr/local/go/bin/go get -u golang.org/x/tools/cmd/goimports
RUN env GO111MODULE=off /usr/local/go/bin/go get -u github.com/tsliwowicz/go-wrk
RUN env GO111MODULE=off /usr/local/go/bin/go get -u github.com/kyoh86/richgo
RUN echo "alias go=richgo" > /root/.bash_aliases
RUN env GO111MODULE=off /usr/local/go/bin/go get -u github.com/psampaz/go-mod-outdated && \
env GO111MODULE=off /usr/local/go/bin/go get -u golang.org/x/tools/cmd/goimports && \
env GO111MODULE=off /usr/local/go/bin/go get -u github.com/tsliwowicz/go-wrk && \
env GO111MODULE=off /usr/local/go/bin/go get -u github.com/kyoh86/richgo && \
env GO111MODULE=off /usr/local/go/bin/go get -u github.com/tianon/gosu && \
echo "alias go=richgo" > /root/.bash_aliases
# MariaDB test database settings
COPY /docker/development/.my.cnf /root/.my.cnf
# Create photoprism user and directory for deployment
RUN useradd photoprism -m -d /photoprism && \
chmod 777 /photoprism && \
echo "alias go=richgo" > /photoprism/.bash_aliases && \
chown -R photoprism:photoprism /photoprism && \
find /go -type d -print0 | xargs -0 chmod 777 && \
find /go -type f -print0 | xargs -0 chmod a+rw
# Copy mysql client config for development
COPY --chown=root:root /docker/development/.my.cnf /root/.my.cnf
COPY --chown=photoprism:photoprism /docker/development/.my.cnf /photoprism/.my.cnf
RUN chmod 644 /root/.my.cnf /photoprism/.my.cnf
# Set up project directory
WORKDIR "/go/src/github.com/photoprism/photoprism"

View file

@ -1,4 +1,4 @@
FROM photoprism/development:20200825 as build
FROM photoprism/development:20201004 as build
# Set up project directory
WORKDIR "/go/src/github.com/photoprism/photoprism"
@ -36,6 +36,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
ffmpeg
# Copy dependencies
COPY --from=build /go/bin/gosu /bin/gosu
COPY --from=build /usr/lib/libtensorflow.so /usr/lib/libtensorflow.so
COPY --from=build /usr/lib/libtensorflow_framework.so /usr/lib/libtensorflow_framework.so
RUN ldconfig
@ -50,12 +51,16 @@ RUN sh -c "echo 'deb http://download.opensuse.org/repositories/graphics:/darktab
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set default umask and create photoprism user
RUN umask 0000 && useradd photoprism -m -d /photoprism
WORKDIR /photoprism
ENV TF_CPP_MIN_LOG_LEVEL 2
ENV PATH /photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV TMPDIR /tmp
# Storage path names
ENV PHOTOPRISM_ASSETS_PATH /photoprism/assets
ENV PHOTOPRISM_ORIGINALS_PATH /photoprism/originals
ENV PHOTOPRISM_IMPORT_PATH /photoprism/import
@ -63,6 +68,33 @@ ENV PHOTOPRISM_STORAGE_PATH /photoprism/storage
ENV PHOTOPRISM_LOG_FILENAME /photoprism/photoprism.log
ENV PHOTOPRISM_PID_FILENAME /photoprism/photoprism.pid
# Defaults for common config values
# See https://docs.photoprism.org/getting-started/config-options/
ENV PHOTOPRISM_DEBUG "false"
ENV PHOTOPRISM_PUBLIC "false"
ENV PHOTOPRISM_READONLY "false"
ENV PHOTOPRISM_UPLOAD_NSFW "true"
ENV PHOTOPRISM_DETECT_NSFW "false"
ENV PHOTOPRISM_EXPERIMENTAL "false"
ENV PHOTOPRISM_SITE_URL "http://localhost:2342/"
ENV PHOTOPRISM_SITE_TITLE "PhotoPrism"
ENV PHOTOPRISM_SITE_CAPTION "Browse Your Life"
ENV PHOTOPRISM_SITE_DESCRIPTION ""
ENV PHOTOPRISM_SITE_AUTHOR ""
ENV PHOTOPRISM_HTTP_HOST "0.0.0.0"
ENV PHOTOPRISM_HTTP_PORT 2342
ENV PHOTOPRISM_SETTINGS_HIDDEN "false"
ENV PHOTOPRISM_DATABASE_DRIVER "sqlite"
ENV PHOTOPRISM_SIDECAR_JSON "true"
ENV PHOTOPRISM_SIDECAR_YAML "true"
ENV PHOTOPRISM_THUMB_FILTER "lanczos"
ENV PHOTOPRISM_THUMB_UNCACHED "false"
ENV PHOTOPRISM_THUMB_SIZE 2048
ENV PHOTOPRISM_THUMB_SIZE_UNCACHED 7680
ENV PHOTOPRISM_JPEG_SIZE 7680
ENV PHOTOPRISM_JPEG_QUALITY 92
ENV PHOTOPRISM_DARKTABLE_PRESETS "false"
# Copy files to /photoprism
COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism
COPY --from=build /root/.photoprism/assets /photoprism/assets
@ -72,9 +104,11 @@ RUN mkdir -p \
/photoprism/originals \
/photoprism/import \
/photoprism/storage/settings \
/photoprism/storage/cache
RUN chmod -R 777 /photoprism
/photoprism/storage/cache && \
chmod 777 /photoprism && \
chown -R photoprism:photoprism /photoprism && \
find /photoprism -type d -print0 | xargs -0 chmod 777 && \
find /photoprism -type f -print0 | xargs -0 chmod a+rw
# Show photoprism version
RUN photoprism -v
@ -82,5 +116,9 @@ RUN photoprism -v
# Expose http port
EXPOSE 2342
# Configure entrypoint
COPY --chown=root:root /docker/photoprism/entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# Run server
CMD photoprism start

View file

@ -73,12 +73,12 @@ RUN npm install --unsafe-perm=true --allow-root -g npm
RUN npm config set cache ~/.cache/npm
# Install Go
ENV GOLANG_VERSION 1.15
ENV GOLANG_VERSION 1.15.2
RUN set -eux; \
\
url="https://golang.org/dl/go${GOLANG_VERSION}.linux-arm64.tar.gz"; \
wget -O go.tgz "$url"; \
echo "7e18d92f61ddf480a4f9a57db09389ae7b9dadf68470d0cb9c00d734a0c57f8d *go.tgz" | sha256sum -c -; \
echo "c8ec460cc82d61604b048f9439c06bd591722efce5cd48f49e19b5f6226bd36d *go.tgz" | sha256sum -c -; \
tar -C /usr/local -xzf go.tgz; \
rm go.tgz; \
export PATH="/usr/local/go/bin:$PATH"; \
@ -103,6 +103,9 @@ COPY . .
# Build PhotoPrism
RUN make dep build-js install
# Build gosu
RUN env GO111MODULE=off /usr/local/go/bin/go get -u github.com/tianon/gosu
# Same base image as photoprism/development
FROM ubuntu:20.04
@ -133,17 +136,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
rm -rf /var/lib/apt/lists/*
# Copy dependencies
COPY --from=build /go/bin/gosu /bin/gosu
COPY --from=build /usr/lib/libtensorflow.so /usr/lib/libtensorflow.so
COPY --from=build /usr/lib/libtensorflow_framework.so /usr/lib/libtensorflow_framework.so
RUN ldconfig
# Set default umask and create photoprism user
RUN umask 0000 && useradd photoprism -m -d /photoprism
WORKDIR /photoprism
ENV TF_CPP_MIN_LOG_LEVEL 2
ENV PATH /photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV TMPDIR /tmp
# Storage path names
ENV PHOTOPRISM_ASSETS_PATH /photoprism/assets
ENV PHOTOPRISM_ORIGINALS_PATH /photoprism/originals
ENV PHOTOPRISM_IMPORT_PATH /photoprism/import
@ -151,6 +159,33 @@ ENV PHOTOPRISM_STORAGE_PATH /photoprism/storage
ENV PHOTOPRISM_LOG_FILENAME /photoprism/photoprism.log
ENV PHOTOPRISM_PID_FILENAME /photoprism/photoprism.pid
# Defaults for common config values
# See https://docs.photoprism.org/getting-started/config-options/
ENV PHOTOPRISM_DEBUG "false"
ENV PHOTOPRISM_PUBLIC "false"
ENV PHOTOPRISM_READONLY "false"
ENV PHOTOPRISM_UPLOAD_NSFW "true"
ENV PHOTOPRISM_DETECT_NSFW "false"
ENV PHOTOPRISM_EXPERIMENTAL "false"
ENV PHOTOPRISM_SITE_URL "http://localhost:2342/"
ENV PHOTOPRISM_SITE_TITLE "PhotoPrism"
ENV PHOTOPRISM_SITE_CAPTION "Browse Your Life"
ENV PHOTOPRISM_SITE_DESCRIPTION ""
ENV PHOTOPRISM_SITE_AUTHOR ""
ENV PHOTOPRISM_HTTP_HOST "0.0.0.0"
ENV PHOTOPRISM_HTTP_PORT 2342
ENV PHOTOPRISM_SETTINGS_HIDDEN "false"
ENV PHOTOPRISM_DATABASE_DRIVER "sqlite"
ENV PHOTOPRISM_SIDECAR_JSON "true"
ENV PHOTOPRISM_SIDECAR_YAML "true"
ENV PHOTOPRISM_THUMB_FILTER "lanczos"
ENV PHOTOPRISM_THUMB_UNCACHED "false"
ENV PHOTOPRISM_THUMB_SIZE 2048
ENV PHOTOPRISM_THUMB_SIZE_UNCACHED 7680
ENV PHOTOPRISM_JPEG_SIZE 7680
ENV PHOTOPRISM_JPEG_QUALITY 92
ENV PHOTOPRISM_DARKTABLE_PRESETS "false"
# Copy files to /photoprism
COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism
COPY --from=build /root/.photoprism/assets /photoprism/assets
@ -160,9 +195,11 @@ RUN mkdir -p \
/photoprism/originals \
/photoprism/import \
/photoprism/storage/settings \
/photoprism/storage/cache
RUN chmod -R 777 /photoprism
/photoprism/storage/cache && \
chmod 777 /photoprism && \
chown -R photoprism:photoprism /photoprism && \
find /photoprism -type d -print0 | xargs -0 chmod 777 && \
find /photoprism -type f -print0 | xargs -0 chmod a+rw
# Show photoprism version
RUN photoprism -v
@ -170,5 +207,9 @@ RUN photoprism -v
# Expose http port
EXPOSE 2342
# Configure entrypoint
COPY --chown=root:root /docker/photoprism/entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# Run server
CMD photoprism start

16
docker/photoprism/entrypoint.sh Executable file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
if [[ ${UMASK} ]]; then
umask ${UMASK}
fi
if [[ ${UID} ]] && [[ ${GID} ]] && [[ ${UID} != "0" ]] && [[ $(id -u) = "0" ]]; then
usermod -u ${UID} photoprism
usermod -g ${GID} photoprism
exec gosu ${UID}:${GID} "$@"
elif [[ ${UID} ]] && [[ ${UID} != "0" ]] && [[ $(id -u) = "0" ]]; then
usermod -u ${UID} photoprism
exec gosu ${UID} "$@"
else
exec "$@"
fi

View file

@ -2,6 +2,7 @@ package webdav
import (
"os"
"path/filepath"
"testing"
"github.com/photoprism/photoprism/pkg/fs"
@ -84,7 +85,7 @@ func TestClient_Download(t *testing.T) {
t.Fatal(err)
}
tempDir := os.TempDir() + rnd.UUID()
tempDir := filepath.Join(os.TempDir(), rnd.UUID())
tempFile := tempDir + "/foo.jpg"
if len(files) == 0 {
@ -110,7 +111,7 @@ func TestClient_DownloadDir(t *testing.T) {
assert.IsType(t, Client{}, c)
t.Run("non-recursive", func(t *testing.T) {
tempDir := os.TempDir() + rnd.UUID()
tempDir := filepath.Join(os.TempDir(), rnd.UUID())
if errs := c.DownloadDir("Photos", tempDir, false, false); len(errs) > 0 {
t.Fatal(errs)
@ -122,7 +123,7 @@ func TestClient_DownloadDir(t *testing.T) {
})
t.Run("recursive", func(t *testing.T) {
tempDir := os.TempDir() + rnd.UUID()
tempDir := filepath.Join(os.TempDir(), rnd.UUID())
if errs := c.DownloadDir("Photos", tempDir, true, false); len(errs) > 0 {
t.Fatal(errs)