diff --git a/docker/Dockerfile b/docker/Dockerfile index a5b68b59..f50d68dc 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -7,9 +7,11 @@ FROM ghcr.io/linuxserver/baseimage-alpine:edge ENV OPENSSL_CONF="/etc/ssl" # For downloading thumbnails ENV SSL_CERT_DIR="/etc/ssl/certs/" +# Working directory used at both build and run times: +ENV DEFAULT_WORKSPACE="/config" COPY root/ / -RUN mkdir -p /config && \ +RUN mkdir -pv "${DEFAULT_WORKSPACE}" && \ apk update --no-cache && \ apk upgrade --no-cache && \ apk add --no-cache --repository=http://dl-3.alpinelinux.org/alpine/edge/main/ \ @@ -58,12 +60,12 @@ RUN mkdir -p /config && \ # CONTAINER CONFIGS ENV EDITOR="nano" \ -HOME="/config" \ +HOME="${DEFAULT_WORKSPACE}" \ DOCKER_MODS=linuxserver/mods:universal-stdout-logs|linuxserver/mods:universal-cron \ -DEFAULT_WORKSPACE=/config \ -CRON_SCRIPT="/config/cron" \ -CRON_WRAPPER_SCRIPT="/config/.cron_wrapper" \ -LOGS_TO_STDOUT=/config/.cron.log \ +CRON_SCRIPT="${DEFAULT_WORKSPACE}/cron" \ +CRON_WRAPPER_SCRIPT="${DEFAULT_WORKSPACE}/.cron_wrapper" \ +LOGS_TO_STDOUT="${DEFAULT_WORKSPACE}/.cron.log" \ LSIO_FIRST_PARTY=false -VOLUME /config \ No newline at end of file +VOLUME "${DEFAULT_WORKSPACE}" +WORKDIR "${DEFAULT_WORKSPACE}" diff --git a/docker/Dockerfile.gui b/docker/Dockerfile.gui index dd04e318..6e2f8309 100644 --- a/docker/Dockerfile.gui +++ b/docker/Dockerfile.gui @@ -81,9 +81,10 @@ ENV EDITOR="nano" \ HOME="/config" \ DOCKER_MODS=linuxserver/mods:universal-stdout-logs|linuxserver/mods:universal-cron \ DEFAULT_WORKSPACE=/config/ytdl-sub-configs \ -CRON_SCRIPT="/config/ytdl-sub-configs/cron" \ +CRON_SCRIPT="${DEFAULT_WORKSPACE}/cron" \ CRON_WRAPPER_SCRIPT="/config/.cron_wrapper" \ LOGS_TO_STDOUT=/config/.cron.log \ LSIO_FIRST_PARTY=false -VOLUME /config \ No newline at end of file +VOLUME /config +WORKDIR "${DEFAULT_WORKSPACE}" diff --git a/docker/Dockerfile.headless b/docker/Dockerfile.headless new file mode 120000 index 00000000..1d1fe94d --- /dev/null +++ b/docker/Dockerfile.headless @@ -0,0 +1 @@ +Dockerfile \ No newline at end of file diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu index de7dce0f..37240dd4 100644 --- a/docker/Dockerfile.ubuntu +++ b/docker/Dockerfile.ubuntu @@ -7,13 +7,15 @@ ARG DEBIAN_FRONTEND=noninteractive ENV OPENSSL_CONF="/etc/ssl" # For downloading thumbnails ENV SSL_CERT_DIR="/etc/ssl/certs/" +# Working directory used at both build and run times: +ENV DEFAULT_WORKSPACE="/config" ############################################################################### # YTDL-SUB INSTALL SHELL ["/bin/bash", "-c"] COPY root/ / -RUN mkdir -p /config && \ +RUN mkdir -pv "${DEFAULT_WORKSPACE}" && \ apt-get -y update && \ apt-get -y upgrade && \ apt-get install --no-install-recommends -y \ @@ -81,12 +83,12 @@ RUN mkdir -p /config && \ # CONTAINER CONFIGS ENV EDITOR="nano" \ -HOME="/config" \ +HOME="${DEFAULT_WORKSPACE}" \ DOCKER_MODS=linuxserver/mods:universal-stdout-logs|linuxserver/mods:universal-cron \ -DEFAULT_WORKSPACE=/config \ -CRON_SCRIPT="/config/cron" \ -CRON_WRAPPER_SCRIPT="/config/.cron_wrapper" \ -LOGS_TO_STDOUT=/config/.cron.log \ +CRON_SCRIPT="${DEFAULT_WORKSPACE}/cron" \ +CRON_WRAPPER_SCRIPT="${DEFAULT_WORKSPACE}/.cron_wrapper" \ +LOGS_TO_STDOUT="${DEFAULT_WORKSPACE}/.cron.log" \ LSIO_FIRST_PARTY=false -VOLUME /config \ No newline at end of file +VOLUME "${DEFAULT_WORKSPACE}" +WORKDIR "${DEFAULT_WORKSPACE}" diff --git a/docker/testing/Makefile b/docker/testing/Makefile new file mode 100644 index 00000000..89e6773c --- /dev/null +++ b/docker/testing/Makefile @@ -0,0 +1,46 @@ +# Local building and testing of the Docker image variants. + +# Defensive settings for make: +# https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +.SHELLFLAGS:=-eu -o pipefail -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules +export PS1?=$$ +# Prefix echoed recipe commands with the recipe line number for debugging: +export PS4?=:$$LINENO+ + +VARIANTS=headless gui ubuntu +ROOT_PREREQS:=$(shell find ../root -type f) + +# Finished with `$(shell)`, echo recipe commands going forward +.SHELLFLAGS+= -x + + +### Top-level targets: + +.PHONY: all +all: build + +.PHONY: build +build: $(VARIANTS:%=./build/ytdl-sub-%.log) + +.PHONY: run +run: build $(VARIANTS:%=./volumes/ytdl-sub-%/) + docker compose up + + +### Real targets: + +# Re-build the local images when changes require it. +./build/ytdl-sub-%.log: ../Dockerfile.% $(ROOT_PREREQS) + mkdir -pv "$(dir $(@))" + docker compose build "$(@:build/ytdl-sub-%.log=ytdl-sub-%)" |& + tee -a "$(@)" + +# Ensure volumes are owned by the developer's normal user: +./volumes/ytdl-sub-%/: + mkdir -pv "$(@)" diff --git a/docker/testing/docker-compose.yml b/docker/testing/docker-compose.yml index 432d0098..604ad5d9 100644 --- a/docker/testing/docker-compose.yml +++ b/docker/testing/docker-compose.yml @@ -1,39 +1,47 @@ services: ytdl-sub-gui: - image: ytdl-sub-gui:local - container_name: ytdl-sub-gui + build: + context: "../" + dockerfile: "./Dockerfile.gui" + image: "ytdl-sub-gui:local" + container_name: "ytdl-sub-gui" environment: - - PUID=1000 - - PGID=1000 - - TZ=America/Los_Angeles - - CRON_SCHEDULE="*/1 * * * *" - - CRON_RUN_ON_START=true + PUID: "1000" + PGID: "1000" + TZ: "America/Los_Angeles" + CRON_SCHEDULE: '"*/1 * * * *"' + CRON_RUN_ON_START: "true" volumes: - - ./volumes/ytdl-sub-gui:/config + - "./volumes/ytdl-sub-gui/:/config/" ports: - - 8443:8443 - restart: unless-stopped - ytdl-sub: - image: ytdl-sub:local - container_name: ytdl-sub + - "8443:8443" + restart: "unless-stopped" + ytdl-sub-headless: + build: + context: "../" + image: "ytdl-sub-headless:local" + container_name: "ytdl-sub-headless" environment: - - PUID=1000 - - PGID=1000 - - TZ=America/Los_Angeles - - CRON_SCHEDULE="*/1 * * * *" - - CRON_RUN_ON_START=true + PUID: "1000" + PGID: "1000" + TZ: "America/Los_Angeles" + CRON_SCHEDULE: '"*/1 * * * *"' + CRON_RUN_ON_START: "true" volumes: - - ./volumes/ytdl-sub:/config - restart: unless-stopped + - "./volumes/ytdl-sub-headless/:/config/" + restart: "unless-stopped" ytdl-sub-ubuntu: - image: ytdl-sub-ubuntu:local - container_name: ytdl-sub-ubuntu + build: + context: "../" + dockerfile: "./Dockerfile.ubuntu" + image: "ytdl-sub-ubuntu:local" + container_name: "ytdl-sub-ubuntu" environment: - - PUID=1000 - - PGID=1000 - - TZ=America/Los_Angeles - - CRON_SCHEDULE="*/1 * * * *" - - CRON_RUN_ON_START=true + PUID: "1000" + PGID: "1000" + TZ: "America/Los_Angeles" + CRON_SCHEDULE: '"*/1 * * * *"' + CRON_RUN_ON_START: "true" volumes: - - ./volumes/ytdl-sub:/config - restart: unless-stopped + - "./volumes/ytdl-sub-ubuntu/:/config/" + restart: "unless-stopped" diff --git a/docs/source/guides/development/index.rst b/docs/source/guides/development/index.rst index 4dfdb3c9..9183331a 100644 --- a/docs/source/guides/development/index.rst +++ b/docs/source/guides/development/index.rst @@ -52,9 +52,10 @@ above command will rebuild those as well. Testing ------- -Tests are written using pytest. Many of them evaluate checksums of output files to ensure no unintended -changes are introduced to the way ``ytdl-sub`` produces files. This checksum can be inaccurate for -end-to-end tests, but are reliable for integration tests. + +Tests are written using pytest. Many of them evaluate checksums of output files to +ensure no unintended changes are introduced to the way ``ytdl-sub`` produces files. This +checksum can be inaccurate for end-to-end tests, but are reliable for integration tests. If integration tests are failing, ensure... @@ -63,6 +64,20 @@ If integration tests are failing, ensure... - your local ``ytdl-sub`` dependencies are up-to-date +Docker +------ + +Test changes to the Docker image variants locally: + +.. code-block:: shell + + cd ./docker/testing/ + make -j run + +See ``./docker/testing/docker-compose.yml`` for the Compose services for each image +variant. + + IDE Setup ---------