rhel85: use nginx with custom config for container

Running the container on Openshift requires that the process inside the
container run without special permissions.
Switching to nginx and setting the following options that don't require
root privileges:
- Port 8080 (> 1024)
- pid file in '/tmp' instead of the default '/run' path

Also, the log file is chmod-ed to be world writable. Nginx always writes
to the default log file on startup, even if a different log file path is
specified in the configuration.

See rhbz#1945238

Signed-off-by: Achilleas Koutsou <achilleas@koutsou.net>
This commit is contained in:
Achilleas Koutsou 2021-07-27 13:26:46 +02:00 committed by Tom Gundersen
parent a717a7245b
commit ca56714aa4
3 changed files with 46 additions and 10 deletions

View file

@ -574,13 +574,13 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
packageSets: map[string]rpmmd.PackageSet{
buildPkgsKey: edgeBuildPackageSet(),
osPkgsKey: edgeCommitPackageSet(),
containerPkgsKey: {Include: []string{"httpd"}},
containerPkgsKey: {Include: []string{"nginx"}},
},
enabledServices: edgeServices,
rpmOstree: true,
bootISO: false,
pipelines: edgeContainerPipelines,
exports: []string{containerPkgsKey},
exports: []string{"container"},
}
edgeInstallerImgType := imageType{
name: "edge-installer",

View file

@ -3,6 +3,7 @@ package rhel85
import (
"fmt"
"math/rand"
"path/filepath"
"strings"
"github.com/osbuild/osbuild-composer/internal/blueprint"
@ -559,8 +560,11 @@ func edgeContainerPipelines(t *imageType, customizations *blueprint.Customizatio
if err != nil {
return nil, err
}
pipelines = append(pipelines, *containerTreePipeline(repos, packageSetSpecs[containerPkgsKey], options, customizations))
pipelines = append(pipelines, *containerPipeline(t))
nginxConfigPath := "/etc/nginx.conf"
httpPort := "8080"
pipelines = append(pipelines, *containerTreePipeline(repos, packageSetSpecs[containerPkgsKey], options, customizations, nginxConfigPath, httpPort))
pipelines = append(pipelines, *containerPipeline(t, nginxConfigPath, httpPort))
return pipelines, nil
}
@ -772,7 +776,7 @@ func tarStage(source, filename string) *osbuild.Stage {
return osbuild.NewTarStage(&osbuild.TarStageOptions{Filename: filename}, &osbuild.TarStageInputs{Tree: tree})
}
func containerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, options distro.ImageOptions, c *blueprint.Customizations) *osbuild.Pipeline {
func containerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, options distro.ImageOptions, c *blueprint.Customizations, nginxConfigPath, listenPort string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "container-tree"
p.Build = "name:build"
@ -783,16 +787,25 @@ func containerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpe
} else {
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US"}))
}
p.AddStage(osbuild.NewOSTreeInitStage(&osbuild.OSTreeInitStageOptions{Path: "/var/www/html/repo"}))
htmlRoot := "/usr/share/nginx/html"
repoPath := filepath.Join(htmlRoot, "repo")
p.AddStage(osbuild.NewOSTreeInitStage(&osbuild.OSTreeInitStageOptions{Path: repoPath}))
p.AddStage(osbuild.NewOSTreePullStage(
&osbuild.OSTreePullStageOptions{Repo: "/var/www/html/repo"},
&osbuild.OSTreePullStageOptions{Repo: repoPath},
ostreePullStageInputs("org.osbuild.pipeline", "name:ostree-commit", options.OSTree.Ref),
))
// make nginx log directory world writeable, otherwise nginx can't start in
// an unprivileged container
p.AddStage(osbuild.NewChmodStage(chmodStageOptions("/var/log/nginx", "o+w", true)))
p.AddStage(osbuild.NewNginxConfigStage(nginxConfigStageOptions(nginxConfigPath, htmlRoot, listenPort)))
return p
}
func containerPipeline(t *imageType) *osbuild.Pipeline {
func containerPipeline(t *imageType, nginxConfigPath, listenPort string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "container"
p.Build = "name:build"
@ -800,8 +813,8 @@ func containerPipeline(t *imageType) *osbuild.Pipeline {
Architecture: t.arch.Name(),
Filename: t.Filename(),
Config: &osbuild.OCIArchiveConfig{
Cmd: []string{"httpd", "-D", "FOREGROUND"},
ExposedPorts: []string{"80"},
Cmd: []string{"nginx", "-c", nginxConfigPath},
ExposedPorts: []string{listenPort},
},
}
baseInput := new(osbuild.OCIArchiveStageInput)

View file

@ -8,6 +8,7 @@ import (
"github.com/google/uuid"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/disk"
osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2"
@ -515,3 +516,25 @@ func kernelCmdlineStageOptions(rootUUID string, kernelOptions string) *osbuild.K
KernelOpts: kernelOptions,
}
}
func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild.NginxConfigStageOptions {
// configure nginx to work in an unprivileged container
cfg := &osbuild.NginxConfig{
Listen: listen,
Root: htmlRoot,
Daemon: common.BoolToPtr(false),
PID: "/tmp/nginx.pid",
}
return &osbuild.NginxConfigStageOptions{
Path: path,
Config: cfg,
}
}
func chmodStageOptions(path, mode string, recursive bool) *osbuild.ChmodStageOptions {
return &osbuild.ChmodStageOptions{
Items: map[string]osbuild.ChmodStagePathOptions{
path: {Mode: mode, Recursive: recursive},
},
}
}