# This Dockerfile will build an image to run a MVS38J system based # on my copy of the TK4- system. # # Runs hercules under uid 6001 (named hercules) to keep it clear of normal # host system uids starting in the 1000 range. # # >>>> You M U S T change <<<<< # globally change tk4-minus to the directory name your mvs3.8j system # lives under. And that dir must be directly under the dir with this # Dockerfile. # # In the container I place my mvs38j install under /home/hercules/tk4-minus # which is set as an environment variable in this dockerfile and used # everywhere in the dockerfile EXCEPT # EXCEPT for the CMD and HEALTHCHECK where a dockerfile variable # should not be used. # The environment conf file used by all teh scripts copied into # the container should be updated to match anything you change here. # # Build with one of the two below, depending upon what you use # (you may change the name from mvs38j of course) # docker build -t localhost/mvs38j . # podman build -t localhost/mvs38j . # # Can be run to test it with (once built of course) # Adjust the timezone offset that will be uodated in the config file # for your location is needed. # docker run --memory=250m --cpus="0.5" --rm -d --name mvstest \ # -p 3270:3270/tcp -p 3505:3505/tcp \ # -e "MVSTZOFFSET=+1100" \ # localhost/mvs38j # ============================================================ # The first block --- create a temporary image # IMPORTANT name it (I am naming it 'build') so all those # messy layers we created can be copied from the 'build' # image to the final container image as a single layer. # (I can save 500Mb in image size this way). # Building as a named temporary image lets us in a later stage # of this file 'copy' everything we have done under /home/hercules # in the 'build' image to the final image as a single layer. # ============================================================ # # I will mainly run this on Debian12 and Debian13 servers so # use lowest common base image. # FROM debian:12-slim AS build MAINTAINER Mark # For documentatin you should update the version LABEL version="1.01" LABEL hercules_website="http://www.hercules-390.eu/" LABEL tk3_website="http://bsp-gmbh.com/turnkey/" # Where my mvs3.8j system goes WITHIN THE CONTAINER file structure # >>>> Must be under /home/hercules as that is the user we create <<<<< # IN THE SCRIPTS MATCH THIS ENV HERCULES_DIR /home/hercules/tk4-minus # Set uid to 6001 to keep it well away from existing docker host uids # We need this in the 'build' image so we can chown/chmod things before # they are copied to the final image. RUN useradd hercules -u 6001 -U -c "Used to run the hercules system" # where we generate workfiles on the image filesystem # also the home filesystem when 'docker exec -it /bin/bash' is run WORKDIR /var/tmp # --------- documentation block ---------- # These are the packages required (commands run much later on) # for each distro type. This example file uses Debian:12-slim # in the commands later down so uses the debian packages. # # For rhel/fedora #RUN microdnf -y install coreutils x3270-text screen telnet procps-ng net-tools nmap-ncat which vim-minimal hercules && microdnf clean all # # For Debian # must do the update to get the package list or all packages are not found # "which" is in "debianutils", the "su" command is in util-linux #RUN apt -y update && apt -y install c3270 screen telnet procps net-tools netcat-openbsd vim-tiny util-linux debianutils curl hercules && useradd hercules -u 6001 -U -c "Used to run the hercules system" # --------- end documentation block ---------- RUN mkdir -p $HERCULES_DIR # COPY src-onlocalfilesystem dest-onimagefilesystem # no * after first copy will keep the directory structure # On docker dev machine files are directly under docker build dir # hands-off startup script COPY ./container_scripts/container_start_system.sh $HERCULES_DIR/container_start_system.sh # in a container the initial command must never exit, so we need a wrapper # that runs forever (in a very long sleep loop at the end)... # and does the initial customisations COPY ./container_scripts/container_start_system_wrapper.sh $HERCULES_DIR/container_start_system_wrapper.sh # (2) copy the entire mvs38j directory structure into the container # My mvs38j directory structure is under subdir tk4-minus, copy all to desired container dir # your hercules CONFIG file should be under here somewhere also COPY ./tk4-minus/ $HERCULES_DIR/ # set correct owner and we need them executable RUN chown -R hercules:hercules $HERCULES_DIR RUN chmod 755 $HERCULES_DIR/container_start_system.sh $HERCULES_DIR/container_start_system_wrapper.sh # Copy the healthcheck script in, healthceck entry defined much later on COPY ./container_scripts/container_healthcheck.sh $HERCULES_DIR/container_healthcheck.sh RUN chmod 755 $HERCULES_DIR/container_healthcheck.sh # ============================================================ # The second block --- create the final image we will use # Now we have a final layer (well lots of layers) cached and # mamed 'build' we will create a new image from the debian12 # slim image and copy across from the cached image only the # application under /home/hercules. That will copy the data as a # single layer (saving around 500Mb of stuff that exists in # multiple layers because of all the copy/run steps we used # in creating that build image. # ============================================================ FROM debian:12-slim # environment variables used by the scripts RUN mkdir /etc/hercules_local && chmod 755 /etc/hercules_local COPY ./container_scripts/container_environment.conf /etc/hercules_local/container_environment.conf # packages needed RUN apt -y update && apt -y install c3270 screen telnet procps net-tools netcat-openbsd vim-tiny util-linux debianutils curl hercules && useradd hercules -u 6001 -U -c "Used to run the hercules system" # copy all the stuff from the build image as one layer COPY --from=build /home/hercules /home/hercules # ============================================================ # Notes on how EXPOSE works, really only useful (and confusing) # if the image is run with -P which is a bad idea anyway as you # wil never know what host port is assigned). # Exposed ports for docker start on the host at 32768 upward, so # 3270 is on the host at 32768, 3505 on the host at 32769 etc. # Those are used if the docker run is with -P to map everything exposed; # it is not ideal as you do not really know what is listening where. # It is better to use docker run mapping with lowercase p such # as -p hostip:80:80/tcp or -p 80:80/tcp so you have known host ports # (if a ipv4 hostip: is prefixed then only ipv4 will be used, the default # is docker will start a proxy for both ipv4 and ipv6 doubling the # running process count so if you only need ipv4 use the host ipaddr. # # If EXPOSE is used docker will always start a docker-proxy for the port # even if no -p mapping is used, so lets not use EXPOSE. # What ports I may map are just commented here for documentation. # EXPOSE 3270 TSO # EXPOSE 3505 Socket card reader # Entrypoint is normally used to do setup work before starting the app, # ie: a script to change app passwords etc. # CMD should be used to do the actual start of the container app # cmd can be overwritten with docker run args, entrypoint cannot. # cmd must be a script that never ends, if it ends the container startup # is considered failed, so at the end of the script go into a sleep/loop # but keep running. # cmd can also be used to do lots of customisations # this script was copied into place in earlier steps CMD ["/home/hercules/tk4-minus/container_start_system_wrapper.sh"] # I have no setup needed other than what is in the script run by CMD # so do not use the below # ENTRYPOINT ["/bin/bash"] # Add a healthcheck, check every 5mins (300s) # Note 5min interval is to stop hammering the 3270 port # with http (curl) requests to check it responds, that curl will always # treat the response as invalid data but at least a response to test. # The actual healthcheck script was copied in earlier. HEALTHCHECK --interval=300s --timeout=20s --start-period=120s --retries=3 \ CMD bash /home/hercules/tk4-minus/container_healthcheck.sh # # End of Dockerfile