2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-12-22 19:31:35 +00:00

Start work on webp support

This commit is contained in:
asonix 2020-06-16 15:55:24 -05:00
parent 80d9387dbb
commit df85faff8b
10 changed files with 667 additions and 465 deletions

BIN
client-examples/1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:x86_64-unknown-linux-gnu AS x86_64-builder # Target environment
FROM amd64/ubuntu:20.04 as target-env
ENV \
TARGET=x86_64-unknown-linux-gnu \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=amd64 \
HOST=x86_64-unknown-linux \
TOOL=x86_64-linux-gnu \
TARGET=x86_64-unknown-linux-gnu \
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \
CC_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-gcc \
CXX_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
apt-get update && \ sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
apt-get upgrade -y && \ sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \ addgroup --gid 991 build && \
adduser \ adduser \
--disabled-password \ --disabled-password \
@ -10,167 +39,174 @@ RUN \
--ingroup build \ --ingroup build \
--uid 991 \ --uid 991 \
--home /opt/build \ --home /opt/build \
build build && \
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=x86_64-unknown-linux \
TARGET=x86_64-unknown-linux-gnu \
TOOL=x86_64-linux-gnu \
ARCH=amd64
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM x86_64-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
dpkg --add-architecture $ARCH && \ dpkg --add-architecture $ARCH && \
apt-get update && \ apt-get update && \
apt-get -y install \ apt-get upgrade -y && \
libgexiv2-dev:$ARCH \ apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \ libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \ libjpeg-dev:$ARCH \
libpng-dev:$ARCH \ libpng-dev:$ARCH \
libwebp-dev:$ARCH \ libwebp-dev:$ARCH \
liblzma-dev:$ARCH \ liblzma-dev:$ARCH \
llvm-dev \ libxml2-dev:$ARCH
libclang-dev \
clang && \
chown build:build ImageMagick.tar.gz
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build USER build
RUN \ RUN \
tar xvzf ImageMagick.tar.gz && \ tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
./configure \ ./configure \
CC=$TOOL-gcc \ CC=$TOOL-gcc \
CXX=$TOOL-g++ \ CXX=$TOOL-g++ \
--prefix=/imagemagick \ --enable-shared \
--with-modules \ --with-modules \
--enable-shared \ --disable-static \
--disable-static \ --disable-docs \
--without-perl \ --prefix=/usr/local \
--with-xml=yes \ --with-utilities=no \
--with-png=yes \ --without-perl \
--with-jpeg=yes \ --with-xml=yes \
--with-webp=yes \ --with-png=yes \
--host=$HOST && \ --with-jpeg=yes \
--with-webp=yes \
--host=$HOST && \
make make
USER root USER root
RUN \ RUN \
make install && \ make install && \
ldconfig /imagemagick/lib ldconfig /usr/local/lib
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
USER root
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \
apt-get install -y \
libgexiv2-dev:$ARCH \
libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
USER build USER build
WORKDIR /opt/build WORKDIR /opt/build
RUN \ RUN \
cargo new repo USER=build cargo new repo
WORKDIR /opt/build/repo WORKDIR /opt/build/repo
COPY Cargo.toml Cargo.lock ./ COPY --chown=build:build Cargo.toml Cargo.lock ./
USER root
RUN \
chown -R build:build ./
USER build
ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL" \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7"
RUN \ RUN \
mkdir -p ./src && \ mkdir -p ./src && \
echo 'fn main() { println!("Dummy") }' > ./src/main.rs && \ echo 'fn main() { println!("Dummy") }' > ./src/main.rs && \
cargo build --release && \ USER=build cargo build --$BUILD_MODE && \
rm -rf ./src rm -rf ./src && \
rm -rf ./target/$BUILD_MODE/deps/pict_rs-*
COPY src ./src/ COPY --chown=build:build src ./src/
USER root RUN \
RUN \ cargo build --$BUILD_MODE --frozen
chown -R build:build ./src && \
rm -r ./target/release/deps/pict_rs-* # Producing target binary
FROM target-env
USER build
ARG UID=991
RUN cargo build --release --frozen ARG GID=991
FROM ubuntu:20.04
ARG UID=1000
ARG GID=1000
ARG BINARY=pict-rs
ARG TARGET=x86_64-unknown-linux-gnu
RUN \ RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \ addgroup --gid $GID pictrs && \
adduser \ adduser \
--disabled-password \ --disabled-password \
--gecos "" \ --gecos "" \
--ingroup pictrs \ --ingroup pictrs \
--uid $UID \ --uid $UID \
--home /opt/pictrs \ --home /opt/pict-rs \
pictrs pictrs && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick COPY --from=pict-rs-builder /opt/build/repo/target/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=builder /opt/build/repo/target/release/$BINARY /usr/bin/$BINARY COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt VOLUME /mnt
WORKDIR /opt/pictrs WORKDIR /opt/pict-rs
USER pictrs USER pictrs
EXPOSE 8080 EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080"] CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -12,6 +12,6 @@ services:
- "127.0.0.1:8080:8080" - "127.0.0.1:8080:8080"
restart: always restart: always
environment: environment:
- PICTRS_PATH=/app/data - RUST_LOG=info,pict_rs=debug
volumes: volumes:
- ./volumes/pictrs:/mnt - ./volumes/pictrs:/mnt

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:x86_64-unknown-linux-gnu AS x86_64-builder # Target environment
FROM amd64/ubuntu:20.04 as target-env
ENV \
TARGET=x86_64-unknown-linux-gnu \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=amd64 \
HOST=x86_64-unknown-linux \
TOOL=x86_64-linux-gnu \
TARGET=x86_64-unknown-linux-gnu \
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \
CC_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-gcc \
CXX_X86_64_UNKNOWN_LINUX_GNU=x86_64-linux-gnu-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
apt-get update && \ sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
apt-get upgrade -y && \ sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \ addgroup --gid 991 build && \
adduser \ adduser \
--disabled-password \ --disabled-password \
@ -10,153 +39,168 @@ RUN \
--ingroup build \ --ingroup build \
--uid 991 \ --uid 991 \
--home /opt/build \ --home /opt/build \
build build && \
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=x86_64-unknown-linux \
TARGET=x86_64-unknown-linux-gnu \
TOOL=x86_64-linux-gnu \
ARCH=amd64
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM x86_64-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
dpkg --add-architecture $ARCH && \ dpkg --add-architecture $ARCH && \
apt-get update && \ apt-get update && \
apt-get -y install \ apt-get upgrade -y && \
libgexiv2-dev:$ARCH \ apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \ libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \ libjpeg-dev:$ARCH \
libpng-dev:$ARCH \ libpng-dev:$ARCH \
libwebp-dev:$ARCH \ libwebp-dev:$ARCH \
libxml2-dev:$ARCH \
liblzma-dev:$ARCH \ liblzma-dev:$ARCH \
llvm-dev \ libxml2-dev:$ARCH
libclang-dev \
clang && \
chown build:build ImageMagick.tar.gz
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build USER build
RUN \ RUN \
tar xzf ImageMagick.tar.gz && \ tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
./configure \ ./configure \
CC=$TOOL-gcc \ CC=$TOOL-gcc \
CXX=$TOOL-g++ \ CXX=$TOOL-g++ \
--prefix=/imagemagick \ --enable-shared \
--disable-docs \ --with-modules \
--with-modules \ --disable-static \
--enable-shared \ --disable-docs \
--disable-static \ --prefix=/usr/local \
--without-perl \ --with-utilities=no \
--with-xml=yes \ --without-perl \
--with-png=yes \ --with-xml=yes \
--with-jpeg=yes \ --with-png=yes \
--with-webp=yes \ --with-jpeg=yes \
--host=$HOST && \ --with-webp=yes \
--host=$HOST && \
make make
USER root USER root
RUN \ RUN \
make install && \ make install && \
ldconfig /imagemagick/lib ldconfig /usr/local/lib
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build USER build
WORKDIR /opt/build RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
ARG TAG=master USER root
ARG REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ARG BINARY=pict-rs
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \ RUN \
git clone -b $TAG $REPOSITORY repo apt-get install -y \
libgexiv2-dev:$ARCH \
WORKDIR /opt/build/repo libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang
ENV \ ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \ PATH=$PATH:/opt/build/.cargo/bin \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL" \ LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \ LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \ IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \ IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \ CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7" CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
ARG TAG=master
ARG GIT_REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ADD --chown=build:build $GIT_REPOSITORY/archive/$TAG.tar.gz /opt/build/$TAG.tar.gz
USER build
RUN \ RUN \
cargo build --release --target $TARGET && \ tar zxf $TAG.tar.gz
$TOOL-strip target/$TARGET/release/$BINARY
FROM amd64/ubuntu:20.04 WORKDIR /opt/build/pict-rs
RUN \
USER=build cargo build --target=$TARGET --$BUILD_MODE && \
$TOOL-strip /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs
# Producing target binary
FROM target-env
ARG TARGET=x86_64-unknown-linux-gnu
ARG UID=991 ARG UID=991
ARG GID=991 ARG GID=991
ARG BINARY=pict-rs
RUN \ RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \ addgroup --gid $GID pictrs && \
adduser \ adduser \
--disabled-password \ --disabled-password \
--gecos "" \ --gecos "" \
--ingroup pictrs \ --ingroup pictrs \
--uid $UID \ --uid $UID \
--home /opt/pictrs \ --home /opt/pict-rs \
pictrs && \ pictrs && \
chown -R pictrs:pictrs /mnt apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick COPY --from=pict-rs-builder /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=builder /opt/build/repo/target/$TARGET/release/$BINARY /usr/bin/$BINARY COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt VOLUME /mnt
WORKDIR /opt/pictrs WORKDIR /opt/pict-rs
USER pictrs USER pictrs
EXPOSE 8080 EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080", "-w", "thumbnail"] CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:arm-unknown-linux-gnueabihf AS arm32v7-builder # Target environment
FROM arm32v7/ubuntu:20.04 as target-env
ENV \
TARGET=armv7-unknown-linux-gnueabihf \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=armhf \
HOST=arm-unknown-linux \
TOOL=arm-linux-gnueabihf \
TARGET=armv7-unknown-linux-gnueabihf \
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
CC_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
CXX_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
apt-get update && \ sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
apt-get upgrade -y && \ sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \ addgroup --gid 991 build && \
adduser \ adduser \
--disabled-password \ --disabled-password \
@ -10,156 +39,169 @@ RUN \
--ingroup build \ --ingroup build \
--uid 991 \ --uid 991 \
--home /opt/build \ --home /opt/build \
build build && \
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=arm-unknown-linux \
TARGET=arm-unknown-linux-gnueabihf \
TOOL=arm-linux-gnueabihf \
ARCH=armhf
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM arm32v7-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
dpkg --add-architecture $ARCH && \ dpkg --add-architecture $ARCH && \
apt-get update && \ apt-get update && \
apt-get -y install \ apt-get upgrade -y && \
libgexiv2-dev:$ARCH \ apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \ libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \ libjpeg-dev:$ARCH \
libpng-dev:$ARCH \ libpng-dev:$ARCH \
libwebp-dev:$ARCH \ libwebp-dev:$ARCH \
libxml2-dev:$ARCH \
liblzma-dev:$ARCH \ liblzma-dev:$ARCH \
libc6-dev-$ARCH-cross \ libxml2-dev:$ARCH
llvm-dev \
libclang-dev \
clang \
libexpat1-dev:$ARCH && \
chown build:build ImageMagick.tar.gz
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build USER build
RUN \ RUN \
tar xzf ImageMagick.tar.gz && \ tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/lib/$TOOL -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
./configure \ ./configure \
CC=$TOOL-gcc \ CC=$TOOL-gcc \
CXX=$TOOL-g++ \ CXX=$TOOL-g++ \
--prefix=/imagemagick \ --enable-shared \
--disable-docs \ --with-modules \
--with-modules \ --disable-static \
--enable-shared \ --disable-docs \
--disable-static \ --prefix=/usr/local \
--without-perl \ --with-utilities=no \
--with-xml=yes \ --without-perl \
--with-png=yes \ --with-xml=yes \
--with-jpeg=yes \ --with-png=yes \
--with-webp=yes \ --with-jpeg=yes \
--host=$HOST && \ --with-webp=yes \
--host=$HOST && \
make make
USER root USER root
RUN \ RUN \
make install && \ make install && \
ldconfig /imagemagick/lib && \ ldconfig /usr/local/lib
rm -r /usr/include/x86_64-linux-gnu
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build USER build
WORKDIR /opt/build RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
ARG TAG=master USER root
ARG REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ARG BINARY=pict-rs
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \ RUN \
git clone -b $TAG $REPOSITORY repo apt-get install -y \
libgexiv2-dev:$ARCH \
WORKDIR /opt/build/repo libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang && \
rm -rf /usr/include/x86_64-linux-gnu
ENV \ ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \ PATH=$PATH:/opt/build/.cargo/bin \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
RUSTFLAGS="-L/usr/lib/$TOOL -L/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/lib/$TOOL" \ LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \ LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \ IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \ IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \ CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7" CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
ARG TAG=master
ARG GIT_REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ADD --chown=build:build $GIT_REPOSITORY/archive/$TAG.tar.gz /opt/build/$TAG.tar.gz
USER build
RUN \ RUN \
cargo build --release --target $TARGET && \ tar zxf $TAG.tar.gz
$TOOL-strip target/$TARGET/release/$BINARY
FROM arm32v7/ubuntu:20.04 WORKDIR /opt/build/pict-rs
RUN \
USER=build cargo build --target=$TARGET --$BUILD_MODE && \
$TOOL-strip /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs
# Producing target binary
FROM target-env
ARG TARGET=arm-unknown-linux-gnueabihf
ARG UID=991 ARG UID=991
ARG GID=991 ARG GID=991
ARG BINARY=pict-rs
RUN \ RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \ addgroup --gid $GID pictrs && \
adduser \ adduser \
--disabled-password \ --disabled-password \
--gecos "" \ --gecos "" \
--ingroup pictrs \ --ingroup pictrs \
--uid $UID \ --uid $UID \
--home /opt/pictrs \ --home /opt/pict-rs \
pictrs && \ pictrs && \
chown -R pictrs:pictrs /mnt apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick COPY --from=pict-rs-builder /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=builder /opt/build/repo/target/$TARGET/release/$BINARY /usr/bin/$BINARY COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt VOLUME /mnt
WORKDIR /opt/pictrs WORKDIR /opt/pict-rs
USER pictrs USER pictrs
EXPOSE 8080 EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080", "-w", "thumbnail"] CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -1,8 +1,37 @@
FROM rustembedded/cross:aarch64-unknown-linux-gnu AS aarch64-builder # Target environment
FROM arm64v8/ubuntu:20.04 as target-env
ENV \
TARGET=aarch64-unknown-linux-gnu \
BUILD_MODE=release
# Basic cross-build environment
FROM ubuntu:20.04 as cross-build
ENV \
ARCH=arm64 \
HOST=aarch64-unknown-linux \
TOOL=aarch64-linux-gnu \
TARGET=aarch64-unknown-linux-gnu \
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
CC_AARCH64_UNKNOWN_LINUX_GNU=aarch64-linux-gnu-gcc \
CXX_AARCH64_UNKNOWN_LINUX_GNU=aarch64-linux-gnu-g++ \
BUILD_MODE=release
ENV \
TOOLCHAIN=stable \
DEBIAN_FRONTEND=noninteractive \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LD_RUN_PATH=/usr/lib/$TOOL:/usr/$TOOL/lib \
LDFLAGS="-L/usr/lib/$TOOL -L/usr/$TOOL/lib -Wl,-rpath-link,/usr/lib/$TOOL -Wl,-rpath-link,/usr/$TOOL/lib" \
CFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="-I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
apt-get update && \ sed 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch-=amd64,i386] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list > /etc/apt/sources.list.d/ports.list && \
apt-get upgrade -y && \ sed -i 's/http:\/\/\(.*\).ubuntu.com\/ubuntu\//[arch=amd64,i386] http:\/\/\1.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list && \
addgroup --gid 991 build && \ addgroup --gid 991 build && \
adduser \ adduser \
--disabled-password \ --disabled-password \
@ -10,155 +39,169 @@ RUN \
--ingroup build \ --ingroup build \
--uid 991 \ --uid 991 \
--home /opt/build \ --home /opt/build \
build build && \
ADD https://sh.rustup.rs /opt/build/rustup.sh
RUN \
chown -R build:build /opt/build
USER build
WORKDIR /opt/build
ENV \
PATH=$PATH:/opt/build/.cargo/bin \
TOOLCHAIN=stable \
HOST=aarch64-unknown-linux \
TARGET=aarch64-unknown-linux-gnu \
TOOL=aarch64-linux-gnu \
ARCH=arm64
RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
FROM aarch64-builder as builder
USER root
ADD https://imagemagick.org/download/ImageMagick.tar.gz ./
RUN \
dpkg --add-architecture $ARCH && \ dpkg --add-architecture $ARCH && \
apt-get update && \ apt-get update && \
apt-get -y install \ apt-get upgrade -y && \
libgexiv2-dev:$ARCH \ apt-get install -y \
pkg-config \
build-essential \
crossbuild-essential-$ARCH
WORKDIR /opt/build
# Environment for ImageMagick
FROM cross-build as imagemagick-builder
RUN \
apt-get install -y \
libltdl-dev:$ARCH \ libltdl-dev:$ARCH \
libjpeg-dev:$ARCH \ libjpeg-dev:$ARCH \
libpng-dev:$ARCH \ libpng-dev:$ARCH \
libwebp-dev:$ARCH \ libwebp-dev:$ARCH \
libxml2-dev:$ARCH \
liblzma-dev:$ARCH \ liblzma-dev:$ARCH \
libc6-dev-$ARCH-cross \ libxml2-dev:$ARCH
llvm-dev \
libclang-dev \
clang && \
chown build:build ImageMagick.tar.gz
ADD --chown=build:build https://imagemagick.org/download/ImageMagick.tar.gz /opt/build/ImageMagick.tar.gz
USER build USER build
RUN \ RUN \
tar xzf ImageMagick.tar.gz && \ tar zxf ImageMagick.tar.gz && \
mv ImageMagick-* ImageMagick mv ImageMagick-* ImageMagick
WORKDIR /opt/build/ImageMagick WORKDIR /opt/build/ImageMagick
ENV \
USER=build \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=/usr/lib/$TOOL/pkgconfig:/usr/lib/pkgconfig \
LD_LIBRARY_PATH=/usr/lib/$TOOL \
LD_RUN_PATH=$LD_RUN_PATH:/usr/lib/$TOOL \
LDFLAGS="$LDFLAGS -L/usr/lib/$TOOL -Wl,-rpath-link,/usr/lib/$TOOL" \
CFLAGS="$CFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include" \
CPPFLAGS="$CPPFLAGS -I/usr/include/$TOOL -I/usr/$TOOL/include -I/usr/include"
RUN \ RUN \
./configure \ ./configure \
CC=$TOOL-gcc \ CC=$TOOL-gcc \
CXX=$TOOL-g++ \ CXX=$TOOL-g++ \
--prefix=/imagemagick \ --enable-shared \
--disable-docs \ --with-modules \
--with-modules \ --disable-static \
--enable-shared \ --disable-docs \
--disable-static \ --prefix=/usr/local \
--without-perl \ --with-utilities=no \
--with-xml=yes \ --without-perl \
--with-png=yes \ --with-xml=yes \
--with-jpeg=yes \ --with-png=yes \
--with-webp=yes \ --with-jpeg=yes \
--host=$HOST && \ --with-webp=yes \
--host=$HOST && \
make make
USER root USER root
RUN \ RUN \
make install && \ make install && \
ldconfig /imagemagick/lib && \ ldconfig /usr/local/lib
rm -r /usr/include/x86_64-linux-gnu
# Environment for Rust
FROM cross-build as rust
RUN \
apt-get install -y curl
ENV \
PATH=$PATH:/opt/build/.cargo/bin
ADD --chown=build:build https://sh.rustup.rs /opt/build/rustup.sh
USER build USER build
WORKDIR /opt/build RUN \
chmod +x rustup.sh && \
./rustup.sh --default-toolchain $TOOLCHAIN --profile minimal -y && \
rustup target add $TARGET
ARG TAG=master USER root
ARG REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ARG BINARY=pict-rs
# Environment for pict-rs
FROM cross-build as pict-rs-builder
RUN \ RUN \
git clone -b $TAG $REPOSITORY repo apt-get install -y \
libgexiv2-dev:$ARCH \
WORKDIR /opt/build/repo libxml2:$ARCH \
libltdl7:$ARCH \
llvm-dev \
libclang-dev \
clang && \
rm -rf /usr/include/x86_64-linux-gnu
ENV \ ENV \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/imagemagick/lib \ PATH=$PATH:/opt/build/.cargo/bin \
LD_RUN_PATH=$LD_RUN_PATH:/imagemagick/lib \ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
LDFLAGS="$LDFLAGS -L/imagemagick/lib" \ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL" \ LD_RUN_PATH=$LD_RUN_PATH:/usr/local/lib \
IMAGE_MAGICK_LIB_DIRS=/imagemagick/lib \ LDFLAGS="$LDFLAGS -L/usr/local/lib" \
IMAGE_MAGICK_INCLUDE_DIRS=/imagemagick/include/ImageMagick-7 \ IMAGE_MAGICK_LIB_DIRS=/usr/local/lib \
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/imagemagick/lib/pkgconfig \ IMAGE_MAGICK_INCLUDE_DIRS=/usr/local/include/ImageMagick-7 \
CFLAGS="$CFLAGS -I/imagemagick/include/ImageMagick-7" \ CFLAGS="$CFLAGS -I/usr/local/include/ImageMagick-7" \
CPPFLAGS="$CPPFLAGS -I/imagemagick/include/ImageMagick-7" CPPFLAGS="$CPPFLAGS -I/usr/local/include/ImageMagick-7" \
RUSTFLAGS="-L/usr/lib/$TOOL -C link-arg=-Wl,-rpath-link,/usr/lib/$TOOL -L/usr/$TOOL/lib -C link-arg=-Wl,-rpath-link,/usr/$TOOL/lib"
COPY --from=rust --chown=build:build /opt/build/.cargo /opt/build/.cargo
COPY --from=rust --chown=build:build /opt/build/.rustup /opt/build/.rustup
COPY --from=imagemagick-builder /usr/local/ /usr/local
ARG TAG=master
ARG GIT_REPOSITORY=https://git.asonix.dog/asonix/pict-rs
ADD --chown=build:build $GIT_REPOSITORY/archive/$TAG.tar.gz /opt/build/$TAG.tar.gz
USER build
RUN \ RUN \
cargo build --release --target $TARGET && \ tar zxf $TAG.tar.gz
$TOOL-strip target/$TARGET/release/$BINARY
FROM arm64v8/ubuntu:20.04 WORKDIR /opt/build/pict-rs
RUN \
USER=build cargo build --target=$TARGET --$BUILD_MODE && \
$TOOL-strip /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs
# Producing target binary
FROM target-env
ARG TARGET=aarch64-unknown-linux-gnu
ARG UID=991 ARG UID=991
ARG GID=991 ARG GID=991
ARG BINARY=pict-rs
RUN \ RUN \
apt-get update && \
apt-get -y upgrade && \
apt-get -y install \
tini \
libgexiv2-2 \
libgomp1 \
libltdl7 && \
addgroup --gid $GID pictrs && \ addgroup --gid $GID pictrs && \
adduser \ adduser \
--disabled-password \ --disabled-password \
--gecos "" \ --gecos "" \
--ingroup pictrs \ --ingroup pictrs \
--uid $UID \ --uid $UID \
--home /opt/pictrs \ --home /opt/pict-rs \
pictrs && \ pictrs && \
chown -R pictrs:pictrs /mnt apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
libgexiv2-2 \
libpng16-16 \
libjpeg8 \
libwebp6 \
libwebpdemux2 \
libwebpmux3 \
libltdl7 \
libgomp1 \
libxml2 \
tini
COPY --from=builder /imagemagick /imagemagick COPY --from=pict-rs-builder /opt/build/pict-rs/target/$TARGET/$BUILD_MODE/pict-rs /usr/local/bin/pict-rs
COPY --from=builder /opt/build/repo/target/$TARGET/release/$BINARY /usr/bin/$BINARY COPY --from=imagemagick-builder /usr/local /usr/local
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
VOLUME /mnt VOLUME /mnt
WORKDIR /opt/pictrs WORKDIR /opt/pict-rs
USER pictrs USER pictrs
EXPOSE 8080 EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/bin/pict-rs", "-p", "/mnt", "-a", "0.0.0.0:8080", "-w", "thumbnail"] CMD ["/usr/local/bin/pict-rs", "-p", "/mnt"]

View file

@ -30,7 +30,7 @@ pub(crate) struct Config {
short, short,
long, long,
env = "PICTRS_FORMAT", env = "PICTRS_FORMAT",
help = "An optional image format to convert all uploaded files into, supports 'jpg' and 'png'" help = "An optional image format to convert all uploaded files into, supports 'jpg', 'png', and 'webp'"
)] )]
format: Option<Format>, format: Option<Format>,
@ -88,6 +88,7 @@ pub(crate) struct FormatError(String);
pub(crate) enum Format { pub(crate) enum Format {
Jpeg, Jpeg,
Png, Png,
Webp,
} }
impl std::str::FromStr for Format { impl std::str::FromStr for Format {
@ -97,6 +98,7 @@ impl std::str::FromStr for Format {
match s { match s {
"png" => Ok(Format::Png), "png" => Ok(Format::Png),
"jpg" => Ok(Format::Jpeg), "jpg" => Ok(Format::Jpeg),
"webp" => Ok(Format::Webp),
other => Err(FormatError(other.to_string())), other => Err(FormatError(other.to_string())),
} }
} }

View file

@ -68,6 +68,9 @@ pub(crate) enum UploadError {
#[error("File metadata could not be parsed, {0}")] #[error("File metadata could not be parsed, {0}")]
Validate(#[from] rexiv2::Rexiv2Error), Validate(#[from] rexiv2::Rexiv2Error),
#[error("Error in MagickWand, {0}")]
Wand(String),
} }
impl From<actix_web::client::SendRequestError> for UploadError { impl From<actix_web::client::SendRequestError> for UploadError {

View file

@ -23,6 +23,7 @@ mod validate;
use self::{ use self::{
config::Config, error::UploadError, middleware::Tracing, upload_manager::UploadManager, config::Config, error::UploadError, middleware::Tracing, upload_manager::UploadManager,
validate::image_webp,
}; };
const MEGABYTES: usize = 1024 * 1024; const MEGABYTES: usize = 1024 * 1024;
@ -75,7 +76,7 @@ fn to_ext(mime: mime::Mime) -> &'static str {
} else if mime == mime::IMAGE_GIF { } else if mime == mime::IMAGE_GIF {
".gif" ".gif"
} else { } else {
".bmp" ".webp"
} }
} }
@ -84,7 +85,7 @@ fn from_ext(ext: std::ffi::OsString) -> mime::Mime {
Some("png") => mime::IMAGE_PNG, Some("png") => mime::IMAGE_PNG,
Some("jpg") => mime::IMAGE_JPEG, Some("jpg") => mime::IMAGE_JPEG,
Some("gif") => mime::IMAGE_GIF, Some("gif") => mime::IMAGE_GIF,
_ => mime::IMAGE_BMP, _ => image_webp(),
} }
} }

View file

@ -1,13 +1,37 @@
use crate::{config::Format, error::UploadError, upload_manager::tmp_file}; use crate::{config::Format, error::UploadError, upload_manager::tmp_file};
use actix_web::web; use actix_web::web;
use image::{io::Reader, ImageDecoder, ImageEncoder, ImageFormat}; use image::{io::Reader, ImageFormat};
use magick_rust::MagickWand;
use rexiv2::{MediaType, Metadata}; use rexiv2::{MediaType, Metadata};
use std::{ use std::{
fs::File, fs::File,
io::{BufReader, BufWriter, Write}, io::{BufReader, BufWriter, Write},
path::PathBuf, path::PathBuf,
}; };
use tracing::{debug, instrument, trace, Span}; use tracing::{debug, error, instrument, trace, warn, Span};
pub(crate) trait Op {
fn op<F, T>(&self, f: F) -> Result<T, UploadError>
where
F: Fn(&Self) -> Result<T, &'static str>;
}
impl Op for MagickWand {
fn op<F, T>(&self, f: F) -> Result<T, UploadError>
where
F: Fn(&Self) -> Result<T, &'static str>,
{
match f(self) {
Ok(t) => Ok(t),
Err(e) => {
if let Ok(e) = self.get_exception() {
error!("WandError: {}", e.0);
}
Err(UploadError::Wand(e.to_owned()))
}
}
}
}
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub(crate) enum GifError { pub(crate) enum GifError {
@ -18,12 +42,21 @@ pub(crate) enum GifError {
Io(#[from] std::io::Error), Io(#[from] std::io::Error),
} }
pub(crate) fn image_webp() -> mime::Mime {
"image/webp".parse().unwrap()
}
fn ptos(p: &PathBuf) -> Result<String, UploadError> {
Ok(p.to_str().ok_or(UploadError::Path)?.to_owned())
}
// import & export image using the image crate // import & export image using the image crate
#[instrument] #[instrument]
pub(crate) async fn validate_image( pub(crate) async fn validate_image(
tmpfile: PathBuf, tmpfile: PathBuf,
prescribed_format: Option<Format>, prescribed_format: Option<Format>,
) -> Result<mime::Mime, UploadError> { ) -> Result<mime::Mime, UploadError> {
let tmpfile_str = ptos(&tmpfile)?;
let span = Span::current(); let span = Span::current();
let content_type = web::block(move || { let content_type = web::block(move || {
@ -39,21 +72,54 @@ pub(crate) async fn validate_image(
mime::IMAGE_GIF mime::IMAGE_GIF
} }
(Some(Format::Jpeg), MediaType::Jpeg) | (None, MediaType::Jpeg) => { (Some(Format::Jpeg), MediaType::Jpeg) | (None, MediaType::Jpeg) => {
validate(&tmpfile, ImageFormat::Jpeg)?; {
let wand = MagickWand::new();
debug!("reading: {}", tmpfile_str);
wand.op(|w| w.read_image(&tmpfile_str))?;
debug!("format: {}", wand.op(|w| w.get_format())?);
}
let meta = Metadata::new_from_path(&tmpfile)?;
meta.clear(); meta.clear();
meta.save_to_file(&tmpfile)?; meta.save_to_file(&tmpfile)?;
mime::IMAGE_JPEG mime::IMAGE_JPEG
} }
(Some(Format::Png), MediaType::Png) | (None, MediaType::Png) => { (Some(Format::Png), MediaType::Png) | (None, MediaType::Png) => {
validate(&tmpfile, ImageFormat::Png)?; {
let wand = MagickWand::new();
debug!("reading: {}", tmpfile_str);
wand.op(|w| w.read_image(&tmpfile_str))?;
debug!("format: {}", wand.op(|w| w.get_format())?);
}
let meta = Metadata::new_from_path(&tmpfile)?;
meta.clear(); meta.clear();
meta.save_to_file(&tmpfile)?; meta.save_to_file(&tmpfile)?;
mime::IMAGE_PNG mime::IMAGE_PNG
} }
(Some(Format::Webp), MediaType::Other(webp)) | (None, MediaType::Other(webp))
if webp == "image/webp" =>
{
{
let wand = MagickWand::new();
debug!("reading: {}", tmpfile_str);
wand.op(|w| w.read_image(&tmpfile_str))?;
debug!("format: {}", wand.op(|w| w.get_format())?);
debug!("type: {}", wand.op(|w| Ok(w.get_type()))?);
debug!("image_type: {}", wand.op(|w| Ok(w.get_image_type()))?);
}
// let meta = Metadata::new_from_path(&tmpfile)?;
// meta.clear();
// meta.save_to_file(&tmpfile)?;
image_webp()
}
(Some(Format::Jpeg), _) => { (Some(Format::Jpeg), _) => {
let newfile = tmp_file(); let newfile = tmp_file();
convert(&tmpfile, &newfile, ImageFormat::Jpeg)?; convert(&tmpfile, &newfile, ImageFormat::Jpeg)?;
@ -66,13 +132,10 @@ pub(crate) async fn validate_image(
mime::IMAGE_PNG mime::IMAGE_PNG
} }
(_, MediaType::Bmp) => { (_, media_type) => {
let newfile = tmp_file(); warn!("Unsupported media type, {}", media_type);
validate_bmp(&tmpfile, &newfile)?; return Err(UploadError::UnsupportedFormat);
mime::IMAGE_BMP
} }
_ => return Err(UploadError::UnsupportedFormat),
}; };
drop(entered); drop(entered);
@ -112,20 +175,6 @@ fn validate(path: &PathBuf, format: ImageFormat) -> Result<(), UploadError> {
Ok(()) Ok(())
} }
#[instrument]
fn validate_bmp(from: &PathBuf, to: &PathBuf) -> Result<(), UploadError> {
debug!("Transmuting BMP");
let decoder = image::bmp::BmpDecoder::new(BufReader::new(File::open(from)?))?;
let mut writer = BufWriter::new(File::create(to)?);
let encoder = image::bmp::BMPEncoder::new(&mut writer);
validate_still_image(decoder, encoder)?;
writer.flush()?;
std::fs::rename(to, from)?;
Ok(())
}
#[instrument] #[instrument]
fn validate_gif(from: &PathBuf, to: &PathBuf) -> Result<(), GifError> { fn validate_gif(from: &PathBuf, to: &PathBuf) -> Result<(), GifError> {
debug!("Transmuting GIF"); debug!("Transmuting GIF");
@ -157,21 +206,3 @@ fn validate_gif(from: &PathBuf, to: &PathBuf) -> Result<(), GifError> {
std::fs::rename(to, from)?; std::fs::rename(to, from)?;
Ok(()) Ok(())
} }
fn validate_still_image<'a, D, E>(decoder: D, encoder: E) -> Result<(), UploadError>
where
D: ImageDecoder<'a>,
E: ImageEncoder,
{
let (width, height) = decoder.dimensions();
let color_type = decoder.color_type();
let total_bytes = decoder.total_bytes();
debug!("Reading image");
let mut decoded_bytes = vec![0u8; total_bytes as usize];
decoder.read_image(&mut decoded_bytes)?;
debug!("Writing image");
encoder.write_image(&decoded_bytes, width, height, color_type)?;
Ok(())
}