Initial import for my docker images

FossilOrigin-Name: b20f814ed3306d0ba6c1aae98fbeb11cab4e783e53c60d25bc8dba56676532c7
This commit is contained in:
mat.kovach@everops.com 2023-04-05 15:24:56 +00:00
commit b9c3d2bb4d
3 changed files with 308 additions and 0 deletions

13
Makefile Normal file
View File

@ -0,0 +1,13 @@
TANGLE=tclsh scripts/tangle.tcl
DOCKERFILES=ubi9+epel.dockerfile
.SUFFIXES: .md .dockerfile
.md.dockerfile:
$(TANGLE) -R $@ $< > $@
.PHONY: default
default: all
.PHONY: all
all: $(DOCKERFILES)

135
scripts/tangle.tcl Executable file
View File

@ -0,0 +1,135 @@
#!/usr/bin/env tclsh
#
# A simple noweave, based on noweb, that allows us to do simple literate
# programming.
#
# procedures
#
proc with-open-file {fname mode fp block} {
upvar 1 $fp fpvar
set binarymode 0
if {[string equal [string index $mode end] b]} {
set mode [string range $mode 0 end-1]
set binarymode 1
}
set fpvar [open $fname $mode]
if {$binarymode} {
fconfigure $fpvar -translation binary
}
uplevel 1 $block
close $fpvar
}
proc add-array-value { _arr key value } {
upvar 1 $_arr arr
if {[info exists arr($key)]} {
append arr($key) "\n$value"
} else {
array set arr [list $key $value]
}
}
proc expand-chunks {_arr chunk indent} {
upvar 1 $_arr arr
if {![info exists arr($chunk)]} {
puts stderr "Could not find chunk $chunk"
puts stderr "chunks found"
foreach key [array names arr] {
puts stderr $key
}
exit 1
}
foreach line [split $arr($chunk) "\n"] {
if {[regexp {^(\s*)(<<)(.*)(>>)\s*$} $line -> newIndent open newChunk close]} {
expand-chunks arr $newChunk $newIndent
} else {
puts -nonewline "$indent"
puts "$line"
}
}
}
proc Usage {} {
global argv0
puts stderr "$argv0 -R <chunk_name> filename"
exit 1
}
#
# variables
#
array set chunks {}
unset -nocomplain requestedChunk
#
# get the chuck and the filename
#
while {[llength $argv]} {
set argv [lassign $argv[set argv {}] flag]
switch -glob $flag {
-R {
set argv [lassign $argv[set argv {}] requestedChunk]
}
-h - --help - -\? {
Usage
}
-- break
-* {
puts stderr "unknown option $flag"
Usage
}
default {
set argv [list $flag {*}$argv]
break
}
}
}
#
# make sure we got a file name
#
if {[llength $argv] != 1} {
puts stderr "no file given, exiting"
Usage
}
#
# make sure we got a chunk
#
set filename $argv
if {![info exists requestedChunk]} {
## puts stderr "no chunk requested, default to the root chunk '*'"
set requestedChunk "*"
}
#
# read the file and get all chunks
#
with-open-file $filename r fp {
set in_chunk_p 0
unset -nocomplain chunk
while 1 {
gets $fp line
if [eof $fp] break
if {!$in_chunk_p && [regexp {(^<<)(.*)(>>=$)} $line -> open chunk close]} {
set in_chunk_p 1
continue
}
if {$in_chunk_p && [regexp {^(@).*(% def)?$} $line -> endchunk rest]} {
set in_chunk_p 0
unset -nocomplain chunk
continue
}
if {$in_chunk_p} {
add-array-value chunks $chunk $line
}
}
}
#
# Print out the requested chunk
#
expand-chunks chunks $requestedChunk ""
exit 0

160
ubi9+epel.md Normal file
View File

@ -0,0 +1,160 @@
# A simple base docker image for RH's UBI9 Docker Image
Redhat has recently made their Universal Base Image (UBI) availabe
on the Docker Registery (docker.io/libarary/redhat/ubi9).
Of course, it doesn't have the ELPL repository enabled on it, which is
something I use consistently with the RHel based images.
There are a few other things I liked to do with my docker images to help
make development and usage a bit more standardized.
## Standard Docker Stuff
I like to insure that my containers follow a few simple rules.
* Never run as root.
* For containers, I liked to have a single user I run in.
* Needed software and configuration that requires root should be done first.
* At the end, the container should default to be running as that user.
* A set working directory that can be a docker volume or a volume passed from the host.
* This present a challenge in make sure that that uid/gid is correct between the active user and the directory.
* When using a host volume, I also have to make sure the UID/GID matches to not have any permission issues.
* While we also like to use the latest version of a base docker image, that isn't always possible.
* We should default to building the latest version, but allow for changing that.
## UBI9+EPEL Docker Image
### Setup FROM and enable a version choice.
First let's set the where we'll pull from. I use `podman` and `docker` equally, so on I give the full path to the FROM image.
An `ARG` for the version, `VER` is there. This can be overridden with `--build-arg 'VER=<version>'`.
```
<<base.image>>=
ARG VER=latest
FROM docker.io/redhat/ubi9:${VER}
@
```
### Setup user specific arguments.
Setup a base username, uid, gid, and work directory with some defaults. All of these can be overridden with `-build-arg "ARG=VALUE"`.
```
<<base.userargs>>=
ARG baseUSER="mat.kovach"
ARG baseUID=5000
ARG baseGID=5000
ARG baseDIR="/work"
@
```
### Add user and work directory
You'll need to be careful here to not change a current directory. For example, do not set baseDIR="/bin".
Add the group, user, (with the home directory of the user ad the work directory) and insure the proper ownership on the work directory.
```
<<base.setupuser>>=
RUN groupadd -g ${baseGID} ${baseUSER} && \
useradd -c 'work user' -m -u ${baseUID} \
-g ${baseGID} -d ${baseDIR} ${baseUSER} && \
chown -R ${baseUID}:${baseGID} ${baseDIR}
@
```
### Add repos and update software.
First, we'll add the EPEL repo. If you have additional repos you want to
enable, add them here.
```
<<base.enablerepos>>=
RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \
/usr/bin/crb enable && \
dnf update -y
@
```
### Addtional root changes
We are still root at this point, this is where we add software, make
additional changes, etc.
```
<<base.addsoftware>>=
RUN dnf install -y ed joe tcl tcllib
@
```
The different sections are setup based on how often they may be changed.
The more likely some will change, the further down they should be to help
minimize the layers that need to be rebuilt.
### Make sure we the user, volume, and workdir setup
```
<<base.end>>=
USER ${baseUSER}
VOLUME ${baseDIR}
WORKDIR ${baseDIR}
# you can add entry point, etc. here.
@
```
### Pulling it all together
```
<<ubi9+epel.dockerfile>>=
<<base.image>>
<<base.userargs>>
<<base.setupuser>>
<<base.enablerepos>>
<<base.addsoftware>>
<<base.end>>
@
```
## build and test
`docker build -t mek:ubi9 -f ubi9-epel.dockerfile .`
`docker run --rm -it mek:ubi9 /bin/bash`
```
$ docker run --rm -it mek:ubi9 /bin/bash
[mat.kovach@4bd996f669b2 ~]$ pwd
/work
[mat.kovach@4bd996f669b2 ~]$ id -a
uid=5000(mat.kovach) gid=5000(mat.kovach) groups=5000(mat.kovach)
$ dnf repolist
Not root, Subscription Management repositories not updated
This system is not registered with an entitlement server. You can use subscription-manager to register.
repo id repo name
epel Extra Packages for Enterprise Linux 9 - x86_64
ubi-9-appstream-rpms Red Hat Universal Base Image 9 (RPMs) - AppStream
ubi-9-baseos-rpms Red Hat Universal Base Image 9 (RPMs) - BaseOS
ubi-9-codeready-builder Red Hat Universal Base Image 9 (RPMs) - CodeReady Builder
```
Now let's try using my current working directory inside the container.
```
$ docker run --rm -it -v $(PWD):/work mek:ubi9 /bin/bash
bash-5.1$ pwd
/work
bash-5.1$ ls -l *.md
-rw-r--r-- 1 mat.kovach mat.kovach 3474 Apr 5 14:57 UBI9-DOCKER.md
bash-5.1$ touch test
bash-5.1$ exit
exit
Mats-MBP:docker mek$ ls -l test
-rw-r--r--@ 1 mek staff 0 Apr 5 11:06 test
```