Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.git
target
work
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@
/target/
/version.properties
/temp/

# Runtime directory for Docker Compose volume mount
/work/
33 changes: 30 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,33 @@ docker run --rm -v `pwd`:/work fits -r -n -i in-dir -o out-dir
docker run --rm -v `pwd`:/work fits -f fits-custom.xml -i file.txt
```

### Docker Compose Installation

To run FITS using Docker Compose, you'll need Docker (or Docker-compatible service) with the Compose plugin installed.
Comment thread
guinslym marked this conversation as resolved.

1. Clone this repository (or download and extract a copy of the source).
2. Build the Docker image using the provided `docker-compose.yml`.

```shell
git clone https://github.com/harvard-lts/fits.git
cd fits
docker compose build fits
```

After building the image, place the files you want to analyze in the `work/` subdirectory (it is created automatically
on first run). FITS will have access to anything inside that directory. Run FITS using `docker compose run`:

```shell
# Run FITS on a file
docker compose run --rm fits -i /work/file.txt

# Run FITS on a directory
docker compose run --rm fits -r -n -i /work/in-dir -o /work/out-dir

# Run FITS with alternate configuration
docker compose run --rm fits -f fits-custom.xml -i /work/file.txt
```

## Configuration

### Logging
Expand Down Expand Up @@ -175,8 +202,8 @@ consistent. To do so, first install Docker, Podman, or an equivalent
container service, and execute the following:

# The build only needs to be run once
docker build -f docker/Dockerfile-test -t fits-test .
docker run --rm -v `pwd`:/fits -v ~/.m2:/root/.m2 fits-test mvn clean test
docker compose build test
docker compose run --rm test

To build yet skip the tests, use the following command:

Expand All @@ -201,7 +228,7 @@ The test expectation xml files can be overwritten with the current FITS output b
`-Doverwrite=true` flag. For example:

```shell
docker run --rm -v `pwd`:/fits -v ~/.m2:/root/.m2 fits-test mvn -Doverwrite=true clean test
docker compose run --rm test mvn -Doverwrite=true clean test
```

However, generally speaking, test expectation files should be changed as little as possible so that the diffs are
Expand Down
27 changes: 27 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
services:
# Build and run FITS from source (no Maven required on host)
fits:
build:
context: .
dockerfile: docker/Dockerfile-compose
network: host
image: fits:latest
volumes:
- ./work:/work:z
# Example: docker compose run --rm fits -i myfile.txt
entrypoint: ["/opt/fits/fits.sh"]

# Run unit tests
test:
build:
context: .
dockerfile: docker/Dockerfile-test
volumes:
- .:/fits:z
- maven-cache:/root/.m2
command: mvn clean test
profiles:
- test

volumes:
maven-cache:
64 changes: 64 additions & 0 deletions docker/Dockerfile-compose
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Multi-stage Dockerfile that builds FITS from source without requiring
# Maven on the host.

# Stage 1: Build with Maven
FROM docker.io/maven:3-eclipse-temurin-17 AS build
WORKDIR /src
COPY . .
RUN mvn -e -DskipTests -Dfits.install.platforms=linux clean package

# Stage 2: Runtime image (same as docker/Dockerfile)
FROM docker.io/eclipse-temurin:17-jre-jammy

ARG FILE_VERSION=5.43
ARG FILE_SHA256=8c8015e91ae0e8d0321d94c78239892ef9dbc70c4ade0008c0e95894abfb1991

RUN apt-get update && \
apt-get install -yqq \
# jpylyzer dependencies
python3 \
python-is-python3 \
# exiftool dependencies https://github.com/exiftool/exiftool
libarchive-zip-perl \
libio-compress-perl \
libcompress-raw-zlib-perl \
libcompress-bzip2-perl \
libcompress-raw-bzip2-perl \
libio-digest-perl \
libdigest-md5-file-perl \
libdigest-perl-md5-perl \
libdigest-sha-perl \
libposix-strptime-perl \
libunicode-linebreak-perl\
# file dependencies
make \
gcc \
# mediainfo dependencies
libmms0 \
libcurl3-gnutls \
# FITS
unzip \
&& rm -rf /var/lib/apt/lists/*

# Install file https://github.com/file/file
RUN cd /var/tmp && \
curl -so file-${FILE_VERSION}.tar.gz https://astron.com/pub/file/file-${FILE_VERSION}.tar.gz && \
echo "${FILE_SHA256} file-${FILE_VERSION}.tar.gz" | sha256sum --check && \
tar xzf file-${FILE_VERSION}.tar.gz && \
cd file-${FILE_VERSION} && \
./configure && \
make -j4 && \
make install && \
ldconfig && \
cd .. && \
rm -rf file-${FILE_VERSION}*

# Install FITS from build stage
COPY --from=build /src/target/fits-*.zip /opt/fits.zip
RUN unzip -q /opt/fits.zip -d /opt/fits && \
rm /opt/fits.zip && \
mkdir -p /var/log/fits

WORKDIR /work

ENTRYPOINT ["/opt/fits/fits.sh"]
2 changes: 1 addition & 1 deletion docs_readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,4 @@ When contributing to the documentation:
4. **Check links** to ensure they work correctly
5. **Optimize images** for web use before adding them

For more information about contributing to FITS, see the main project [CONTRIBUTING.md](../CONTRIBUTING.md).
For more information about contributing to FITS, see the main project [CONTRIBUTING.md](../CONTRIBUTING.md).
43 changes: 36 additions & 7 deletions src/main/script/ToolInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -80,6 +81,16 @@ public static Tool fromString(String value) {
private static final Path TOOLS_ROOT = ROOT.resolve("tools");
private static final Path PROPS_FILE = ROOT.resolve("tools.properties");

/**
* Controls which platform-specific tool binaries are installed. Defaults to all platforms.
* Override by passing -Dfits.install.platforms=linux (or linux,mac,windows) to the JVM.
*/
private static final Set<String> INSTALL_PLATFORMS = Arrays.stream(
Comment thread
guinslym marked this conversation as resolved.
System.getProperty("fits.install.platforms", "linux,mac,windows").split(","))
.map(String::trim)
.map(String::toLowerCase)
.collect(Collectors.toSet());

private static final String VERSION_FILE_NAME = "version";

private static final String UNIX = "unix.";
Expand Down Expand Up @@ -156,14 +167,24 @@ public void execute() throws IOException {
}

private void installExiftool() throws IOException {
installExiftoolUnix();
installExiftoolWindows();
if (INSTALL_PLATFORMS.contains("linux")) {
installExiftoolUnix();
}
if (INSTALL_PLATFORMS.contains("windows")) {
installExiftoolWindows();
}
}

private void installMediaInfo() throws IOException {
installMediaInfoMac();
installMediaInfoWindows();
installMediaInfoLinux();
if (INSTALL_PLATFORMS.contains("linux")) {
installMediaInfoLinux();
}
if (INSTALL_PLATFORMS.contains("mac")) {
installMediaInfoMac();
}
if (INSTALL_PLATFORMS.contains("windows")) {
installMediaInfoWindows();
}
}

private void installMediaInfoMac() throws IOException {
Expand Down Expand Up @@ -261,6 +282,10 @@ private void installExiftoolWindows() throws IOException {
}

private void installFileUtility() throws IOException {
if (!INSTALL_PLATFORMS.contains("windows")) {
return;
}

var target = toolDir.resolve(tool.windowsDir);

// Install file utility
Expand All @@ -275,8 +300,12 @@ private void installFileUtility() throws IOException {
}

private void installJpylyzer() throws IOException {
installJpylyzerWindows();
installJpylyzerUnix();
if (INSTALL_PLATFORMS.contains("linux")) {
installJpylyzerUnix();
}
if (INSTALL_PLATFORMS.contains("windows")) {
installJpylyzerWindows();
}
}

private void installJpylyzerWindows() throws IOException {
Expand Down
7 changes: 7 additions & 0 deletions tool-poms/tool-installer-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
<relativePath>../pom.xml</relativePath>
</parent>

<properties>
<!-- Comma-separated list of platforms to install tool binaries for.
Pass -Dfits.install.platforms=linux to Maven to install only Linux binaries. -->
<fits.install.platforms>linux,mac,windows</fits.install.platforms>
</properties>

<build>
<plugins>
<!-- Copy the scripts dependencies into target -->
Expand Down Expand Up @@ -49,6 +55,7 @@
<workingDirectory>..</workingDirectory>
<executable>java</executable>
<arguments>
<argument>-Dfits.install.platforms=${fits.install.platforms}</argument>
<argument>-cp</argument>
<argument>target/tool-installer-lib/*</argument>
<argument>src/main/script/ToolInstaller.java</argument>
Expand Down
10 changes: 5 additions & 5 deletions tools.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# exiftool
# When upgrading exiftool, be sure to select a *production release* version (https://www.exiftool.org/history.html).
# None production releases are not available for download long-term.
exiftool.version=13.36
exiftool.unix.url=https://sourceforge.net/projects/exiftool/files/Image-ExifTool-13.36.tar.gz/download
exiftool.unix.md5=8386ca5cd2335009648278b64f0e6061
exiftool.windows.url=https://sourceforge.net/projects/exiftool/files/exiftool-13.36_64.zip/download
exiftool.windows.md5=867d26f7cfcd48c4d9228d78f698e326
exiftool.version=13.50
exiftool.unix.url=https://sourceforge.net/projects/exiftool/files/Image-ExifTool-13.50.tar.gz/download
exiftool.unix.md5=4c9b544800bca220d21ecced4585f4d1
exiftool.windows.url=https://sourceforge.net/projects/exiftool/files/exiftool-13.50_64.zip/download
exiftool.windows.md5=3cf829e28af2be7e2d88f97ba84f177f

# MediaInfo
# https://mediaarea.net/en/MediaInfo/Download
Expand Down