From dd8476e2a0f347099958964876c99bb7e883ee19 Mon Sep 17 00:00:00 2001 From: Spoked <5782630+dreulavelle@users.noreply.github.com> Date: Tue, 19 Dec 2023 04:28:37 -0500 Subject: [PATCH] Docker (#70) * add makefile. fix entrypoint. dockerfile needs entrypoint execution tweak though. * Fixed entrypoint. Fixed user being set to root * Fix readme * Done. Can now set PUID/PGID correctly. Updated Dev Env makefile. * Sneak in update lol * Update help * Correct syntax for update. --------- Co-authored-by: Spoked --- .dockerignore | 1 + .gitignore | 3 ++- Dockerfile | 65 +++++++++++++++++++++++------------------------- README.md | 30 ++++++++++++++--------- entrypoint.sh | 43 ++++++++++++++++++-------------- makefile | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 145 insertions(+), 65 deletions(-) create mode 100644 makefile diff --git a/.dockerignore b/.dockerignore index eb3f86ff..d6838f2f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,7 @@ .dockerignore docker-compose.yml Dockerfile +makefile # Frontend .DS_Store diff --git a/.gitignore b/.gitignore index d5511e5f..6096d90b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ settings.json .vscode __pycache__ .git -docker-compose.yml \ No newline at end of file +docker-compose.yml +makefile \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index d35b0ec2..b8ff047c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,37 @@ -FROM alpine:3.19 - -LABEL org.label-schema.name="Iceberg" \ - org.label-schema.description="Iceberg Debrid Downloader" \ - org.label-schema.url="https://github.com/dreulavelle/iceberg" - -# Install necessary packages -RUN apk --update add python3 py3-pip nodejs npm bash shadow vim nano rclone && \ +# Frontend Builder +FROM node:20-alpine AS frontend +WORKDIR /app +COPY frontend/package*.json ./ +RUN npm install esbuild@0.19.9 +RUN npm install +COPY frontend/ . +RUN npm run build && npm prune --production + +# Final Image +FROM node:20-alpine + +LABEL name="Iceberg" \ + description="Iceberg Debrid Downloader" \ + url="https://github.com/dreulavelle/iceberg" + +RUN apk --update add python3 py3-pip bash shadow vim nano rclone && \ rm -rf /var/cache/apk/* -# Install pnpm -RUN npm install -g pnpm - -# Set the working directory WORKDIR /iceberg -# Copy the application files -COPY . /iceberg/ - -# Set up Python virtual environment and install dependencies -RUN python3 -m venv /venv && \ - source /venv/bin/activate && \ - pip install --no-cache-dir -r requirements.txt - -# Build the frontend -RUN cd frontend && \ - pnpm install && \ - pnpm run build - -# Expose necessary ports -EXPOSE 4173 8080 +# Frontend +COPY --from=frontend --chown=node:node /app/build /iceberg/frontend/build +COPY --from=frontend --chown=node:node /app/node_modules /iceberg/frontend/node_modules +COPY --from=frontend --chown=node:node /app/package.json /iceberg/frontend/package.json -# Copy and set permissions for the entrypoint script -COPY entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh +# Backend +COPY backend/ /iceberg/backend +RUN python3 -m venv /venv +COPY requirements.txt /iceberg/requirements.txt +RUN source /venv/bin/activate && pip install -r /iceberg/requirements.txt -# Set the entrypoint script -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +COPY entrypoint.sh ./entrypoint.sh +RUN chmod +x ./entrypoint.sh +ENTRYPOINT ["/iceberg/entrypoint.sh"] -# Start the backend first, then the frontend (suppressed frontend output) -CMD cd backend && source /venv/bin/activate && exec python main.py & \ - cd frontend && pnpm run preview --host 0.0.0.0 >/dev/null 2>&1 +EXPOSE 3000 8080 diff --git a/README.md b/README.md index 9f37df97..c55f65d1 100644 --- a/README.md +++ b/README.md @@ -41,22 +41,14 @@ services: container_name: Iceberg restart: unless-stopped environment: - - PUID=1000 - - GUID=1000 + PUID: "1000" + PGID: "1000" ports: - - "4173:4173" + - "3000:3000" volumes: - ./data:/iceberg/data ``` -> [!WARNING] -> You must have a standard settings.json file already in place before bind mounting it! -> An empty settings.json file, or no file at all, will cause issues! - -You can get a copy of the default settings [here](https://raw.githubusercontent.com/dreulavelle/iceberg/main/backend/utils/default_settings.json) - -After copying over the settings file (on a fresh install) you can bind mount it like the compose above. - ## Running outside of Docker First terminal: @@ -84,3 +76,19 @@ Rclone is mounted to /iceberg/vfs on your host machine -> settings should have: Plex container volume configuration for rclone mount is "/iceberg/vfs:/media/vfs" -> settings should have: "container_mount": "/media/vfs" Plex libraries you want to add to sections: movies -> /media/library/movies, shows -> /media/library/shows + + +## Development +You can view the readme in `make` to get started! + +```sh +make +``` + +To get started you can simply + +```sh +make start +``` + +You can restart with `make restart` **or** `make restart-nocache` to build the image without caching layers. diff --git a/entrypoint.sh b/entrypoint.sh index 7e47ddf7..0e619881 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,27 +1,34 @@ -#!/bin/sh +#!/bin/bash -echo "Starting Container with ${PUID}:${PGID} permissions..." +echo "Starting Container with ${PUID:-1000}:${PGID:-1000} permissions..." -# Create group if it doesn't exist or reuse the existing group -if ! getent group $PGID > /dev/null; then - addgroup -g $PGID iceberg +if ! [ "$PUID" -eq "$PUID" ] 2> /dev/null; then + echo "PUID is not a valid integer. Exiting..." + exit 1 +fi + +if ! [ "$PGID" -eq "$PGID" ] 2> /dev/null; then + echo "PGID is not a valid integer. Exiting..." + exit 1 +fi + +: ${USERNAME:=iceberg} +: ${GROUPNAME:=iceberg} + + +if ! getent group ${PGID} >/dev/null; then + addgroup -g $PGID $GROUPNAME > /dev/null else - existing_group=$(getent group $PGID | cut -d: -f1) - echo "Group with GID $PGID already exists as $existing_group" - iceberg_group=$existing_group + GROUPNAME=$(getent group ${PGID} | cut -d: -f1) fi -# Create user if it doesn't exist or reuse the existing user -if ! getent passwd $PUID > /dev/null; then - adduser -D -u $PUID -G ${iceberg_group:-iceberg} iceberg +if ! getent passwd ${PUID} >/dev/null; then + adduser -D -u $PUID -G $GROUPNAME $USERNAME > /dev/null else - existing_user=$(getent passwd $PUID | cut -d: -f1) - echo "User with UID $PUID already exists as $existing_user" - iceberg_user=$existing_user + USERNAME=$(getent passwd ${PUID} | cut -d: -f1) fi -# Change ownership of relevant directories -chown -R ${PUID}:${PGID} /iceberg +chown -R ${USERNAME}:${GROUPNAME} /iceberg -echo "Initialization complete. Executing main process..." -exec su -s /bin/sh -c "$@" ${iceberg_user:-iceberg} +echo "Container Initialization complete." +exec su -m $USERNAME -c 'cd backend && source /venv/bin/activate && exec python /iceberg/backend/main.py & node /iceberg/frontend/build' diff --git a/makefile b/makefile new file mode 100644 index 00000000..6affd144 --- /dev/null +++ b/makefile @@ -0,0 +1,68 @@ +.PHONY: help start reset stop restart rebuild logs exec sc ec update + +# Detect operating system +ifeq ($(OS),Windows_NT) + # For Windows + DATA_PATH := $(shell echo %cd%)\data +else + # For Linux + DATA_PATH := $(PWD)/data +endif + +help: + @echo Iceberg Local Development Environment + @echo ------------------------------------------------------------------------- + @echo start : Build and run the Iceberg container + @echo reset : Build and run the Iceberg container without caching image + @echo stop : Stop and remove the Iceberg container and image + @echo restart : Restart the Iceberg container (without rebuilding image) + @echo rebuild : Rebuild the Iceberg container (with rebuilding image) + @echo exec : Open a shell inside the Iceberg container + @echo logs : Show the logs of the Iceberg container + @echo sc : Show the contents of the settings.json file inside the Iceberg container + @echo ec : Edit the settings.json file inside the Iceberg container + @echo update : Update this repository from GitHub and rebuild image + @echo ------------------------------------------------------------------------- + +start: + @docker build -t iceberg:latest -f Dockerfile . + @docker run -d --name iceberg --hostname iceberg -p 3000:3000 -p 8080:8080 -e PUID=1000 -e PGID=1000 -v $(DATA_PATH):/iceberg/data iceberg:latest + @echo Iceberg Frontend is running on http://localhost:3000/status/ + @echo Iceberg Backend is running on http://localhost:8080/items/ + @docker logs iceberg -f + +reset: + @docker build --no-cache -t iceberg:latest -f Dockerfile . + @docker run -d --name iceberg --hostname iceberg -p 3000:3000 -p 8080:8080 -e PUID=1000 -e PGID=1000 -v $(DATA_PATH):/iceberg/data iceberg:latest + @echo Iceberg Frontend is running on http://localhost:3000/status/ + @echo Iceberg Backend is running on http://localhost:8080/items/ + @docker logs iceberg -f + +stop: + @-docker stop iceberg + @-docker rm iceberg + @-docker rmi iceberg:latest + +restart: + @-docker restart iceberg + @echo Iceberg Frontend is running on http://localhost:3000/status/ + @echo Iceberg Backend is running on http://localhost:8080/items/ + @docker logs iceberg -f + +rebuild: stop reset + +logs: + @docker logs iceberg -f + +exec: + @docker exec -it iceberg /bin/bash + +sc: + @docker exec -it iceberg /bin/bash -c "cat /iceberg/data/settings.json" + +ec: + @docker exec -it iceberg /bin/bash -c "vim /iceberg/data/settings.json" + +update: + @git pull + @make rebuild \ No newline at end of file