Skip to content

Instantly share code, notes, and snippets.

@sheldonhull
Created April 29, 2024 21:22
Show Gist options
  • Save sheldonhull/0b6a278a3cb418eafbd0cdcb05f3eef5 to your computer and use it in GitHub Desktop.
Save sheldonhull/0b6a278a3cb418eafbd0cdcb05f3eef5 to your computer and use it in GitHub Desktop.
dagger - using with mkdocs to build a container image that dynamically generates requirements.txt for optimized caching
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"dagger/myteam/internal/dagger"
)
type Myteam struct{}
const (
mkdocsBaseImage = "squidfunk/mkdocs-material"
mkdocsTag = "latest"
)
const (
localRepositoryName = "dev.local"
localImageName = "mkdocs"
localImageTag = "latest"
localRequirementsFile = "requirements.txt"
// daggerInternalMkdocsWorkingDirectory is the working directory for the mkdocs container, internal to the container, not the host.
daggerInternalMkdocsWorkingDirectory = "/docs"
// permissionUserReadWriteExecute is the permissions for the artifact directory.
permissionUserReadWriteExecute = 0o0700
)
var (
qualifiedImageName = mkdocsBaseImage + ":" + mkdocsTag
qualifiedLocalImageName = localRepositoryName + "/" + localImageName + ":" + localImageTag
qualifiedInternalRequirementsFile = filepath.Join(daggerInternalMkdocsWorkingDirectory, localRequirementsFile)
)
// MKDocsBaseImageBuild creates the docker image base container that other actions can be run from.
func (m *Myteam) MKDocsBaseImageBuild(ctx context.Context, dir *Directory) (output string, err error) {
packages := []string{
"mkdocs-glightbox",
"mkdocs-rss-plugin",
"mkdocs-autolinks-plugin",
"mkdocs-git-revision-date-localized-plugin",
"mkdocs-exclude",
"mkdocs-git-authors-plugin",
"mkdocs-swagger-ui-tag",
"mkdocs-glightbox",
"markdown-callouts",
"mkdocs-awesome-pages-plugin",
}
ctr := dag.Container().From(qualifiedImageName).
WithMountedDirectory(daggerInternalMkdocsWorkingDirectory, dir).
WithWorkdir(daggerInternalMkdocsWorkingDirectory).
WithEnvVariable("TINI_SUBREAPER", "true").
WithEnvVariable("PIP_ROOT_USER_ACTION", "ignore")
if _, err := os.Stat(qualifiedInternalRequirementsFile); os.IsNotExist(err) {
fmt.Println("requirements not found, so installing packages from code first exists")
for _, p := range packages {
ctr = ctr.WithExec([]string{"python3", "-m", "pip", "install", p}, dagger.ContainerWithExecOpts{
SkipEntrypoint: true,
})
}
fmt.Println("freezing python packages to requirements file", qualifiedInternalRequirementsFile)
ctr = ctr.WithFocus().WithExec([]string{"python3", "-m", "pip", "freeze"}, dagger.ContainerWithExecOpts{
SkipEntrypoint: true,
RedirectStdout: qualifiedInternalRequirementsFile,
})
} else {
fmt.Println("requirements file exists")
ctr = ctr.WithExec([]string{"python", "-m", "pip", "install", "-r", qualifiedInternalRequirementsFile}, dagger.ContainerWithExecOpts{
SkipEntrypoint: true,
})
}
return ctr.Stdout(ctx)
}
// MKDocsBaseImageBuild creates the docker image base container that other actions can be run from.
func (m *Myteam) MKDocsBaseImageBuildFromDockerfile(ctx context.Context, dir *Directory) *dagger.Container { //(output string, err error) {
// build dagger container from dockerfile
return dag.Container().Build(dir, dagger.ContainerBuildOpts{
Dockerfile: "docker/Dockerfile.mkdocs",
}) // add tags and such and then retrieve later
}
// // Starts mkdoc as a service
// func (m *Myteam) MkdocService(ctx context.Context, directoryArg *Directory) (string, error) {
// return dag.Container().
// From("squidfunk/mkdocs-material:latest").
// WithMountedDirectory("/docs", directoryArg).
// WithWorkdir("/mnt").
// WithExec([]string{"mkdocs", "serve"}).Stdout(ctx)
// }
// starts and returns an HTTP service
func (m *Myteam) MkdocsServe(ctx context.Context, dir *Directory) *Service {
return dag.Container().
From("squidfunk/mkdocs-material:latest").
WithWorkdir("/docs").
WithMountedDirectory("/docs", dir).
WithExec([]string{
"mkdocs",
"serve",
"--clean",
"--dev-addr",
"0.0.0.0:8000",
}, dagger.ContainerWithExecOpts{
SkipEntrypoint: true,
}).
WithExposedPort(8000).
WithEnvVariable("TINI_SUBREAPER", "true").
AsService()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment