feat: add a route to the traefik dashboard
This commit is contained in:
parent
2a761272a0
commit
5e21bf67e8
9 changed files with 106 additions and 22 deletions
|
@ -20,7 +20,6 @@ type DockerConfig struct {
|
|||
}
|
||||
|
||||
// DockerNetworkConfig contains configuration for creating the docker network.
|
||||
|
||||
type DockerNetworkConfig struct {
|
||||
Name string `json:"name"`
|
||||
Subnet string `json:"subnet"`
|
||||
|
@ -41,10 +40,12 @@ type ServicesConfig struct {
|
|||
// TraefikConfig contains configuration for the Traefik container.
|
||||
type TraefikConfig struct {
|
||||
CheckNewVersion bool `json:"checkNewVersion"`
|
||||
ContainerIp string `json:"containerIp"`
|
||||
Domain string `json:"domain"`
|
||||
GroupId int
|
||||
LogLevel string `json:"logLevel"`
|
||||
SendAnonymousUsage bool `json:"sendAnonymousUsage"`
|
||||
Version string `json:"version"`
|
||||
ContainerIp string `json:"containerIp"`
|
||||
LogLevel string `json:"logLevel"`
|
||||
}
|
||||
|
||||
// NewConfig creates a new Config value from a given
|
||||
|
|
|
@ -30,10 +30,11 @@ func TestValidConfig(t *testing.T) {
|
|||
Services: ServicesConfig{
|
||||
Traefik: TraefikConfig{
|
||||
CheckNewVersion: true,
|
||||
ContainerIp: "172.17.1.2",
|
||||
Domain: "forge.localhost",
|
||||
LogLevel: "info",
|
||||
SendAnonymousUsage: false,
|
||||
Version: "v2.4.9",
|
||||
ContainerIp: "172.17.1.2",
|
||||
LogLevel: "info",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
3
internal/config/testdata/config-valid.json
vendored
3
internal/config/testdata/config-valid.json
vendored
|
@ -16,7 +16,8 @@
|
|||
"sendAnonymousUsage": false,
|
||||
"version": "v2.4.9",
|
||||
"containerIp": "172.17.1.2",
|
||||
"logLevel": "info"
|
||||
"logLevel": "info",
|
||||
"domain": "forge.localhost"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,18 +15,27 @@ type DockerContainerInput struct {
|
|||
EnvVars pulumi.StringArray
|
||||
Name pulumi.StringInput
|
||||
Network pulumi.StringInput
|
||||
Volumes []DockerVolumeMount
|
||||
HostPathVolumes []HostPathVolume
|
||||
DockerVolumes []DockerVolume
|
||||
UniqueLabel string
|
||||
}
|
||||
|
||||
// DockerVolumeMount is the configuration
|
||||
// HostPathVolume is the configuration
|
||||
// used for mounting a host directory
|
||||
// to a directory inside a container.
|
||||
type DockerVolumeMount struct {
|
||||
type HostPathVolume struct {
|
||||
HostPath pulumi.StringInput
|
||||
MountPath pulumi.StringInput
|
||||
}
|
||||
|
||||
// DockerVolume is the configuration
|
||||
// used for mounting a docker volume
|
||||
// to a directory inside a container.
|
||||
type DockerVolume struct {
|
||||
Name pulumi.StringInput
|
||||
MountPath pulumi.StringInput
|
||||
}
|
||||
|
||||
func CreateContainer(ctx *pulumi.Context, c DockerContainerInput) error {
|
||||
// all containers will mount the host's timezone and localtime files
|
||||
// to ensure the correct time is synced.
|
||||
|
@ -43,13 +52,21 @@ func CreateContainer(ctx *pulumi.Context, c DockerContainerInput) error {
|
|||
},
|
||||
}
|
||||
|
||||
// optionally create additional container volumes.
|
||||
for _, v := range c.Volumes {
|
||||
vArg := docker.ContainerVolumeArgs{
|
||||
// create additional container volumes if specified.
|
||||
for _, v := range c.HostPathVolumes {
|
||||
arg := docker.ContainerVolumeArgs{
|
||||
ContainerPath: v.MountPath,
|
||||
HostPath: v.HostPath,
|
||||
}
|
||||
volumes = append(volumes, vArg)
|
||||
volumes = append(volumes, arg)
|
||||
}
|
||||
|
||||
for _, v := range c.DockerVolumes {
|
||||
arg := docker.ContainerVolumeArgs{
|
||||
ContainerPath: v.MountPath,
|
||||
VolumeName: v.Name,
|
||||
}
|
||||
volumes = append(volumes, arg)
|
||||
}
|
||||
|
||||
args := docker.ContainerArgs{
|
||||
|
|
|
@ -29,6 +29,12 @@ var templateTraefikDockerfile string
|
|||
//go:embed templates/traefik/traefik.yaml.tmpl
|
||||
var templateTraefikStaticConfig string
|
||||
|
||||
//go:embed templates/traefik/dynamic_dashboard.yaml.tmpl
|
||||
var templateTraefikDynamicDashboardConfig string
|
||||
|
||||
//go:embed templates/traefik/entrypoint.sh.tmpl
|
||||
var templateTraefikEntrypoint string
|
||||
|
||||
// newContainerStack creates the ContainerStack value.
|
||||
func newDockerStack(ctx context.Context, project, stack string, c config.Config) (*DockerStack, error) {
|
||||
deployFunc := deployDockerStack(project, c.Docker, c.Services)
|
||||
|
@ -79,6 +85,9 @@ func (c *DockerStack) Destroy(ctx context.Context) error {
|
|||
// deployDockerStack returns a Pulumi run function
|
||||
// that is used to deploy the docker stack.
|
||||
func deployDockerStack(project string, dockerConfig config.DockerConfig, services config.ServicesConfig) pulumi.RunFunc {
|
||||
groupID := 2239
|
||||
services.Traefik.GroupId = groupID
|
||||
|
||||
return func(ctx *pulumi.Context) error {
|
||||
// TODO: Create the provider when we start playing with remote hosts
|
||||
|
||||
|
@ -100,7 +109,7 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
|
|||
UniqueLabel: "shared",
|
||||
}
|
||||
|
||||
_, err = docker.CreateVolume(ctx, sharedVolumeInput)
|
||||
sharedVolume, err := docker.CreateVolume(ctx, sharedVolumeInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -125,6 +134,14 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
|
|||
return fmt.Errorf("unable to generate the Traefik static configuration from template...\n%w", err)
|
||||
}
|
||||
|
||||
if err := generateFile(services.Traefik, templateTraefikDynamicDashboardConfig, "traefikDashboardConf", filepath.Join(traefikContextDir, "dynamic_dashboard.yaml")); err != nil {
|
||||
return fmt.Errorf("unable to generate the Traefik dashboard configuration from template...\n%w", err)
|
||||
}
|
||||
|
||||
if err := generateFile(services.Traefik, templateTraefikEntrypoint, "traefikEntrypoint", filepath.Join(traefikContextDir, "entrypoint.sh")); err != nil {
|
||||
return fmt.Errorf("unable to generate the Traefik entrypoint script from template...\n%w", err)
|
||||
}
|
||||
|
||||
c := docker.DockerImageInput{
|
||||
BuildContext: pulumi.String(traefikContextDir),
|
||||
Dockerfile: pulumi.String(filepath.Join(traefikContextDir, "Dockerfile")),
|
||||
|
@ -144,6 +161,12 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
|
|||
Name: pulumi.String("helix-traefik"),
|
||||
Network: network.Name,
|
||||
UniqueLabel: "traefik-container",
|
||||
DockerVolumes: []docker.DockerVolume{
|
||||
{
|
||||
Name: sharedVolume.Name,
|
||||
MountPath: pulumi.String("/helix/shared"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err = docker.CreateContainer(ctx, traefikContainerInput); err != nil {
|
||||
|
|
|
@ -2,6 +2,12 @@ FROM traefik:{{ .Version }}
|
|||
|
||||
ADD traefik.yml /helix/traefik/
|
||||
|
||||
ADD entrypoint.sh /
|
||||
|
||||
ADD dynamic_dashboard.yaml /tmp/
|
||||
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 22 80 443
|
||||
|
||||
CMD ["--configfile=/helix/traefik/traefik.yml"]
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
http:
|
||||
routers:
|
||||
dashboard:
|
||||
entryPoints:
|
||||
- "https"
|
||||
rule: "Host(`{{ .Domain }}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
|
||||
service: "api@internal"
|
||||
tls: {}
|
26
internal/stacks/templates/traefik/entrypoint.sh.tmpl
Normal file
26
internal/stacks/templates/traefik/entrypoint.sh.tmpl
Normal file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Create the dynamic config directory in the shared volume.
|
||||
mkdir -p /helix/shared/traefik/dynamic
|
||||
chgrp {{ .GroupId }} /helix/shared/traefik/dynamic
|
||||
chmod a-rwx,u+rwx,g+rwx /helix/shared/traefik/dynamic
|
||||
|
||||
# Move the dashboard config to the new directory.
|
||||
mv /tmp/dynamic_dashboard.yaml /helix/shared/traefik/dynamic/dashboard.yaml
|
||||
|
||||
# first arg is `-f` or `--some-option`
|
||||
if [ "${1#-}" != "$1" ]; then
|
||||
set -- traefik "$@"
|
||||
fi
|
||||
|
||||
# if our command is a valid Traefik subcommand, let's invoke it through Traefik instead
|
||||
# (this allows for "docker run traefik version", etc)
|
||||
if traefik "$1" --help >/dev/null 2>&1
|
||||
then
|
||||
set -- traefik "$@"
|
||||
else
|
||||
echo "= '$1' is not a Traefik command: assuming shell execution." 1>&2
|
||||
fi
|
||||
|
||||
exec "$@"
|
|
@ -22,6 +22,6 @@ entryPoints:
|
|||
providers:
|
||||
file:
|
||||
watch: true
|
||||
directory: "/helix/traefik/config/dynamic"
|
||||
directory: "/helix/shared/traefik/dynamic"
|
||||
log:
|
||||
level: "{{ .LogLevel }}"
|
||||
|
|
Reference in a new issue