From 4247066c1bf3188b82155c8f08a5428e59625b7e Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Sat, 19 Feb 2022 15:32:52 +0100 Subject: [PATCH] Docker: Reduce image layers and improve build scripts --- .dockerignore | 1 + .gitignore | 1 + docker/develop/.my.cnf => .my.cnf | 0 Dockerfile | 11 +- Makefile | 127 +++++++------ build/.gitignore | 2 - docker/develop/armv7/Dockerfile | 140 ++++++++------- docker/develop/bullseye/Dockerfile | 170 +++++++++--------- docker/develop/buster/Dockerfile | 70 ++++---- docker/develop/entrypoint.sh | 4 +- docker/develop/impish/Dockerfile | 72 ++++---- docker/photoprism/armv7/Dockerfile | 141 +++++++-------- docker/photoprism/bullseye/Dockerfile | 146 +++++++-------- docker/photoprism/buster/Dockerfile | 147 +++++++-------- docker/photoprism/impish/Dockerfile | 142 +++++++-------- internal/config/config.go | 5 +- scripts/build.sh | 35 +--- scripts/{init => dist}/.buildignore | 0 scripts/{init => dist}/Makefile | 0 scripts/{init => dist}/arch.sh | 0 scripts/{init => dist}/cleanup.sh | 2 + scripts/{init => dist}/dist-upgrade.sh | 2 +- scripts/dist/doctor.sh | 9 + .../photoprism => scripts/dist}/entrypoint.sh | 23 ++- scripts/{init => dist}/heif-convert.sh | 0 scripts/{init => dist}/install-darktable.sh | 4 +- scripts/{init => dist}/install-devtools.sh | 2 +- scripts/{init => dist}/install-go.sh | 2 +- scripts/dist/install-mariadb.sh | 28 +++ scripts/{init => dist}/install-nodejs.sh | 12 +- scripts/dist/install-tensorflow.sh | 52 ++++++ scripts/init/install-mariadb-client.sh | 12 -- scripts/init/install-tensorflow.sh | 40 ----- 33 files changed, 700 insertions(+), 702 deletions(-) rename docker/develop/.my.cnf => .my.cnf (100%) delete mode 100644 build/.gitignore rename scripts/{init => dist}/.buildignore (100%) rename scripts/{init => dist}/Makefile (100%) rename scripts/{init => dist}/arch.sh (100%) rename scripts/{init => dist}/cleanup.sh (97%) rename scripts/{init => dist}/dist-upgrade.sh (93%) create mode 100755 scripts/dist/doctor.sh rename {docker/photoprism => scripts/dist}/entrypoint.sh (84%) rename scripts/{init => dist}/heif-convert.sh (100%) rename scripts/{init => dist}/install-darktable.sh (97%) rename scripts/{init => dist}/install-devtools.sh (98%) rename scripts/{init => dist}/install-go.sh (98%) create mode 100755 scripts/dist/install-mariadb.sh rename scripts/{init => dist}/install-nodejs.sh (63%) create mode 100755 scripts/dist/install-tensorflow.sh delete mode 100755 scripts/init/install-mariadb-client.sh delete mode 100755 scripts/init/install-tensorflow.sh diff --git a/.dockerignore b/.dockerignore index a0f3d9068..ff203a1b1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,7 @@ /assets/nasnet /assets/nsfw /storage +/build /photoprism /coverage.* /frontend/tests/acceptance/screenshots diff --git a/.gitignore b/.gitignore index 5a09c1fd2..fbca221d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /photos/originals/* /photos/import/* /storage/* +/build/* /node_modules /frontend/.eslintcache /frontend/node_modules/* diff --git a/docker/develop/.my.cnf b/.my.cnf similarity index 100% rename from docker/develop/.my.cnf rename to .my.cnf diff --git a/Dockerfile b/Dockerfile index fe4801434..8fbd39af1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,14 @@ -FROM photoprism/develop:220218-bullseye +FROM photoprism/develop:220219-bullseye ## other base images to choose from... # FROM photoprism/develop:buster # Debian 10 (Buster) # FROM photoprism/develop:impish # Ubuntu 21.10 (Impish Indri) -# update NPM JS package manager -RUN npm install -g npm - -# copy scripts to test changes +# copy entrypoint script to container COPY --chown=root:root /docker/develop/entrypoint.sh /entrypoint.sh -COPY --chown=root:root /scripts/init/Makefile /root/Makefile -# set up project directory +# define working directory in container WORKDIR "/go/src/github.com/photoprism/photoprism" +# copy project source code to container COPY . . \ No newline at end of file diff --git a/Makefile b/Makefile index e9c39c2a7..bdde80d17 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,24 @@ export GODEBUG=http2client=0 GOIMPORTS=goimports BINARY_NAME=photoprism -DOCKER_TAG := $(shell date -u +%Y%m%d) +# Build Parameters +BUILD_PATH ?= $(shell realpath "./build") +BUILD_DATE ?= $(shell date -u +%y%m%d) +BUILD_VERSION ?= $(shell git describe --always) +BUILD_TAG ?= $(BUILD_DATE)-$(BUILD_VERSION) +BUILD_OS ?= $(shell uname -s) +BUILD_ARCH ?= $(shell scripts/dist/arch.sh) +JS_BUILD_PATH ?= $(shell realpath "./assets/static/build") + +# Installation Parameters +INSTALL_PATH ?= $(BUILD_PATH)/photoprism-$(BUILD_TAG)-$(shell echo $(BUILD_OS) | tr '[:upper:]' '[:lower:]')-$(BUILD_ARCH) +DESTDIR ?= $(INSTALL_PATH) +DESTUID ?= 1000 +DESTGID ?= 1000 +INSTALL_USER ?= $(DESTUID):$(DESTGID) +INSTALL_MODE ?= u+rwX,a+rX +INSTALL_MODE_BIN ?= 755 + UID := $(shell id -u) HASRICHGO := $(shell which richgo) @@ -15,9 +32,8 @@ else endif all: dep build -dep: dep-tensorflow dep-js dep-go -build: generate build-js build-go -install: install-bin install-assets +dep: dep-tensorflow dep-npm dep-js dep-go +build: build-js test: test-js test-go test-go: reset-testdb run-test-go test-pkg: reset-testdb run-test-pkg @@ -31,13 +47,41 @@ acceptance-run-chromium: acceptance-private-restart acceptance-private acceptanc acceptance-run-firefox: acceptance-private-restart acceptance-private-firefox acceptance-private-stop acceptance-restart acceptance-firefox acceptance-stop test-all: test acceptance-run-chromium fmt: fmt-js fmt-go -upgrade: dep-upgrade-js dep-upgrade clean-local: clean-local-config clean-local-cache -clean-install: clean-local dep build-js install-bin install-assets -dev: npm install-go-amd64 -npm: - $(info Upgrading NPM version...) - sudo npm update -g npm +upgrade: dep-upgrade-js dep-upgrade +devtools: install-go dep-npm +clean: + rm -f *.log .test* + [ ! -f " $(BINARY_NAME)" ] || rm -f $(BINARY_NAME) + [ ! -d "node_modules" ] || rm -rf node_modules + [ ! -d "frontend/node_modules" ] || rm -rf frontend/node_modules + [ ! -d "$(BUILD_PATH)" ] || rm -rf --preserve-root $(BUILD_PATH) + [ ! -d "$(JS_BUILD_PATH)" ] || rm -rf --preserve-root $(JS_BUILD_PATH) +install: + $(info Installing in "$(DESTDIR)"...) + [ ! -d "$(DESTDIR)" ] || rm -rf --preserve-root $(DESTDIR) + mkdir --mode=$(INSTALL_MODE) -p $(DESTDIR) + env TMPDIR="$(BUILD_PATH)" ./scripts/dist/install-tensorflow.sh $(DESTDIR) + rm -rf --preserve-root $(DESTDIR)/include + (cd $(DESTDIR) && mkdir -p bin scripts lib assets config config/examples) + scripts/build.sh prod $(DESTDIR)/bin/$(BINARY_NAME) + [ ! -f "$(GOBIN)/gosu" ] || cp $(GOBIN)/gosu $(DESTDIR)/bin/gosu + [ ! -f "$(GOBIN)/exif-read-tool" ] || cp $(GOBIN)/exif-read-tool $(DESTDIR)/bin/exif-read-tool + rsync -r -l --safe-links --exclude-from=assets/.buildignore --chmod=a+r,u+rw ./assets/ $(DESTDIR)/assets + rsync -r -l --safe-links --exclude-from=scripts/dist/.buildignore --chmod=a+rx,u+rwx ./scripts/dist/ $(DESTDIR)/scripts + mv $(DESTDIR)/scripts/heif-convert.sh $(DESTDIR)/bin/heif-convert + cp internal/config/testdata/*.yml $(DESTDIR)/config/examples + chown -R $(INSTALL_USER) $(DESTDIR) + chmod -R $(INSTALL_MODE) $(DESTDIR) + chmod -R $(INSTALL_MODE_BIN) $(DESTDIR)/bin $(DESTDIR)/lib $(DESTDIR)/scripts/*.sh + echo "PhotoPrism $(BUILD_TAG) has been successfully installed in \"$(DESTDIR)\".\nEnjoy!" +install-go: + sudo scripts/dist/install-go.sh + go build -v ./... +install-tensorflow: + sudo scripts/dist/install-tensorflow.sh +install-darktable: + sudo scripts/dist/install-darktable.sh acceptance-restart: cp -f storage/acceptance/backup.db storage/acceptance/index.db cp -f storage/acceptance/config/settingsBackup.yml storage/acceptance/config/settings.yml @@ -75,30 +119,16 @@ generate: @if [ ${$(shell git diff --shortstat assets/locales/messages.pot):1:45} == $(POT_UNCHANGED) ]; then\ git checkout -- assets/locales/messages.pot;\ fi -install-go-amd64: - $(info Installing Go (AMD64)...) - sudo docker/scripts/install-go.sh amd64 - go build -v ./... -install-bin: - scripts/build.sh prod ~/.local/bin/$(BINARY_NAME) -install-assets: - $(info Installing assets) - mkdir -p ~/.photoprism/storage/config - mkdir -p ~/.photoprism/storage/cache - mkdir -p ~/.photoprism/storage - mkdir -p ~/.photoprism/assets - mkdir -p ~/Pictures/Originals - mkdir -p ~/Pictures/Import - cp -r assets/locales assets/facenet assets/nasnet assets/nsfw assets/profiles assets/static assets/templates ~/.photoprism/assets - find ~/.photoprism/assets -name '.*' -type f -delete clean-local-assets: - rm -rf ~/.photoprism/assets/* + rm -rf $(BUILD_PATH)/assets/* clean-local-cache: - rm -rf ~/.photoprism/storage/cache/* + rm -rf $(BUILD_PATH)/storage/cache/* clean-local-config: - rm -f ~/.photoprism/storage/config/* + rm -f $(BUILD_PATH)/config/* dep-list: go list -u -m -json all | go-mod-outdated -direct +dep-npm: + sudo npm install -g npm dep-js: (cd frontend && npm install --silent --legacy-peer-deps) dep-go: @@ -119,9 +149,13 @@ zip-nsfw: (cd assets && zip -r nsfw.zip nsfw -x "*/.*" -x "*/version.txt") build-js: (cd frontend && env NODE_ENV=production npm run build) -build-go: +build-go: build-debug +build-debug: rm -f $(BINARY_NAME) scripts/build.sh debug $(BINARY_NAME) +build-prod: + rm -f $(BINARY_NAME) + scripts/build.sh prod $(BINARY_NAME) build-race: rm -f $(BINARY_NAME) scripts/build.sh race $(BINARY_NAME) @@ -156,7 +190,7 @@ reset-mariadb: mysql < scripts/sql/reset-mariadb.sql reset-testdb: $(info Removing test database files...) - find ./internal -type f -name '.test.*' -delete + find ./internal -type f -name ".test.*" -delete run-test-short: $(info Running short Go unit tests in parallel mode...) $(GOTEST) -parallel 2 -count 1 -cpu 2 -short -timeout 5m ./pkg/... ./internal/... @@ -164,7 +198,7 @@ run-test-go: $(info Running all Go unit tests...) $(GOTEST) -parallel 1 -count 1 -cpu 1 -tags slow -timeout 20m ./pkg/... ./internal/... run-test-pkg: - $(info Running all Go unit tests in '/pkg'...) + $(info Running all Go unit tests in "/pkg"...) $(GOTEST) -parallel 2 -count 1 -cpu 2 -tags slow -timeout 20m ./pkg/... run-test-api: $(info Running all API unit tests...) @@ -186,14 +220,6 @@ test-coverage: $(info Running all Go unit tests with code coverage report...) go test -parallel 1 -count 1 -cpu 1 -failfast -tags slow -timeout 30m -coverprofile coverage.txt -covermode atomic ./pkg/... ./internal/... go tool cover -html=coverage.txt -o coverage.html -clean: - rm -f $(BINARY_NAME) - rm -f *.log - rm -rf node_modules - rm -rf storage/testdata - rm -rf storage/backup - rm -rf storage/cache - rm -rf frontend/node_modules docker-develop-all: docker-develop-bullseye docker-develop-buster docker-develop-impish docker-develop-armv7 docker-develop: docker-develop-bullseye docker-develop-bullseye: @@ -273,26 +299,26 @@ docker-pull: docker pull photoprism/photoprism:preview photoprism/photoprism:latest docker-ddns: docker pull golang:alpine - scripts/docker/buildx-multi.sh ddns linux/amd64,linux/arm64 $(DOCKER_TAG) + scripts/docker/buildx-multi.sh ddns linux/amd64,linux/arm64 $(BUILD_DATE) docker-goproxy: docker pull golang:alpine - scripts/docker/buildx-multi.sh goproxy linux/amd64,linux/arm64 $(DOCKER_TAG) + scripts/docker/buildx-multi.sh goproxy linux/amd64,linux/arm64 $(BUILD_DATE) docker-demo: docker pull photoprism/photoprism:preview - scripts/docker/build.sh demo $(DOCKER_TAG) - scripts/docker/push.sh demo $(DOCKER_TAG) + scripts/docker/build.sh demo $(BUILD_DATE) + scripts/docker/push.sh demo $(BUILD_DATE) docker-demo-local: scripts/docker/build.sh photoprism - scripts/docker/build.sh demo $(DOCKER_TAG) - scripts/docker/push.sh demo $(DOCKER_TAG) + scripts/docker/build.sh demo $(BUILD_DATE) + scripts/docker/push.sh demo $(BUILD_DATE) docker-dummy-webdav: docker pull --platform=amd64 golang:1 docker pull --platform=arm64 golang:1 - scripts/docker/buildx-multi.sh dummy-webdav linux/amd64,linux/arm64 $(DOCKER_TAG) + scripts/docker/buildx-multi.sh dummy-webdav linux/amd64,linux/arm64 $(BUILD_DATE) docker-dummy-oidc: docker pull --platform=amd64 golang:1 docker pull --platform=arm64 golang:1 - scripts/docker/buildx-multi.sh dummy-oidc linux/amd64,linux/arm64 $(DOCKER_TAG) + scripts/docker/buildx-multi.sh dummy-oidc linux/amd64,linux/arm64 $(BUILD_DATE) packer-digitalocean: $(info Buildinng DigitalOcean marketplace image...) (cd ./docker/examples/cloud && packer build digitalocean.json) @@ -309,5 +335,6 @@ fmt-go: tidy: go mod tidy -.PHONY: all build dev npm dep dep-go dep-js dep-list dep-tensorflow dep-upgrade dep-upgrade-js test test-js test-go \ -install generate fmt fmt-go fmt-js upgrade start stop terminal root-terminal packer-digitalocean acceptance clean tidy; \ No newline at end of file +.PHONY: all build dev dep-npm dep dep-go dep-js dep-list dep-tensorflow dep-upgrade dep-upgrade-js test test-js test-go \ + install generate fmt fmt-go fmt-js upgrade start stop terminal root-terminal packer-digitalocean acceptance clean tidy \ + install-go install-darktable install-tensorflow devtools; \ No newline at end of file diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index c96a04f00..000000000 --- a/build/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/docker/develop/armv7/Dockerfile b/docker/develop/armv7/Dockerfile index 39eff60f9..d0006a62f 100644 --- a/docker/develop/armv7/Dockerfile +++ b/docker/develop/armv7/Dockerfile @@ -19,82 +19,92 @@ ENV DEBIAN_FRONTEND="noninteractive" \ GO111MODULE="on" \ CGO_CFLAGS="-g -O2 -Wno-return-local-addr" -# apt default settings +# copy scripts and debian backports sources list +COPY --chown=root:root --chmod=755 /scripts/dist/* /root/.local/bin/ +COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh +COPY --chown=root:root --chmod=644 /.my.cnf /etc/my.cnf + +# update image and install build dependencies RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# update image and install build dependencies -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ - apt-utils \ - gpg \ - pkg-config \ - software-properties-common \ - ca-certificates \ - build-essential \ - gcc \ - g++ \ - sudo \ - make \ - nano \ - git \ - zip \ - wget \ - curl \ - rsync \ - unzip \ - sqlite3 \ - chrpath \ - gettext \ - libc6-dev \ - libssl-dev \ - libxft-dev \ - libfreetype6 \ - libfreetype6-dev \ - libfontconfig1 \ - libfontconfig1-dev \ - libhdf5-serial-dev \ - libpng-dev \ - libzmq3-dev \ - libx264-dev \ - libx265-dev \ - libnss3 \ - libxtst6 \ - librsvg2-bin \ - tzdata \ - libheif-examples \ - exiftool \ - ffmpeg \ - ffmpegthumbnailer \ - libavcodec-extra \ - sudo && \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + apt-utils \ + gpg \ + pkg-config \ + software-properties-common \ + ca-certificates \ + build-essential \ + gcc \ + g++ \ + sudo \ + make \ + nano \ + git \ + zip \ + wget \ + curl \ + rsync \ + unzip \ + sqlite3 \ + chrpath \ + gettext \ + libc6-dev \ + libssl-dev \ + libxft-dev \ + libfreetype6 \ + libfreetype6-dev \ + libfontconfig1 \ + libfontconfig1-dev \ + libhdf5-serial-dev \ + libpng-dev \ + libzmq3-dev \ + libx264-dev \ + libx265-dev \ + libnss3 \ + libxtst6 \ + librsvg2-bin \ + tzdata \ + libheif-examples \ + exiftool \ + ffmpeg \ + ffmpegthumbnailer \ + libavcodec-extra \ + sudo && \ /root/.local/bin/install-nodejs.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* && \ /root/.local/bin/install-tensorflow.sh && \ + /root/.local/bin/cleanup.sh && \ mkdir -p "/go/src" "/go/bin" && \ - chmod -R 777 "/go" - -# download TensorFlow models & example files for testing -RUN rm -rf /tmp/* && mkdir -p /tmp/photoprism && \ + chmod -R 777 "/go" && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ wget "https://dl.photoprism.app/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip && \ wget "https://dl.photoprism.app/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip && \ wget "https://dl.photoprism.app/tensorflow/facenet.zip?${BUILD_TAG}" -O /tmp/photoprism/facenet.zip && \ wget "https://dl.photoprism.app/qa/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip -# copy additional scripts to image -COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh - # install Go tools RUN /usr/local/go/bin/go install github.com/tianon/gosu@latest && \ /usr/local/go/bin/go install golang.org/x/tools/cmd/goimports@latest && \ /usr/local/go/bin/go install github.com/kyoh86/richgo@latest && \ - echo "alias go=richgo" > /root/.bash_aliases && \ - cp /go/bin/gosu /bin/gosu + cp /go/bin/gosu /bin/gosu && \ + echo "alias go=richgo ll='ls -alh'" > /photoprism/.bash_aliases && \ + echo "alias go=richgo ll='ls -alh'" > /root/.bash_aliases && \ + echo "photoprism ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ + chmod -R a+rwX /go # create photoprism user and directory for deployment RUN useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism && \ @@ -108,11 +118,15 @@ RUN useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism & # set up project directory WORKDIR "/go/src/github.com/photoprism/photoprism" -# expose HTTP ports: 2342 (HTTP), 2343 (Acceptance Tests), 9515 (Chromedriver), 40000 (Go) +# expose the following container ports: +# - 2342 (HTTP) +# - 2343 (Acceptance Tests) +# - 9515 (Chromedriver) +# - 40000 (Go Debugger) EXPOSE 2342 2343 9515 40000 -# configure entrypoint +# define container entrypoint script ENTRYPOINT ["/entrypoint.sh"] # keep container running -CMD ["tail", "-f", "/dev/null"] \ No newline at end of file +CMD ["tail", "-f", "/dev/null"] diff --git a/docker/develop/bullseye/Dockerfile b/docker/develop/bullseye/Dockerfile index e594841a4..d0cc37e93 100644 --- a/docker/develop/bullseye/Dockerfile +++ b/docker/develop/bullseye/Dockerfile @@ -21,120 +21,116 @@ ENV DEBIAN_FRONTEND="noninteractive" \ GO111MODULE="on" \ CGO_CFLAGS="-g -O2 -Wno-return-local-addr" -# apt default settings +# copy scripts and debian backports sources list +COPY --chown=root:root --chmod=755 /scripts/dist/* /root/.local/bin/ +COPY --chown=root:root --chmod=644 /docker/develop/bullseye/backports.list /etc/apt/sources.list.d/backports.list +COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh +COPY --chown=root:root --chmod=644 /.my.cnf /etc/my.cnf + +# update image and install build dependencies RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# copy backport packages source list -COPY --chown=root:root --chmod=644 /docker/develop/bullseye/backports.list /etc/apt/sources.list.d/backports.list - -# update image and install build dependencies -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ - apt-utils \ - gpg \ - pkg-config \ - software-properties-common \ - ca-certificates \ - build-essential \ - gcc \ - g++ \ - sudo \ - bash \ - make \ - nano \ - wget \ - curl \ - rsync \ - unzip \ - zip \ - git \ - gettext \ - chromium \ - chromium-driver \ - firefox-esr \ - sqlite3 \ - libc6-dev \ - libssl-dev \ - libxft-dev \ - libhdf5-serial-dev \ - libpng-dev \ - libheif-examples \ - librsvg2-bin \ - libzmq3-dev \ - libx264-dev \ - libx265-dev \ - libnss3 \ - libfreetype6 \ - libfreetype6-dev \ - libfontconfig1 \ - libfontconfig1-dev \ - fonts-roboto \ - tzdata \ - exiftool \ - rawtherapee \ - ffmpeg \ - ffmpegthumbnailer \ - libavcodec-extra \ - davfs2 \ - chrpath \ - lsof \ - apache2-utils && \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + apt-utils \ + gpg \ + pkg-config \ + software-properties-common \ + ca-certificates \ + build-essential \ + gcc \ + g++ \ + sudo \ + bash \ + make \ + nano \ + wget \ + curl \ + rsync \ + unzip \ + zip \ + git \ + gettext \ + chromium \ + chromium-driver \ + firefox-esr \ + sqlite3 \ + libc6-dev \ + libssl-dev \ + libxft-dev \ + libhdf5-serial-dev \ + libpng-dev \ + libheif-examples \ + librsvg2-bin \ + libzmq3-dev \ + libx264-dev \ + libx265-dev \ + libnss3 \ + libfreetype6 \ + libfreetype6-dev \ + libfontconfig1 \ + libfontconfig1-dev \ + fonts-roboto \ + tzdata \ + exiftool \ + rawtherapee \ + ffmpeg \ + ffmpegthumbnailer \ + libavcodec-extra \ + davfs2 \ + chrpath \ + lsof \ + apache2-utils && \ /root/.local/bin/install-nodejs.sh && \ - /root/.local/bin/install-mariadb-client.sh && \ + /root/.local/bin/install-mariadb.sh mariadb-client && \ /root/.local/bin/install-tensorflow.sh && \ /root/.local/bin/install-darktable.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* && \ + /root/.local/bin/cleanup.sh && \ mkdir -p "/go/src" "/go/bin" && \ - chmod -R 777 "/go" - -# download TensorFlow models & example files for testing -RUN rm -rf /tmp/* && mkdir -p /tmp/photoprism && \ + chmod -R 777 "/go" && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ wget "https://dl.photoprism.app/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip && \ wget "https://dl.photoprism.app/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip && \ wget "https://dl.photoprism.app/tensorflow/facenet.zip?${BUILD_TAG}" -O /tmp/photoprism/facenet.zip && \ wget "https://dl.photoprism.app/qa/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip -# copy additional scripts to image -COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh - # install Go tools RUN /usr/local/go/bin/go install github.com/tianon/gosu@latest && \ /usr/local/go/bin/go install golang.org/x/tools/cmd/goimports@latest && \ /usr/local/go/bin/go install github.com/kyoh86/richgo@latest && \ /usr/local/go/bin/go install github.com/psampaz/go-mod-outdated@latest && \ /usr/local/go/bin/go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest; \ - echo "alias go=richgo" > /root/.bash_aliases && \ - cp /go/bin/gosu /bin/gosu - -# create photoprism user and directory for deployment -RUN useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism && \ - mkdir -m 777 -p /var/lib/photoprism /tmp/photoprism && \ - echo "alias go=richgo" > /photoprism/.bash_aliases && \ + cp /go/bin/gosu /bin/gosu && \ + echo "alias go=richgo ll='ls -alh'" > /photoprism/.bash_aliases && \ + echo "alias go=richgo ll='ls -alh'" > /root/.bash_aliases && \ echo "photoprism ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rw /photoprism /var/lib/photoprism /tmp/photoprism /go && \ - mv /root/.local/bin/Makefile /root/Makefile && \ cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - find /go -type d -print0 | xargs -0 chmod 777 - -# copy mysql client config for develop -COPY --chown=root:root /docker/develop/.my.cnf /root/.my.cnf -COPY --chown=photoprism:photoprism /docker/develop/.my.cnf /photoprism/.my.cnf -RUN chmod 644 /root/.my.cnf /photoprism/.my.cnf + chmod -R a+rwX /go # set up project directory WORKDIR "/go/src/github.com/photoprism/photoprism" -# expose HTTP ports: 2342 (HTTP), 2343 (Acceptance Tests), 9515 (Chromedriver), 40000 (Go) +# expose the following container ports: +# - 2342 (HTTP) +# - 2343 (Acceptance Tests) +# - 9515 (Chromedriver) +# - 40000 (Go Debugger) EXPOSE 2342 2343 9515 40000 -# configure entrypoint +# define container entrypoint script ENTRYPOINT ["/entrypoint.sh"] # keep container running diff --git a/docker/develop/buster/Dockerfile b/docker/develop/buster/Dockerfile index 9bff3e645..87e9e8f39 100644 --- a/docker/develop/buster/Dockerfile +++ b/docker/develop/buster/Dockerfile @@ -21,21 +21,20 @@ ENV DEBIAN_FRONTEND="noninteractive" \ GO111MODULE="on" \ CGO_CFLAGS="-g -O2 -Wno-return-local-addr" -# apt default settings +# copy scripts and debian backports sources list +COPY --chown=root:root --chmod=755 /scripts/dist/* /root/.local/bin/ +COPY --chown=root:root --chmod=644 /docker/develop/buster/backports.list /etc/apt/sources.list.d/backports.list +COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh +COPY --chown=root:root --chmod=644 /.my.cnf /etc/my.cnf + +# update image and install build dependencies RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# copy backport packages source list -COPY --chown=root:root --chmod=644 /docker/develop/buster/backports.list /etc/apt/sources.list.d/backports.list - -# update image and install build dependencies -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ apt-utils \ gpg \ pkg-config \ @@ -88,52 +87,49 @@ RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-insta /root/.local/bin/install-nodejs.sh && \ /root/.local/bin/install-tensorflow.sh && \ /root/.local/bin/install-darktable.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* && \ + /root/.local/bin/cleanup.sh && \ mkdir -p "/go/src" "/go/bin" && \ - chmod -R 777 "/go" - -# download TensorFlow models & example files for testing -RUN rm -rf /tmp/* && mkdir -p /tmp/photoprism && \ + chmod -R 777 "/go" && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ wget "https://dl.photoprism.app/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip && \ wget "https://dl.photoprism.app/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip && \ wget "https://dl.photoprism.app/tensorflow/facenet.zip?${BUILD_TAG}" -O /tmp/photoprism/facenet.zip && \ wget "https://dl.photoprism.app/qa/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip -# copy additional scripts to image -COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh - # install Go tools RUN /usr/local/go/bin/go install github.com/tianon/gosu@latest && \ /usr/local/go/bin/go install golang.org/x/tools/cmd/goimports@latest && \ /usr/local/go/bin/go install github.com/kyoh86/richgo@latest && \ /usr/local/go/bin/go install github.com/psampaz/go-mod-outdated@latest && \ /usr/local/go/bin/go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest; \ - echo "alias go=richgo" > /root/.bash_aliases && \ - cp /go/bin/gosu /bin/gosu - -# create photoprism user and directory for deployment -RUN useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism && \ - mkdir -m 777 -p /var/lib/photoprism /tmp/photoprism && \ - echo "alias go=richgo" > /photoprism/.bash_aliases && \ + cp /go/bin/gosu /bin/gosu && \ + echo "alias go=richgo ll='ls -alh'" > /photoprism/.bash_aliases && \ + echo "alias go=richgo ll='ls -alh'" > /root/.bash_aliases && \ echo "photoprism ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rw /photoprism /var/lib/photoprism /tmp/photoprism /go && \ - mv /root/.local/bin/Makefile /root/Makefile && \ cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - find /go -type d -print0 | xargs -0 chmod 777 - -# copy mysql client config for develop -COPY --chown=root:root /docker/develop/.my.cnf /root/.my.cnf -COPY --chown=photoprism:photoprism /docker/develop/.my.cnf /photoprism/.my.cnf -RUN chmod 644 /root/.my.cnf /photoprism/.my.cnf + chmod -R a+rwX /go # set up project directory WORKDIR "/go/src/github.com/photoprism/photoprism" -# expose HTTP ports: 2342 (HTTP), 2343 (Acceptance Tests), 9515 (Chromedriver), 40000 (Go) +# expose the following container ports: +# - 2342 (HTTP) +# - 2343 (Acceptance Tests) +# - 9515 (Chromedriver) +# - 40000 (Go Debugger) EXPOSE 2342 2343 9515 40000 -# configure entrypoint +# define container entrypoint script ENTRYPOINT ["/entrypoint.sh"] # keep container running diff --git a/docker/develop/entrypoint.sh b/docker/develop/entrypoint.sh index c2b09bc82..f6e08ce9a 100755 --- a/docker/develop/entrypoint.sh +++ b/docker/develop/entrypoint.sh @@ -8,7 +8,7 @@ if [[ $(id -u) == "0" ]]; then elif [[ ${PHOTOPRISM_INIT} ]]; then for target in $PHOTOPRISM_INIT; do echo "init ${target}..." - make -f /root/Makefile "${target}" + make -f /go/src/github.com/photoprism/photoprism/scripts/dist/Makefile "${target}" done echo 1 >/root/.init fi @@ -59,7 +59,7 @@ if [[ $(id -u) == "0" ]]; then if [[ -z ${PHOTOPRISM_DISABLE_CHOWN} ]]; then echo "develop: set PHOTOPRISM_DISABLE_CHOWN: \"true\" to disable storage permission updates" echo "develop: updating storage permissions..." - chown -Rf "${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" /photoprism /var/lib/photoprism /tmp/photoprism /go + chown -Rf "${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" /photoprism /tmp/photoprism /go fi echo "develop: running as uid ${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" diff --git a/docker/develop/impish/Dockerfile b/docker/develop/impish/Dockerfile index 0bf1a9a08..b2fb191c9 100644 --- a/docker/develop/impish/Dockerfile +++ b/docker/develop/impish/Dockerfile @@ -21,18 +21,19 @@ ENV DEBIAN_FRONTEND="noninteractive" \ GO111MODULE="on" \ CGO_CFLAGS="-g -O2 -Wno-return-local-addr" -# apt default settings +# copy scripts and debian backports sources list +COPY --chown=root:root --chmod=755 /scripts/dist/* /root/.local/bin/ +COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh +COPY --chown=root:root --chmod=644 /.my.cnf /etc/my.cnf + +# update image and install build dependencies RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts to /root/.local/bin -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# update image and install build dependencies -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ apt-utils \ gpg \ gpg-agent \ @@ -86,57 +87,50 @@ RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-insta /root/.local/bin/install-nodejs.sh && \ /root/.local/bin/install-tensorflow.sh && \ /root/.local/bin/install-darktable.sh && \ - /root/.local/bin/install-devtools.sh && \ - /root/.local/bin/install-go.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* && \ + /root/.local/bin/cleanup.sh && \ mkdir -p "/go/src" "/go/bin" && \ - chmod -R 777 "/go" - -# download TensorFlow models & example files for testing -RUN rm -rf /tmp/* && mkdir -p /tmp/photoprism && \ + chmod -R 777 "/go" && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ wget "https://dl.photoprism.app/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip && \ wget "https://dl.photoprism.app/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip && \ wget "https://dl.photoprism.app/tensorflow/facenet.zip?${BUILD_TAG}" -O /tmp/photoprism/facenet.zip && \ wget "https://dl.photoprism.app/qa/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip -# copy additional scripts to image -COPY --chown=root:root --chmod=755 /docker/develop/entrypoint.sh /entrypoint.sh - # install Go tools RUN /usr/local/go/bin/go install github.com/tianon/gosu@latest && \ /usr/local/go/bin/go install golang.org/x/tools/cmd/goimports@latest && \ /usr/local/go/bin/go install github.com/kyoh86/richgo@latest && \ - [ "$TARGETARCH" = "arm" ] || \ /usr/local/go/bin/go install github.com/psampaz/go-mod-outdated@latest && \ /usr/local/go/bin/go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest; \ - echo "alias go=richgo" > /root/.bash_aliases && \ - cp /go/bin/gosu /bin/gosu - -# create photoprism user and directory for deployment -RUN useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism && \ - mkdir -m 777 -p /var/lib/photoprism /tmp/photoprism && \ - echo "alias go=richgo" > /photoprism/.bash_aliases && \ + cp /go/bin/gosu /bin/gosu && \ + echo "alias go=richgo ll='ls -alh'" > /photoprism/.bash_aliases && \ + echo "alias go=richgo ll='ls -alh'" > /root/.bash_aliases && \ echo "photoprism ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rw /photoprism /var/lib/photoprism /tmp/photoprism /go && \ - mv /root/.local/bin/Makefile /root/Makefile && \ cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - find /go -type d -print0 | xargs -0 chmod 777 - -# copy mysql client config for develop -COPY --chown=root:root /docker/develop/.my.cnf /root/.my.cnf -COPY --chown=photoprism:photoprism /docker/develop/.my.cnf /photoprism/.my.cnf -RUN chmod 644 /root/.my.cnf /photoprism/.my.cnf + chmod -R a+rwX /go # set up project directory WORKDIR "/go/src/github.com/photoprism/photoprism" -# expose HTTP ports: 2342 (HTTP), 2343 (Acceptance Tests), 9515 (Chromedriver), 40000 (Go) +# expose the following container ports: +# - 2342 (HTTP) +# - 2343 (Acceptance Tests) +# - 9515 (Chromedriver) +# - 40000 (Go Debugger) EXPOSE 2342 2343 9515 40000 -VOLUME /var/lib/photoprism -# configure entrypoint +# define container entrypoint script ENTRYPOINT ["/entrypoint.sh"] # keep container running -CMD ["tail", "-f", "/dev/null"] \ No newline at end of file +CMD ["tail", "-f", "/dev/null"] diff --git a/docker/photoprism/armv7/Dockerfile b/docker/photoprism/armv7/Dockerfile index 6402757d5..c131616fc 100644 --- a/docker/photoprism/armv7/Dockerfile +++ b/docker/photoprism/armv7/Dockerfile @@ -11,8 +11,8 @@ ARG GODEBUG WORKDIR "/go/src/github.com/photoprism/photoprism" COPY . . -# build frontend and backend -RUN make npm dep build-js install +# build and install dist files for prod env +RUN make all install DESTDIR=/opt/photoprism ################################################## PRODUCTION STAGE #################################################### #### Debian 11 (Bullseye) @@ -23,51 +23,18 @@ LABEL maintainer="Michael Mayer " ARG TARGETARCH ARG TARGETPLATFORM -# set environment variables -ENV DEBIAN_FRONTEND="noninteractive" \ - TMPDIR="/tmp" - -# apt default settings -RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ - echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ - echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ - echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# install additional distribution packages -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ - ca-certificates \ - gpg \ - wget \ - curl \ - make \ - mariadb-client \ - sqlite3 \ - tzdata \ - libc6 \ - libatomic1 \ - libheif-examples \ - librsvg2-bin \ - exiftool \ - rawtherapee \ - ffmpeg \ - ffmpegthumbnailer \ - libavcodec-extra && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get clean && rm -rf /var/lib/apt/lists/* - # set environment variables, see https://docs.photoprism.app/getting-started/config-options/ -ENV TF_CPP_MIN_LOG_LEVEL="2" \ - PATH="/photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \ - PHOTOPRISM_ASSETS_PATH="/photoprism/assets" \ - PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ - PHOTOPRISM_BACKUP_PATH="/var/lib/photoprism" \ - PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ +ENV PATH="/opt/photoprism/bin:/opt/photoprism/scripts:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin" \ + TMPDIR="/tmp" \ + DEBIAN_FRONTEND="noninteractive" \ + TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_IMPORT_PATH="/photoprism/import" \ - PHOTOPRISM_LOG_FILENAME="/photoprism/photoprism.log" \ - PHOTOPRISM_PID_FILENAME="/photoprism/photoprism.pid" \ + PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ + PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \ + PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ + PHOTOPRISM_BACKUP_PATH="/photoprism/storage/backups" \ + PHOTOPRISM_LOG_FILENAME="/photoprism/storage/photoprism.log" \ + PHOTOPRISM_PID_FILENAME="/photoprism/storage/photoprism.pid" \ PHOTOPRISM_DEBUG="false" \ PHOTOPRISM_PUBLIC="false" \ PHOTOPRISM_READONLY="false" \ @@ -107,42 +74,62 @@ ENV TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_AUTO_INDEX=300 \ PHOTOPRISM_AUTO_IMPORT=300 -# 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 +# copy app dist files and debian backports sources list +COPY --from=build /opt/photoprism/ /opt/photoprism +COPY /docker/develop/bullseye/backports.list /etc/apt/sources.list.d/backports.list -# set default umask and create photoprism user -RUN umask 0000 && useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism +# install additional distribution packages +RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ + echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ + echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ + echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + cp /opt/photoprism/bin/gosu /bin/gosu && \ + chown root:root /bin/gosu && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + ca-certificates \ + gpg \ + wget \ + curl \ + make \ + sqlite3 \ + tzdata \ + libc6 \ + libatomic1 \ + libheif-examples \ + librsvg2-bin \ + exiftool \ + rawtherapee \ + ffmpeg \ + ffmpegthumbnailer \ + libavcodec-extra && \ + install-mariadb.sh mariadb-client && \ + cleanup.sh && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ + cleanup.sh + +# define default directory and user WORKDIR /photoprism -# copy additional files to image -COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism -COPY --from=build /root/.photoprism/assets /photoprism/assets -COPY --chown=root:root --chmod=755 /docker/photoprism/entrypoint.sh /entrypoint.sh +# test binary and show version +RUN photoprism -v -# create directories -RUN mkdir -m 777 -p \ - /var/lib/photoprism \ - /tmp/photoprism \ - /photoprism/originals \ - /photoprism/import \ - /photoprism/storage/config \ - /photoprism/storage/cache && \ - mv /root/.local/bin/Makefile /root/Makefile && \ - cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rwx /photoprism /var/lib/photoprism /tmp/photoprism && \ - photoprism -v && \ - /root/.local/bin/cleanup.sh - -# expose http port +# expose default http port 2342 EXPOSE 2342 -# configure entrypoint -ENTRYPOINT ["/entrypoint.sh"] -VOLUME /var/lib/photoprism +# define container entrypoint script +ENTRYPOINT ["/opt/photoprism/scripts/entrypoint.sh"] -# run server -CMD ["photoprism", "start"] +# start app server +CMD ["/opt/photoprism/bin/photoprism", "start"] diff --git a/docker/photoprism/bullseye/Dockerfile b/docker/photoprism/bullseye/Dockerfile index 70ce9c908..4a597529c 100644 --- a/docker/photoprism/bullseye/Dockerfile +++ b/docker/photoprism/bullseye/Dockerfile @@ -11,8 +11,8 @@ ARG GODEBUG WORKDIR "/go/src/github.com/photoprism/photoprism" COPY . . -# build frontend and backend -RUN make npm dep build-js install +# build and install dist files for prod env +RUN make all install DESTDIR=/opt/photoprism ################################################## PRODUCTION STAGE #################################################### #### Debian 11 (Bullseye) @@ -23,55 +23,18 @@ LABEL maintainer="Michael Mayer " ARG TARGETARCH ARG TARGETPLATFORM -# set environment variables -ENV DEBIAN_FRONTEND="noninteractive" \ - TMPDIR="/tmp" - -# apt default settings -RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ - echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ - echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ - echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# copy debian backports source -COPY --chown=root:root --chmod=644 /docker/develop/bullseye/backports.list /etc/apt/sources.list.d/backports.list - -# install additional distribution packages -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ - ca-certificates \ - gpg \ - wget \ - curl \ - make \ - sqlite3 \ - tzdata \ - libc6 \ - libatomic1 \ - libheif-examples \ - librsvg2-bin \ - exiftool \ - rawtherapee \ - ffmpeg \ - ffmpegthumbnailer \ - libavcodec-extra && \ - /root/.local/bin/install-mariadb-client.sh && \ - /root/.local/bin/install-darktable.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* - # set environment variables, see https://docs.photoprism.app/getting-started/config-options/ -ENV TF_CPP_MIN_LOG_LEVEL="2" \ - PATH="/photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \ - PHOTOPRISM_ASSETS_PATH="/photoprism/assets" \ - PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ - PHOTOPRISM_BACKUP_PATH="/var/lib/photoprism" \ - PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ +ENV PATH="/opt/photoprism/bin:/opt/photoprism/scripts:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin" \ + TMPDIR="/tmp" \ + DEBIAN_FRONTEND="noninteractive" \ + TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_IMPORT_PATH="/photoprism/import" \ - PHOTOPRISM_LOG_FILENAME="/photoprism/photoprism.log" \ - PHOTOPRISM_PID_FILENAME="/photoprism/photoprism.pid" \ + PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ + PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \ + PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ + PHOTOPRISM_BACKUP_PATH="/photoprism/storage/backups" \ + PHOTOPRISM_LOG_FILENAME="/photoprism/storage/photoprism.log" \ + PHOTOPRISM_PID_FILENAME="/photoprism/storage/photoprism.pid" \ PHOTOPRISM_DEBUG="false" \ PHOTOPRISM_PUBLIC="false" \ PHOTOPRISM_READONLY="false" \ @@ -111,42 +74,63 @@ ENV TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_AUTO_INDEX=300 \ PHOTOPRISM_AUTO_IMPORT=300 -# 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 +# copy app dist files and debian backports sources list +COPY --from=build /opt/photoprism/ /opt/photoprism +COPY /docker/develop/bullseye/backports.list /etc/apt/sources.list.d/backports.list -# set default umask and create photoprism user -RUN umask 0000 && useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism +# install additional distribution packages +RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ + echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ + echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ + echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + cp /opt/photoprism/bin/gosu /bin/gosu && \ + chown root:root /bin/gosu && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + ca-certificates \ + gpg \ + wget \ + curl \ + make \ + sqlite3 \ + tzdata \ + libc6 \ + libatomic1 \ + libheif-examples \ + librsvg2-bin \ + exiftool \ + rawtherapee \ + ffmpeg \ + ffmpegthumbnailer \ + libavcodec-extra && \ + install-mariadb.sh mariadb-client && \ + install-darktable.sh && \ + cleanup.sh && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ + cleanup.sh + +# define default directory and user WORKDIR /photoprism -# copy additional files to image -COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism -COPY --from=build /root/.photoprism/assets /photoprism/assets -COPY --chown=root:root --chmod=755 /docker/photoprism/entrypoint.sh /entrypoint.sh +# test binary and show version +RUN photoprism -v -# create directories -RUN mkdir -m 777 -p \ - /var/lib/photoprism \ - /tmp/photoprism \ - /photoprism/originals \ - /photoprism/import \ - /photoprism/storage/config \ - /photoprism/storage/cache && \ - mv /root/.local/bin/Makefile /root/Makefile && \ - cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rwx /photoprism /var/lib/photoprism /tmp/photoprism && \ - photoprism -v && \ - /root/.local/bin/cleanup.sh - -# expose http port +# expose default http port 2342 EXPOSE 2342 -# configure entrypoint -ENTRYPOINT ["/entrypoint.sh"] -VOLUME /var/lib/photoprism +# define container entrypoint script +ENTRYPOINT ["/opt/photoprism/scripts/entrypoint.sh"] -# run server -CMD ["photoprism", "start"] +# start app server +CMD ["/opt/photoprism/bin/photoprism", "start"] diff --git a/docker/photoprism/buster/Dockerfile b/docker/photoprism/buster/Dockerfile index 47f27f3f7..1c5daf8d7 100644 --- a/docker/photoprism/buster/Dockerfile +++ b/docker/photoprism/buster/Dockerfile @@ -11,8 +11,8 @@ ARG GODEBUG WORKDIR "/go/src/github.com/photoprism/photoprism" COPY . . -# build frontend and backend -RUN make npm dep build-js install +# build and install dist files for prod env +RUN make all install DESTDIR=/opt/photoprism ################################################## PRODUCTION STAGE #################################################### #### Debian 10 (Buster) @@ -23,56 +23,18 @@ LABEL maintainer="Michael Mayer " ARG TARGETARCH ARG TARGETPLATFORM -# set environment variables -ENV DEBIAN_FRONTEND="noninteractive" \ - TMPDIR="/tmp" - -# apt default settings -RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ - echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ - echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ - echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# copy backports sources -COPY --chown=root:root --chmod=644 /docker/develop/buster/backports.list /etc/apt/sources.list.d/backports.list - -# install additional distribution packages -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ - ca-certificates \ - gpg \ - wget \ - curl \ - make \ - davfs2 \ - mariadb-client \ - sqlite3 \ - tzdata \ - libc6 \ - libatomic1 \ - libheif-examples \ - librsvg2-bin \ - exiftool \ - rawtherapee \ - ffmpeg \ - ffmpegthumbnailer \ - libavcodec-extra && \ - /root/.local/bin/install-darktable.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* - # set environment variables, see https://docs.photoprism.app/getting-started/config-options/ -ENV TF_CPP_MIN_LOG_LEVEL="2" \ - PATH="/photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \ - PHOTOPRISM_ASSETS_PATH="/photoprism/assets" \ - PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ - PHOTOPRISM_BACKUP_PATH="/var/lib/photoprism" \ - PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ +ENV PATH="/opt/photoprism/bin:/opt/photoprism/scripts:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin" \ + TMPDIR="/tmp" \ + DEBIAN_FRONTEND="noninteractive" \ + TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_IMPORT_PATH="/photoprism/import" \ - PHOTOPRISM_LOG_FILENAME="/photoprism/photoprism.log" \ - PHOTOPRISM_PID_FILENAME="/photoprism/photoprism.pid" \ + PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ + PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \ + PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ + PHOTOPRISM_BACKUP_PATH="/photoprism/storage/backups" \ + PHOTOPRISM_LOG_FILENAME="/photoprism/storage/photoprism.log" \ + PHOTOPRISM_PID_FILENAME="/photoprism/storage/photoprism.pid" \ PHOTOPRISM_DEBUG="false" \ PHOTOPRISM_PUBLIC="false" \ PHOTOPRISM_READONLY="false" \ @@ -112,42 +74,63 @@ ENV TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_AUTO_INDEX=300 \ PHOTOPRISM_AUTO_IMPORT=300 -# 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 +# copy app dist files and debian backports sources list +COPY --from=build /opt/photoprism/ /opt/photoprism +COPY --chown=root:root --chmod=644 /docker/develop/buster/backports.list /etc/apt/sources.list.d/backports.list -# set default umask and create photoprism user -RUN umask 0000 && useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism +# install additional distribution packages +RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ + echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ + echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ + echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + cp /opt/photoprism/bin/gosu /bin/gosu && \ + chown root:root /bin/gosu && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + ca-certificates \ + gpg \ + wget \ + curl \ + make \ + mariadb-client \ + sqlite3 \ + tzdata \ + libc6 \ + libatomic1 \ + libheif-examples \ + librsvg2-bin \ + exiftool \ + rawtherapee \ + ffmpeg \ + ffmpegthumbnailer \ + libavcodec-extra && \ + install-darktable.sh && \ + cleanup.sh && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ + cleanup.sh + +# define default directory and user WORKDIR /photoprism -# copy additional files to image -COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism -COPY --from=build /root/.photoprism/assets /photoprism/assets -COPY --chown=root:root --chmod=755 /docker/photoprism/entrypoint.sh /entrypoint.sh +# test binary and show version +RUN photoprism -v -# create directories -RUN mkdir -m 777 -p \ - /var/lib/photoprism \ - /tmp/photoprism \ - /photoprism/originals \ - /photoprism/import \ - /photoprism/storage/config \ - /photoprism/storage/cache && \ - mv /root/.local/bin/Makefile /root/Makefile && \ - cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rwx /photoprism /var/lib/photoprism /tmp/photoprism && \ - photoprism -v && \ - /root/.local/bin/cleanup.s - -# expose http port +# expose default http port 2342 EXPOSE 2342 -# configure entrypoint -ENTRYPOINT ["/entrypoint.sh"] -VOLUME /var/lib/photoprism +# define container entrypoint script +ENTRYPOINT ["/opt/photoprism/scripts/entrypoint.sh"] -# run server -CMD ["photoprism", "start"] +# start app server +CMD ["/opt/photoprism/bin/photoprism", "start"] diff --git a/docker/photoprism/impish/Dockerfile b/docker/photoprism/impish/Dockerfile index 4f5768487..47e08135b 100644 --- a/docker/photoprism/impish/Dockerfile +++ b/docker/photoprism/impish/Dockerfile @@ -11,8 +11,8 @@ ARG GODEBUG WORKDIR "/go/src/github.com/photoprism/photoprism" COPY .. . -# build frontend and backend -RUN make npm dep build-js install +# build and install dist files for prod env +RUN make all install DESTDIR=/opt/photoprism ################################################## PRODUCTION STAGE #################################################### #### Ubuntu 21.10 (Impish Indri) @@ -23,52 +23,18 @@ LABEL maintainer="Michael Mayer " ARG TARGETARCH ARG TARGETPLATFORM -# set environment variables -ENV DEBIAN_FRONTEND="noninteractive" \ - TMPDIR="/tmp" - -# apt default settings -RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ - echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ - echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ - echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ - echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing - -# copy init scripts -COPY --chown=root:root --chmod=755 /scripts/init/* /root/.local/bin/ - -# install additional distribution packages -RUN apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ - ca-certificates \ - gpg \ - wget \ - curl \ - make \ - mariadb-client \ - sqlite3 \ - tzdata \ - libc6 \ - libatomic1 \ - libheif-examples \ - librsvg2-bin \ - exiftool \ - rawtherapee \ - ffmpeg \ - ffmpegthumbnailer \ - libavcodec-extra && \ - /root/.local/bin/install-darktable.sh && \ - apt-get -y autoremove && apt-get -y autoclean && apt-get -y clean && rm -rf /var/lib/apt/lists/* - # set environment variables, see https://docs.photoprism.app/getting-started/config-options/ -ENV TF_CPP_MIN_LOG_LEVEL="2" \ - PATH="/photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \ - PHOTOPRISM_ASSETS_PATH="/photoprism/assets" \ - PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ - PHOTOPRISM_BACKUP_PATH="/var/lib/photoprism" \ - PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ +ENV PATH="/opt/photoprism/bin:/opt/photoprism/scripts:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin" \ + TMPDIR="/tmp" \ + DEBIAN_FRONTEND="noninteractive" \ + TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_IMPORT_PATH="/photoprism/import" \ - PHOTOPRISM_LOG_FILENAME="/photoprism/photoprism.log" \ - PHOTOPRISM_PID_FILENAME="/photoprism/photoprism.pid" \ + PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \ + PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \ + PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \ + PHOTOPRISM_BACKUP_PATH="/photoprism/storage/backups" \ + PHOTOPRISM_LOG_FILENAME="/photoprism/storage/photoprism.log" \ + PHOTOPRISM_PID_FILENAME="/photoprism/storage/photoprism.pid" \ PHOTOPRISM_DEBUG="false" \ PHOTOPRISM_PUBLIC="false" \ PHOTOPRISM_READONLY="false" \ @@ -108,42 +74,62 @@ ENV TF_CPP_MIN_LOG_LEVEL="2" \ PHOTOPRISM_AUTO_INDEX=300 \ PHOTOPRISM_AUTO_IMPORT=300 -# 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 +# copy app dist files and debian backports sources list +COPY --from=build /opt/photoprism/ /opt/photoprism -# set default umask and create photoprism user -RUN umask 0000 && useradd -m -U -u 1000 -d /photoprism photoprism && chmod a+rwx /photoprism +# install additional distribution packages +RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80retry && \ + echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \ + echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \ + echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ + echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ + cp /opt/photoprism/bin/gosu /bin/gosu && \ + chown root:root /bin/gosu && \ + useradd -m -U -u 1000 -d /photoprism photoprism && \ + apt-get update && apt-get -qq dist-upgrade && apt-get -qq install --no-install-recommends \ + ca-certificates \ + gpg \ + wget \ + curl \ + make \ + mariadb-client \ + sqlite3 \ + tzdata \ + libc6 \ + libatomic1 \ + libheif-examples \ + librsvg2-bin \ + exiftool \ + rawtherapee \ + ffmpeg \ + ffmpegthumbnailer \ + libavcodec-extra && \ + install-darktable.sh && \ + cleanup.sh && \ + install -d -m 0777 -o 1000 -g 1000 \ + /var/lib/photoprism \ + /tmp/photoprism \ + /photoprism/originals \ + /photoprism/import \ + /photoprism/storage \ + /photoprism/storage/sidecar \ + /photoprism/storage/albums \ + /photoprism/storage/backups \ + /photoprism/storage/config \ + /photoprism/storage/cache && \ + cleanup.sh + +# define default directory and user WORKDIR /photoprism -# copy additional files to image -COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism -COPY --from=build /root/.photoprism/assets /photoprism/assets -COPY --chown=root:root --chmod=755 /docker/photoprism/entrypoint.sh /entrypoint.sh +# test binary and show version +RUN photoprism -v -# create directories -RUN mkdir -m 777 -p \ - /var/lib/photoprism \ - /tmp/photoprism \ - /photoprism/originals \ - /photoprism/import \ - /photoprism/storage/config \ - /photoprism/storage/cache && \ - mv /root/.local/bin/Makefile /root/Makefile && \ - cp /root/.local/bin/heif-convert.sh /usr/local/bin/heif-convert && \ - chown -Rf photoprism:photoprism /photoprism /var/lib/photoprism /tmp/photoprism && \ - chmod -Rf a+rwx /photoprism /var/lib/photoprism /tmp/photoprism && \ - photoprism -v && \ - /root/.local/bin/cleanup.sh - -# expose http port +# expose default http port 2342 EXPOSE 2342 -# configure entrypoint -ENTRYPOINT ["/entrypoint.sh"] -VOLUME /var/lib/photoprism +# define container entrypoint script +ENTRYPOINT ["/opt/photoprism/scripts/entrypoint.sh"] -# run server -CMD ["photoprism", "start"] +# start app server +CMD ["/opt/photoprism/bin/photoprism", "start"] diff --git a/internal/config/config.go b/internal/config/config.go index 26436c2c9..5f9c4f9ef 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -239,10 +239,11 @@ func (c *Config) initStorage() error { storageName := filepath.Join(c.StoragePath(), serialName) backupName := filepath.Join(c.BackupPath(), serialName) - if data, err := os.ReadFile(storageName); err == nil { + if data, err := os.ReadFile(storageName); err == nil && len(data) == 16 { c.serial = string(data) - } else if data, err := os.ReadFile(backupName); err == nil { + } else if data, err := os.ReadFile(backupName); err == nil && len(data) == 16 { c.serial = string(data) + LogError(os.WriteFile(storageName, []byte(c.serial), os.ModePerm)) } else if err := os.WriteFile(storageName, []byte(c.serial), os.ModePerm); err != nil { return fmt.Errorf("failed creating %s: %s", storageName, err) } else if err := os.WriteFile(backupName, []byte(c.serial), os.ModePerm); err != nil { diff --git a/scripts/build.sh b/scripts/build.sh index 361164e73..bb70dc064 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,41 +1,24 @@ #!/usr/bin/env bash -set -e - -BUILD_DATE=$(date -u +%y%m%d) -BUILD_VERSION=$(git describe --always) - if [[ -z $1 ]] || [[ -z $2 ]]; then echo "Usage: build.sh [debug|race|static|prod] [filename]" 1>&2 exit 1 fi -if [[ $OS == "Windows_NT" ]]; then - BUILD_OS=win32 - if [[ $PROCESSOR_ARCHITEW6432 == "AMD64" ]]; then - BUILD_ARCH=amd64 - else - if [[ $PROCESSOR_ARCHITECTURE == "AMD64" ]]; then - BUILD_ARCH=amd64 - fi - if [[ $PROCESSOR_ARCHITECTURE == "x86" ]]; then - BUILD_ARCH=ia32 - fi - fi -else - BUILD_OS=$(uname -s) - BUILD_ARCH=$(uname -m) -fi +set -e -BUILD_ID=${BUILD_DATE}-${BUILD_VERSION}-${BUILD_OS}-${BUILD_ARCH} +BUILD_OS=$(uname -s) +BUILD_ARCH=$("$(dirname "$0")/dist/arch.sh") +BUILD_DATE=$(date -u +%y%m%d) +BUILD_VERSION=$(git describe --always) +BUILD_TAG=${BUILD_DATE}-${BUILD_VERSION} +BUILD_ID=${BUILD_TAG}-${BUILD_OS}-${BUILD_ARCH^^} -echo "Building $1 binary..." -echo "Version: PhotoPrism CE ${BUILD_ID}" +echo "Building PhotoPrism ${BUILD_ID} ($1)..." if [[ $1 == "debug" ]]; then go build -ldflags "-X main.version=${BUILD_ID}-DEBUG" -o $2 cmd/photoprism/photoprism.go du -h $2 - echo "Done." elif [[ $1 == "race" ]]; then go build -race -ldflags "-X main.version=${BUILD_ID}-DEBUG" -o $2 cmd/photoprism/photoprism.go du -h $2 @@ -43,7 +26,7 @@ elif [[ $1 == "static" ]]; then go build -a -v -ldflags "-linkmode external -extldflags \"-static -L /usr/lib -ltensorflow\" -s -w -X main.version=${BUILD_ID}" -o $2 cmd/photoprism/photoprism.go du -h $2 else - go build -ldflags "-s -w -X main.version=${BUILD_ID}" -o $2 cmd/photoprism/photoprism.go + go build -ldflags "-extldflags \"-Wl,-rpath -Wl,\$ORIGIN/../lib\" -s -w -X main.version=${BUILD_ID}" -o $2 cmd/photoprism/photoprism.go du -h $2 fi diff --git a/scripts/init/.buildignore b/scripts/dist/.buildignore similarity index 100% rename from scripts/init/.buildignore rename to scripts/dist/.buildignore diff --git a/scripts/init/Makefile b/scripts/dist/Makefile similarity index 100% rename from scripts/init/Makefile rename to scripts/dist/Makefile diff --git a/scripts/init/arch.sh b/scripts/dist/arch.sh similarity index 100% rename from scripts/init/arch.sh rename to scripts/dist/arch.sh diff --git a/scripts/init/cleanup.sh b/scripts/dist/cleanup.sh similarity index 97% rename from scripts/init/cleanup.sh rename to scripts/dist/cleanup.sh index 21b9fe6e2..d30d4b43e 100755 --- a/scripts/init/cleanup.sh +++ b/scripts/dist/cleanup.sh @@ -25,3 +25,5 @@ find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; rm -rf /var/log/*.gz /var/log/*.log /var/log/*.[0-9] /var/log/*-???????? rm -rf /var/lib/cloud/instances/* rm -f /root/.ssh/* /etc/ssh/*key* + +echo "Done." diff --git a/scripts/init/dist-upgrade.sh b/scripts/dist/dist-upgrade.sh similarity index 93% rename from scripts/init/dist-upgrade.sh rename to scripts/dist/dist-upgrade.sh index d18d43cdb..241900038 100755 --- a/scripts/init/dist-upgrade.sh +++ b/scripts/dist/dist-upgrade.sh @@ -17,4 +17,4 @@ apt-get -y update apt-get -y dist-upgrade apt-get -y autoremove -echo "Packages updated." \ No newline at end of file +echo "Done." \ No newline at end of file diff --git a/scripts/dist/doctor.sh b/scripts/dist/doctor.sh new file mode 100755 index 000000000..3ee02340e --- /dev/null +++ b/scripts/dist/doctor.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +STORAGE_PATH=${PHOTOPRISM_STORAGE_PATH:-/photoprism/storage} + +URL="https://docs.photoprism.app/getting-started/troubleshooting/docker/#file-permissions" + +# shellcheck disable=SC2028 +touch "${STORAGE_PATH}/.writable" 2>/dev/null || \ + (printf "The storage folder \"%s\" is not writable, please fix filesystem permissions: %s\n" "$STORAGE_PATH" "$URL"; exit 1) diff --git a/docker/photoprism/entrypoint.sh b/scripts/dist/entrypoint.sh similarity index 84% rename from docker/photoprism/entrypoint.sh rename to scripts/dist/entrypoint.sh index 59c03c98b..f314f6b15 100755 --- a/docker/photoprism/entrypoint.sh +++ b/scripts/dist/entrypoint.sh @@ -3,17 +3,21 @@ if [[ $(id -u) == "0" ]]; then echo "started as root" - if [ -e /root/.init ]; then + if [ -e /opt/photoprism/.init ]; then echo "initialized" elif [[ ${PHOTOPRISM_INIT} ]]; then for target in $PHOTOPRISM_INIT; do echo "init ${target}..." - make -f /root/Makefile "${target}" + make -f /opt/photoprism/scripts/Makefile "${target}" done - echo 1 >/root/.init + echo 1 >/opt/photoprism/.init fi fi +set -e + +STORAGE_PATH=${PHOTOPRISM_STORAGE_PATH:-/photoprism/storage} + re='^[0-9]+$' # legacy umask env variable in use? @@ -57,12 +61,12 @@ if [[ $(id -u) == "0" ]]; then if [[ -z ${PHOTOPRISM_DISABLE_CHOWN} ]]; then echo "set PHOTOPRISM_DISABLE_CHOWN: \"true\" to disable storage permission updates" echo "updating storage permissions..." - chown -Rf "${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" /photoprism/storage /photoprism/import /photoprism/assets /var/lib/photoprism /tmp/photoprism + chown -Rf "${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" "${STORAGE_PATH}" /photoprism/import /var/lib/photoprism fi echo "running as uid ${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" + gosu "${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" doctor.sh echo "${@}" - gosu "${PHOTOPRISM_UID}:${PHOTOPRISM_GID}" "$@" & elif [[ ${PHOTOPRISM_UID} =~ $re ]] && [[ ${PHOTOPRISM_UID} != "0" ]]; then # user ID only @@ -72,25 +76,26 @@ if [[ $(id -u) == "0" ]]; then if [[ -z ${PHOTOPRISM_DISABLE_CHOWN} ]]; then echo "set PHOTOPRISM_DISABLE_CHOWN: \"true\" to disable storage permission updates" echo "updating storage permissions..." - chown -Rf "${PHOTOPRISM_UID}" /photoprism/storage /photoprism/import /photoprism/assets /var/lib/photoprism /tmp/photoprism + chown -Rf "${PHOTOPRISM_UID}" "${STORAGE_PATH}" /photoprism/import /var/lib/photoprism fi echo "running as uid ${PHOTOPRISM_UID}" + gosu "${PHOTOPRISM_UID}" doctor.sh echo "${@}" - gosu "${PHOTOPRISM_UID}" "$@" & else # no user or group ID set via end variable echo "running as root" + doctor.sh echo "${@}" - "$@" & fi else + # running as root echo "running as uid $(id -u)" + doctor.sh echo "${@}" - "$@" & fi diff --git a/scripts/init/heif-convert.sh b/scripts/dist/heif-convert.sh similarity index 100% rename from scripts/init/heif-convert.sh rename to scripts/dist/heif-convert.sh diff --git a/scripts/init/install-darktable.sh b/scripts/dist/install-darktable.sh similarity index 97% rename from scripts/init/install-darktable.sh rename to scripts/dist/install-darktable.sh index a0661a56e..944d004c7 100755 --- a/scripts/init/install-darktable.sh +++ b/scripts/dist/install-darktable.sh @@ -30,7 +30,7 @@ if [[ $INSTALL_ARCH == "amd64" ]]; then echo "install-darktable: installing standard amd64 (Intel 64-bit) package" apt-get -qq install darktable fi - echo "Installed." + echo "Done." elif [[ $INSTALL_ARCH == "arm64" ]]; then if [[ $VERSION_CODENAME == "bullseye" ]]; then apt-get update @@ -42,7 +42,7 @@ elif [[ $INSTALL_ARCH == "arm64" ]]; then echo "install-darktable: installing standard amd64 (ARM 64-bit) package" apt-get -qq install darktable fi - echo "Installed." + echo "Done." else echo "Unsupported Machine Architecture: $INSTALL_ARCH" fi diff --git a/scripts/init/install-devtools.sh b/scripts/dist/install-devtools.sh similarity index 98% rename from scripts/init/install-devtools.sh rename to scripts/dist/install-devtools.sh index ea994b52d..cabb2c03c 100755 --- a/scripts/init/install-devtools.sh +++ b/scripts/dist/install-devtools.sh @@ -53,4 +53,4 @@ elif [[ $INSTALL_ARCH == "arm64" ]]; then npm install --unsafe-perm=true --allow-root -g testcafe chromedriver fi -echo "Installed." \ No newline at end of file +echo "Done." \ No newline at end of file diff --git a/scripts/init/install-go.sh b/scripts/dist/install-go.sh similarity index 98% rename from scripts/init/install-go.sh rename to scripts/dist/install-go.sh index 5b08834b1..288135d2f 100755 --- a/scripts/init/install-go.sh +++ b/scripts/dist/install-go.sh @@ -45,4 +45,4 @@ rm go.tgz /usr/local/go/bin/go version -echo "Installed." \ No newline at end of file +echo "Done." \ No newline at end of file diff --git a/scripts/dist/install-mariadb.sh b/scripts/dist/install-mariadb.sh new file mode 100755 index 000000000..e124004c3 --- /dev/null +++ b/scripts/dist/install-mariadb.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# abort if the user is not root +if [[ $(id -u) != "0" ]]; then + echo "Usage: run install-mariadb-client.sh as root" 1>&2 + exit 1 +fi + +if [[ -z $1 ]]; then + echo "Usage: install-mariadb.sh [package names...]" 1>&2 + exit 1 +fi + +set -e + +SETUP_URL="https://downloads.mariadb.com/MariaDB/mariadb_repo_setup" + +if [ ! -f "/etc/apt/sources.list.d/mariadb.list" ]; then + echo "Adding MariaDB packages sources from \"$SETUP_URL\"..." + curl -Ls $SETUP_URL | bash -s -- --mariadb-server-version="mariadb-10.6" +fi + +echo "Installing \"$1\"..." + +apt-get update +apt-get -qq install $1 + +echo "Done." \ No newline at end of file diff --git a/scripts/init/install-nodejs.sh b/scripts/dist/install-nodejs.sh similarity index 63% rename from scripts/init/install-nodejs.sh rename to scripts/dist/install-nodejs.sh index e47c47884..cea6f792c 100755 --- a/scripts/init/install-nodejs.sh +++ b/scripts/dist/install-nodejs.sh @@ -6,9 +6,15 @@ if [[ $(id -u) != "0" ]]; then exit 1 fi -# install from nodesource.com -curl -sL https://deb.nodesource.com/setup_16.x | bash - +set -e + +SETUP_URL="https://deb.nodesource.com/setup_16.x" + +echo "Installing NodeJS and NPM from \"$SETUP_URL\"..." + +curl -sL $SETUP_URL | bash - apt-get update && apt-get -qq install nodejs npm install --unsafe-perm=true --allow-root -g npm npm config set cache ~/.cache/npm -echo "Installed." \ No newline at end of file + +echo "Done." \ No newline at end of file diff --git a/scripts/dist/install-tensorflow.sh b/scripts/dist/install-tensorflow.sh new file mode 100755 index 000000000..871dcdb87 --- /dev/null +++ b/scripts/dist/install-tensorflow.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -e + +TF_VERSION="1.15.2" + +DESTDIR=$(realpath "${1:-/usr}") + +echo "Installing TensorFlow in \"$DESTDIR\"..." + +# abort if the user is not root +if [[ $(id -u) != "0" ]] && [[ $DESTDIR == "/usr" || $DESTDIR == "/usr/local" ]]; then + echo "Error: Run install-tensorflow.sh as root to install in a system directory!" 1>&2 + exit 1 +fi + +mkdir -p "$DESTDIR" + +SYSTEM_ARCH=$("$(dirname "$0")/arch.sh") +INSTALL_ARCH=${2:-$SYSTEM_ARCH} +TMPDIR=${TMPDIR:-/tmp} + +if [[ -z $3 ]]; then + INSTALL_FILE="${INSTALL_ARCH}/libtensorflow-${INSTALL_ARCH}-${TF_VERSION}.tar.gz" +else + INSTALL_FILE="${INSTALL_ARCH}/libtensorflow-${INSTALL_ARCH}-${2}-${TF_VERSION}.tar.gz" +fi + +if [ ! -f "$TMPDIR/$INSTALL_FILE" ]; then + URL="https://dl.photoprism.app/tensorflow/${INSTALL_FILE}" + echo "Downloading $INSTALL_ARCH libs from \"$URL\". Please wait." + curl --create-dirs -fsSL -o "$TMPDIR/$INSTALL_FILE" "$URL" +fi + +echo "Extracting \"$TMPDIR/$INSTALL_FILE\" to \"$DESTDIR\"..." + +if [ -f "$TMPDIR/$INSTALL_FILE" ]; then + tar --overwrite --mode=755 -C "$DESTDIR" -xzf "$TMPDIR/$INSTALL_FILE" +else + echo "Fatal: \"$TMPDI/$INSTALL_FILE\" not found" + exit 1 +fi + +if [[ $DESTDIR == "/usr" || $DESTDIR == "/usr/local" ]]; then + echo "Running ldconfig..." + ldconfig +else + echo "Running \"ldconfig -n $DESTDIR/lib\"." + ldconfig -n "$DESTDIR/lib" +fi + +echo "Done." diff --git a/scripts/init/install-mariadb-client.sh b/scripts/init/install-mariadb-client.sh deleted file mode 100755 index ada9c8b2f..000000000 --- a/scripts/init/install-mariadb-client.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -# abort if the user is not root -if [[ $(id -u) != "0" ]]; then - echo "Usage: run install-mariadb-client.sh as root" 1>&2 - exit 1 -fi - -curl -Ls https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version="mariadb-10.6" -apt-get update -apt-get -qq install mariadb-client -echo "Installed." \ No newline at end of file diff --git a/scripts/init/install-tensorflow.sh b/scripts/init/install-tensorflow.sh deleted file mode 100755 index 889002e65..000000000 --- a/scripts/init/install-tensorflow.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash - -set -e - -TF_VERSION="1.15.2" - -DESTDIR=$(realpath "${1:-/usr}") - -echo "Installing TensorFlow in \"$DESTDIR\"..." - -# abort if the user is not root -if [[ $(id -u) != "0" ]] && [[ $DESTDIR == "/usr" || $DESTDIR == "/usr/local" ]]; then - echo "Error: Run install-tensorflow.sh as root to install in a system directory!" 1>&2 - exit 1 -fi - -mkdir -p "$DESTDIR" - -SYSTEM_ARCH=$("$(dirname "$0")/arch.sh") -INSTALL_ARCH=${2:-$SYSTEM_ARCH} - -if [[ -z $3 ]]; then - URL="https://dl.photoprism.app/tensorflow/${INSTALL_ARCH}/libtensorflow-${INSTALL_ARCH}-${TF_VERSION}.tar.gz" -else - URL="https://dl.photoprism.app/tensorflow/${INSTALL_ARCH}/libtensorflow-${INSTALL_ARCH}-${2}-${TF_VERSION}.tar.gz" -fi - -echo "Downloading $INSTALL_ARCH libs from \"$URL\". Please wait." - -curl -fsSL "$URL" | tar --overwrite --mode=755 -C "$DESTDIR" -xz - -if [[ $DESTDIR == "/usr" || $DESTDIR == "/usr/local" ]]; then - echo "Running ldconfig..." - ldconfig -else - echo "Running \"ldconfig -n $DESTDIR/lib\"." - ldconfig -n "$DESTDIR/lib" -fi - -echo "Installed."