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
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.git
.gradle
.idea
art
build
images
run
templates

*.zip
gradlew.bat
template.xsd
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
.gradle
/run/
/build/
/images/
/templates/
/art/

*.swp
*.txt
*.zip
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,11 @@ A tool to assemble Magic: The Gathering proxies from a set of template images. T

## Building
Proximity can be built using the command `gradlew shadowJar`, or by running the `shadowJar` task in your IDE.

# Docker support
To run this tool in docker, clone the repository, then run the below command from the root of the project.
If you are on Linux, make sure the read the segment on file ownership in the [docker readme](./docker/README.md).
```
docker-compose -f docker/docker-compose.yml up
```
For more details on the docker setup, and how to tweek if further, please see the [docker readme](./docker/README.md).
Empty file added art/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions cards.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1x Peek
1x Shock
1x Murder
14 changes: 14 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM gradle:jdk16 AS compiler
WORKDIR /home/gradle

COPY gradle build.gradle gradlew settings.gradle ./
COPY src src
RUN gradle shadowJar

FROM adoptopenjdk:16-jre-hotspot AS runner
WORKDIR /app

COPY --from=compiler /home/gradle/build/**/*all.jar proximity.jar
COPY docker/entrypoint.sh entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]
94 changes: 94 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Running the docker image via compose
To run this tool in docker, clone the repository, then, depending on platform, run the below command from the root of the project:
```
docker-compose -f docker/docker-compose.yml up
```
Remember that once a docker image is built, it will be reused for all subsequent runs unless a new image
is created that replaces it. To rebuild the image (if you pull new code changes, for example), append
the `--build` flag to the command, like this:
```
docker-compose -f docker/docker-compose.yml up --build
```

# Tweeking docker setup
This section aims to explain the different docker settings you can tinker with, as well as motivating some of
the design choices that's been made with regards to the docker files.

## Docker compose settings
The `docker-compose.yml` file controls what's going on once we run Proximity inside the docker container.
There are a couple of defaults set to give a smooth user experience firs time around: We
automatically mount and use the `cards.txt` file as the cardslist we'll generate, and we automatically
mount the `run/templates` folder, and use the `normal` template for card generation. Lastly, we mount
the `images` folder as output target for the Proximity process.

### Change the cards list
The simplest solution is to just edit the content of the existing `cards.txt` file to whatever you want.
If that for some reason isn't an option, and you would like to use another file for cards, replace the path
of the file to mount as cardslist (What's left of the `:` in Volume 1. The path is relative to the
docker-compose.yml file).

### Change the template
If you would like to use another template, the easiest solution is to place it in the `run/templates`
folder, and change `normal` in the `--template=normal` part of the run command to the name of the
new template folder (or the zip file, if you opt for using a zip).

### Change the output folder
If you would like to change the output folder, replace the path of the mounted output folder.
(What's left of the `:` in Volume 1. The path is relative to the docker-compose.yml file).

### Change command-line flags
If you want to add additional command line flags to pass to Proximity, the easiest is to just add them
at the end of the `command` section. A complete list of command-line flags that can be passed can be found
on the [wiki](https://github.com/Haven-King/Proximity/wiki).

## Running without compose
If you for some reason want to run the docker image without using compose, you will need to mount the
various volumes manually, and pass the appropriate CLI flags. By default, the image is design to use `/app`
as working directory. So the most convenient is to mount your list of cards at `/app/cardslist` and
your template at `/app/templates/normal`. Then, you will also need to mount an output folder, to be
able to extract the generated cards. Proximity outputs cards in a folder called `images`, so you'll
need to mount a folder at `/app/images` to be able to extract them.

An example command to achieve all this would be the following. This command will run Proximity with the
required mounts, and will include the `--cards` and `--template` flag.
```
docker run \
-v $PWD/cards.txt:/app/cardslist \
-v $PWD/run/templates:/app/templates \
-v $PWD/images:/app/images \
-v $PWD/art:/app/art \
proximity:latest \
--cards=cardslist --template=normal
```

## File owners on Linus
Files generated inside a docker container is owned by whatever process is executing the docker process. On
Mac and Windows, the docker process is run by the current user process, so files generated by the docker
process is owned by the user. But on Linux, the docker process is normally run as the `root` user. This
is normally not a problem, since docker isolates its file system inside the container. Proximity however
generates files that we want to access from outside the container (the output images), and thus, we mount
a directory to gain access to those files once they are generated. But since the files were generated by
the root user on Linux, normal users can't access these files.

For some distros of Linux, you can grant access to files generated by the docker process by adding your
user to the `docker` group (see for example [Arch's instructions](https://wiki.archlinux.org/title/Docker#Installation)).
This might not always be an option for you though: being part of the docker group easilly gives the user
priveledge access to the system via `docker run --privileged`.

Thus, we need a way for the docker process to generate files that can be accessed by the host user. There
are a few ways you can go about it, and the most common way is to set tell docker what user id and group id
to execute the container as (i.e. the `-u` flag or `user` in compose). But setting the user can have
some odd side effects on programs running in a container, because the assigned user doesn't really
exist and thus doesn't have what a program might assume a user has (for example, a home directory).
It also isn't easy to shop those settings pre-configured in a compose file,

Instead, we went with an approach where users may supply their user id and group id as environment
variables when executing the docker compose command. If the `GROUP_ID` and `USER_ID` env vars are
set when composer runs, those values are passed to the container. The entrypoint script will then
see these values, and run `chown -R` for those values on the generated output.

### TL:DR
Run the following on a Linux machine if you experience problems with file ownership:
````
GROUP_ID=$(id -g) USER_ID=$(id -u) docker-compose -f docker/docker-compose.yml up
```
17 changes: 17 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3'
services:
proximity:
build:
context: ../
dockerfile: ./docker/Dockerfile
environment:
USER_ID: ${USER_ID:-0}
GROUP_ID: ${GROUP_ID:-0}
TEMPLATE_NAME: ${TEMPLATE_NAME:-}
image: proximity:latest
volumes:
- ../cards.txt:/app/cardslist # Volume 1 - Mounts the default 'cards.txt' as cardslist
- ../templates:/app/templates # Volume 2 - Mounts templates from run/templates (i.e. normal and classic)
- ../images:/app/images # Volume 3 - Mounts the output folder
- ../art:/app/art # Volume 4 - Mounts local art folder
command: --cards=cardslist --template=$TEMPLATE_NAME --use_official_art=true
19 changes: 19 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh
set -e

# if the first arg is an option, pass all args to proximity
# else just exec whatever was supplied
if [ -z "$1" ]; then
echo "Please either supply options for Proximity, or a command to execute"
elif [ "${1#-}" != "$1" ]; then
java -jar proximity.jar "$@"
else
exec "$@"
fi

# if the USER_ID and GROUP_ID env vars are not 0, and the /app/images
# directory exists, chown /app/images to user USER_ID:GROUP_ID
if [ "$USER_ID" -ne "0" -a "$GROUP_ID" -ne "0" -a -d "/app/images" ]; then
echo "Running: chown -R $USER_ID:$GROUP_ID /app/images"
chown -R $USER_ID:$GROUP_ID /app/images
fi
Empty file added templates/.gitkeep
Empty file.