detached 0993a06

Refactor: Enhance security and improve Traefik integration

- Remove exposed ports for improved security
- Add Traefik configuration fields to initconfig.go
- Update CreateTraefikLabels to use only loadbalancer port
- Refactor deployment process to support new port handling
- Simplify port validation in deploy.go and push.go
- Update DeployPayload struct to use 'Port' instead of 'Ports'
- Fix build scripts for dev multi-arch support
- Enhance error handling
commit
0993a06e5043c2be53cbec59db3198dcf0beceef
author
bamen · · 2024-09-02 03:21 UTC
parent
a308320
signature
unsigned
11 files · +78 -35
M build-dev.sh +2 -0
@@ -16,3 +16,5 @@ rm -f $DIST_DIR/*
1616 echo "Building Go binaries..."
1717 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $DIST_DIR/gordon-linux-amd64 ./cmd/cli
1818 CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o $DIST_DIR/gordon-linux-arm64 ./cmd/cli
19+
20+echo "Successfully built Go binaries"
@@ -16,3 +16,5 @@ rm -f $DIST_DIR/*
16 echo "Building Go binaries..."16 echo "Building Go binaries..."
17 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $DIST_DIR/gordon-linux-amd64 ./cmd/cli17 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $DIST_DIR/gordon-linux-amd64 ./cmd/cli
18 CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o $DIST_DIR/gordon-linux-arm64 ./cmd/cli18 CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o $DIST_DIR/gordon-linux-arm64 ./cmd/cli
19+
20+echo "Successfully built Go binaries"
M buildpush-dev.sh +11 -3
@@ -29,13 +29,21 @@ $ENGINE image prune -f
2929
3030 # Build Docker images for each architecture
3131 echo "Building Docker images..."
32-$ENGINE build -t $REPO:${TAG}-amd64 --build-arg ARCH=amd64 -f Dockerfile .
33-$ENGINE build -t $REPO:${TAG}-arm64v8 --build-arg ARCH=arm64 -f Dockerfile .
32+for ARCH in amd64 arm64; do
33+ # Copy the appropriate binary to the root directory and rename it to 'gordon'
34+ cp $DIST_DIR/gordon-linux-$ARCH gordon
35+
36+ # Build the Docker image
37+ $ENGINE build -t $REPO:${TAG}-$ARCH .
38+
39+ # Remove the temporary 'gordon' file
40+ rm gordon
41+done
3442
3543 # Push images
3644 echo "Pushing Docker images..."
3745 $ENGINE push $REPO:${TAG}-amd64
38-$ENGINE push $REPO:${TAG}-arm64v8
46+$ENGINE push $REPO:${TAG}-arm64
3947
4048 # Remove existing manifest if it exists
4149 echo "Removing existing manifest..."
@@ -29,13 +29,21 @@ $ENGINE image prune -f
29 29
30 # Build Docker images for each architecture30 # Build Docker images for each architecture
31 echo "Building Docker images..."31 echo "Building Docker images..."
32-$ENGINE build -t $REPO:${TAG}-amd64 --build-arg ARCH=amd64 -f Dockerfile .32+for ARCH in amd64 arm64; do
33-$ENGINE build -t $REPO:${TAG}-arm64v8 --build-arg ARCH=arm64 -f Dockerfile .33+ # Copy the appropriate binary to the root directory and rename it to 'gordon'
34+ cp $DIST_DIR/gordon-linux-$ARCH gordon
35+
36+ # Build the Docker image
37+ $ENGINE build -t $REPO:${TAG}-$ARCH .
38+
39+ # Remove the temporary 'gordon' file
40+ rm gordon
41+done
34 42
35 # Push images43 # Push images
36 echo "Pushing Docker images..."44 echo "Pushing Docker images..."
37 $ENGINE push $REPO:${TAG}-amd6445 $ENGINE push $REPO:${TAG}-amd64
38-$ENGINE push $REPO:${TAG}-arm64v846+$ENGINE push $REPO:${TAG}-arm64
39 47
40 # Remove existing manifest if it exists48 # Remove existing manifest if it exists
41 echo "Removing existing manifest..."49 echo "Removing existing manifest..."
M internal/cli/cmd/deploy.go +6 -3
@@ -77,10 +77,13 @@ func validateInputs(imageName, port, targetDomain string) error {
7777 if err := handler.ValidateImageName(imageName); err != nil {
7878 return err
7979 }
80+
8081 handler.EnsureImageTag(&imageName)
81- if err := handler.ValidatePortMapping(port); err != nil {
82- return err
82+
83+ if port == "" {
84+ return fmt.Errorf("port is required")
8385 }
86+
8487 return handler.ValidateTargetDomain(targetDomain)
8588 }
8689
@@ -117,7 +120,7 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str
117120 reqPayload := common.RequestPayload{
118121 Type: "deploy",
119122 Payload: common.DeployPayload{
120- Ports: port,
123+ Port: port,
121124 TargetDomain: targetDomain,
122125 ImageName: imageName,
123126 Data: io.NopCloser(reader),
@@ -77,10 +77,13 @@ func validateInputs(imageName, port, targetDomain string) error {
77 if err := handler.ValidateImageName(imageName); err != nil {77 if err := handler.ValidateImageName(imageName); err != nil {
78 return err78 return err
79 }79 }
80+
80 handler.EnsureImageTag(&imageName)81 handler.EnsureImageTag(&imageName)
81- if err := handler.ValidatePortMapping(port); err != nil {82+
82- return err83+ if port == "" {
84+ return fmt.Errorf("port is required")
83 }85 }
86+
84 return handler.ValidateTargetDomain(targetDomain)87 return handler.ValidateTargetDomain(targetDomain)
85 }88 }
86 89
@@ -117,7 +120,7 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str
117 reqPayload := common.RequestPayload{120 reqPayload := common.RequestPayload{
118 Type: "deploy",121 Type: "deploy",
119 Payload: common.DeployPayload{122 Payload: common.DeployPayload{
120- Ports: port,123+ Port: port,
121 TargetDomain: targetDomain,124 TargetDomain: targetDomain,
122 ImageName: imageName,125 ImageName: imageName,
123 Data: io.NopCloser(reader),126 Data: io.NopCloser(reader),
M internal/cli/cmd/push.go +2 -8
@@ -29,7 +29,7 @@ func NewPushCommand(a *cli.App) *cobra.Command {
2929 imageName := args[0]
3030 log.Info("Pushing image", "image", imageName)
3131
32- if err := pushImage(a, imageName, port); err != nil {
32+ if err := pushImage(a, imageName); err != nil {
3333 log.Error("Push failed", "error", err)
3434 os.Exit(1)
3535 }
@@ -41,19 +41,13 @@ func NewPushCommand(a *cli.App) *cobra.Command {
4141 return pushCmd
4242 }
4343
44-func pushImage(a *cli.App, imageName, port string) error {
44+func pushImage(a *cli.App, imageName string) error {
4545 if err := handler.ValidateImageName(imageName); err != nil {
4646 return fmt.Errorf("invalid image name: %w", err)
4747 }
4848
4949 handler.EnsureImageTag(&imageName)
5050
51- if port != "" {
52- if err := handler.ValidatePortMapping(port); err != nil {
53- return fmt.Errorf("invalid port mapping: %w", err)
54- }
55- }
56-
5751 reader, actualSize, err := exportDockerImage(imageName)
5852 if err != nil {
5953 return fmt.Errorf("error exporting image: %w", err)
@@ -29,7 +29,7 @@ func NewPushCommand(a *cli.App) *cobra.Command {
29 imageName := args[0]29 imageName := args[0]
30 log.Info("Pushing image", "image", imageName)30 log.Info("Pushing image", "image", imageName)
31 31
32- if err := pushImage(a, imageName, port); err != nil {32+ if err := pushImage(a, imageName); err != nil {
33 log.Error("Push failed", "error", err)33 log.Error("Push failed", "error", err)
34 os.Exit(1)34 os.Exit(1)
35 }35 }
@@ -41,19 +41,13 @@ func NewPushCommand(a *cli.App) *cobra.Command {
41 return pushCmd41 return pushCmd
42 }42 }
43 43
44-func pushImage(a *cli.App, imageName, port string) error {44+func pushImage(a *cli.App, imageName string) error {
45 if err := handler.ValidateImageName(imageName); err != nil {45 if err := handler.ValidateImageName(imageName); err != nil {
46 return fmt.Errorf("invalid image name: %w", err)46 return fmt.Errorf("invalid image name: %w", err)
47 }47 }
48 48
49 handler.EnsureImageTag(&imageName)49 handler.EnsureImageTag(&imageName)
50 50
51- if port != "" {
52- if err := handler.ValidatePortMapping(port); err != nil {
53- return fmt.Errorf("invalid port mapping: %w", err)
54- }
55- }
56-
57 reader, actualSize, err := exportDockerImage(imageName)51 reader, actualSize, err := exportDockerImage(imageName)
58 if err != nil {52 if err != nil {
59 return fmt.Errorf("error exporting image: %w", err)53 return fmt.Errorf("error exporting image: %w", err)
M internal/cli/handler/http.go +1 -1
@@ -62,7 +62,7 @@ func SendHTTPRequest(a *cli.App, rp *common.RequestPayload, method string, endpo
6262
6363 setAuthRequestHeaders(req, token)
6464 req.Header.Set("Content-Type", "application/octet-stream")
65- req.Header.Set("X-Ports", deployPayload.Ports)
65+ req.Header.Set("X-Ports", deployPayload.Port)
6666 req.Header.Set("X-Target-Domain", deployPayload.TargetDomain)
6767 req.Header.Set("X-Image-Name", deployPayload.ImageName)
6868
@@ -62,7 +62,7 @@ func SendHTTPRequest(a *cli.App, rp *common.RequestPayload, method string, endpo
62 62
63 setAuthRequestHeaders(req, token)63 setAuthRequestHeaders(req, token)
64 req.Header.Set("Content-Type", "application/octet-stream")64 req.Header.Set("Content-Type", "application/octet-stream")
65- req.Header.Set("X-Ports", deployPayload.Ports)65+ req.Header.Set("X-Ports", deployPayload.Port)
66 req.Header.Set("X-Target-Domain", deployPayload.TargetDomain)66 req.Header.Set("X-Target-Domain", deployPayload.TargetDomain)
67 req.Header.Set("X-Image-Name", deployPayload.ImageName)67 req.Header.Set("X-Image-Name", deployPayload.ImageName)
68 68
M internal/common/initconfig.go +17 -2
@@ -17,6 +17,7 @@ type Config struct {
1717 Http HttpConfig `yaml:"Http"`
1818 Admin AdminConfig `yaml:"Admin"`
1919 ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"`
20+ Traefik TraefikConfig `yaml:"Traefik"`
2021 Build BuildConfig `yaml:"-"`
2122 }
2223
@@ -51,10 +52,19 @@ type ContainerEngineConfig struct {
5152 Network string `yaml:"network"`
5253 }
5354
55+type TraefikConfig struct {
56+ EntryPoint string `yaml:"entryPoint"`
57+ SecureEntryPoint string `yaml:"secureEntryPoint"`
58+ Resolver string `yaml:"resolver"`
59+}
60+
5461 // Default values
5562 var (
56- sock = "/var/run/docker.sock"
57- podmansock = "/run/user/1000/podman/podman.sock"
63+ sock = "/var/run/docker.sock"
64+ podmansock = "/run/user/1000/podman/podman.sock"
65+ entryPoint = "web"
66+ entryPointSecure = "websecure"
67+ resolver = "myresolver"
5868 )
5969
6070 func getConfigDir() (string, error) {
@@ -111,6 +121,11 @@ func (config *Config) LoadConfig() (*Config, error) {
111121 PodmanSock: podmansock,
112122 Podman: ReadUserInput("Are you using podman ? (y/n)") == "y",
113123 },
124+ Traefik: TraefikConfig{
125+ EntryPoint: entryPoint,
126+ SecureEntryPoint: entryPointSecure,
127+ Resolver: resolver,
128+ },
114129 }
115130
116131 err = config.SaveConfig()
@@ -17,6 +17,7 @@ type Config struct {
17 Http HttpConfig `yaml:"Http"`17 Http HttpConfig `yaml:"Http"`
18 Admin AdminConfig `yaml:"Admin"`18 Admin AdminConfig `yaml:"Admin"`
19 ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"`19 ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"`
20+ Traefik TraefikConfig `yaml:"Traefik"`
20 Build BuildConfig `yaml:"-"`21 Build BuildConfig `yaml:"-"`
21 }22 }
22 23
@@ -51,10 +52,19 @@ type ContainerEngineConfig struct {
51 Network string `yaml:"network"`52 Network string `yaml:"network"`
52 }53 }
53 54
55+type TraefikConfig struct {
56+ EntryPoint string `yaml:"entryPoint"`
57+ SecureEntryPoint string `yaml:"secureEntryPoint"`
58+ Resolver string `yaml:"resolver"`
59+}
60+
54 // Default values61 // Default values
55 var (62 var (
56- sock = "/var/run/docker.sock"63+ sock = "/var/run/docker.sock"
57- podmansock = "/run/user/1000/podman/podman.sock"64+ podmansock = "/run/user/1000/podman/podman.sock"
65+ entryPoint = "web"
66+ entryPointSecure = "websecure"
67+ resolver = "myresolver"
58 )68 )
59 69
60 func getConfigDir() (string, error) {70 func getConfigDir() (string, error) {
@@ -111,6 +121,11 @@ func (config *Config) LoadConfig() (*Config, error) {
111 PodmanSock: podmansock,121 PodmanSock: podmansock,
112 Podman: ReadUserInput("Are you using podman ? (y/n)") == "y",122 Podman: ReadUserInput("Are you using podman ? (y/n)") == "y",
113 },123 },
124+ Traefik: TraefikConfig{
125+ EntryPoint: entryPoint,
126+ SecureEntryPoint: entryPointSecure,
127+ Resolver: resolver,
128+ },
114 }129 }
115 130
116 err = config.SaveConfig()131 err = config.SaveConfig()
M internal/common/payload.go +1 -1
@@ -38,7 +38,7 @@ func (e *DeploymentError) Error() string {
3838 }
3939
4040 type DeployPayload struct {
41- Ports string `json:"ports"`
41+ Port string `json:"port"`
4242 TargetDomain string `json:"targetdomain"`
4343 ImageName string `json:"imagename"`
4444 ImageID string `json:"imageid"`
@@ -38,7 +38,7 @@ func (e *DeploymentError) Error() string {
38 }38 }
39 39
40 type DeployPayload struct {40 type DeployPayload struct {
41- Ports string `json:"ports"`41+ Port string `json:"port"`
42 TargetDomain string `json:"targetdomain"`42 TargetDomain string `json:"targetdomain"`
43 ImageName string `json:"imagename"`43 ImageName string `json:"imagename"`
44 ImageID string `json:"imageid"`44 ImageID string `json:"imageid"`
M internal/httpserve/handler/cli-endpoints.go +3 -3
@@ -130,7 +130,7 @@ func PostPush(c echo.Context, a *server.App) error {
130130 func PostDeploy(c echo.Context, a *server.App) error {
131131 // Initialize pushPayload object
132132 payload := &common.DeployPayload{
133- Ports: c.Request().Header.Get("X-Ports"),
133+ Port: c.Request().Header.Get("X-Ports"),
134134 ImageName: c.Request().Header.Get("X-Image-Name"),
135135 TargetDomain: c.Request().Header.Get("X-Target-Domain"),
136136 }
@@ -149,8 +149,8 @@ func PostDeploy(c echo.Context, a *server.App) error {
149149 imageFileName = imageFileName + ".tar"
150150
151151 // Check the ports struct, if there is no /tcp, or /udp, add /tcp
152- if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Ports) {
153- payload.Ports = payload.Ports + "/tcp"
152+ if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Port) {
153+ payload.Port = payload.Port + "/tcp"
154154 }
155155
156156 // Check the target domain, if there is no https:// or http://, add https://
@@ -130,7 +130,7 @@ func PostPush(c echo.Context, a *server.App) error {
130 func PostDeploy(c echo.Context, a *server.App) error {130 func PostDeploy(c echo.Context, a *server.App) error {
131 // Initialize pushPayload object131 // Initialize pushPayload object
132 payload := &common.DeployPayload{132 payload := &common.DeployPayload{
133- Ports: c.Request().Header.Get("X-Ports"),133+ Port: c.Request().Header.Get("X-Ports"),
134 ImageName: c.Request().Header.Get("X-Image-Name"),134 ImageName: c.Request().Header.Get("X-Image-Name"),
135 TargetDomain: c.Request().Header.Get("X-Target-Domain"),135 TargetDomain: c.Request().Header.Get("X-Target-Domain"),
136 }136 }
@@ -149,8 +149,8 @@ func PostDeploy(c echo.Context, a *server.App) error {
149 imageFileName = imageFileName + ".tar"149 imageFileName = imageFileName + ".tar"
150 150
151 // Check the ports struct, if there is no /tcp, or /udp, add /tcp151 // Check the ports struct, if there is no /tcp, or /udp, add /tcp
152- if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Ports) {152+ if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Port) {
153- payload.Ports = payload.Ports + "/tcp"153+ payload.Port = payload.Port + "/tcp"
154 }154 }
155 155
156 // Check the target domain, if there is no https:// or http://, add https://156 // Check the target domain, if there is no https:// or http://, add https://
M internal/templating/cmdparams/fromcli.go +4 -7
@@ -18,11 +18,6 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag
1818
1919 environmentSlice := ParseEnvironmentSlice("")
2020
21- portMappings, err := ParsePortMappingsSlice(ppl.Ports)
22- if err != nil {
23- return docker.ContainerCommandParams{}, err
24- }
25-
2621 // from ppl.TargetDomain, (eg. "https://test.example.com") get container_name (eg. "test"), get container_subdomain (eg. "test"), get container_domain (eg. "example.com") and get container_protocol (eg. "https")
2722 // Parse TargetDomain to get the various components
2823 parsedURL, err := url.Parse(ppl.TargetDomain)
@@ -52,10 +47,12 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag
5247 Volumes: volumeSlice,
5348 Environment: environmentSlice,
5449 Network: a.Config.ContainerEngine.Network,
55- PortMappings: portMappings,
5650 }
5751
58- CreateTraefikLabels(&params)
52+ err = CreateTraefikLabels(&params, ppl.Port, a)
53+ if err != nil {
54+ return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err)
55+ }
5956
6057 return params, nil
6158 }
@@ -18,11 +18,6 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag
18 18
19 environmentSlice := ParseEnvironmentSlice("")19 environmentSlice := ParseEnvironmentSlice("")
20 20
21- portMappings, err := ParsePortMappingsSlice(ppl.Ports)
22- if err != nil {
23- return docker.ContainerCommandParams{}, err
24- }
25-
26 // from ppl.TargetDomain, (eg. "https://test.example.com") get container_name (eg. "test"), get container_subdomain (eg. "test"), get container_domain (eg. "example.com") and get container_protocol (eg. "https")21 // from ppl.TargetDomain, (eg. "https://test.example.com") get container_name (eg. "test"), get container_subdomain (eg. "test"), get container_domain (eg. "example.com") and get container_protocol (eg. "https")
27 // Parse TargetDomain to get the various components22 // Parse TargetDomain to get the various components
28 parsedURL, err := url.Parse(ppl.TargetDomain)23 parsedURL, err := url.Parse(ppl.TargetDomain)
@@ -52,10 +47,12 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag
52 Volumes: volumeSlice,47 Volumes: volumeSlice,
53 Environment: environmentSlice,48 Environment: environmentSlice,
54 Network: a.Config.ContainerEngine.Network,49 Network: a.Config.ContainerEngine.Network,
55- PortMappings: portMappings,
56 }50 }
57 51
58- CreateTraefikLabels(&params)52+ err = CreateTraefikLabels(&params, ppl.Port, a)
53+ if err != nil {
54+ return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err)
55+ }
59 56
60 return params, nil57 return params, nil
61 }58 }
M internal/templating/cmdparams/frominputs.go +17 -1
@@ -1,6 +1,8 @@
11 package cmdparams
22
33 import (
4+ "fmt"
5+
46 "github.com/bnema/gordon/internal/server"
57 "github.com/bnema/gordon/pkg/docker"
68 )
@@ -10,6 +12,10 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
1012 volumeSlice := ParseVolumeSlice(inputs["volumes"])
1113 environmentSlice := ParseEnvironmentSlice(inputs["environment_variables"])
1214 portMappings, err := ParsePortMappingsSlice(inputs["ports"])
15+
16+ // Extract the container port (right side of the mapping)
17+ containerPort := extractContainerPort(portMappings)
18+
1319 if err != nil {
1420 return docker.ContainerCommandParams{}, err
1521 }
@@ -28,7 +34,17 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
2834 PortMappings: portMappings,
2935 }
3036
31- CreateTraefikLabels(&params)
37+ err = CreateTraefikLabels(&params, containerPort, a)
38+ if err != nil {
39+ return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err)
40+ }
3241
3342 return params, nil
3443 }
44+
45+func extractContainerPort(portMappings []docker.PortMapping) string {
46+ if len(portMappings) > 0 {
47+ return portMappings[0].ContainerPort
48+ }
49+ return ""
50+}
@@ -1,6 +1,8 @@
1 package cmdparams1 package cmdparams
2 2
3 import (3 import (
4+ "fmt"
5+
4 "github.com/bnema/gordon/internal/server"6 "github.com/bnema/gordon/internal/server"
5 "github.com/bnema/gordon/pkg/docker"7 "github.com/bnema/gordon/pkg/docker"
6 )8 )
@@ -10,6 +12,10 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
10 volumeSlice := ParseVolumeSlice(inputs["volumes"])12 volumeSlice := ParseVolumeSlice(inputs["volumes"])
11 environmentSlice := ParseEnvironmentSlice(inputs["environment_variables"])13 environmentSlice := ParseEnvironmentSlice(inputs["environment_variables"])
12 portMappings, err := ParsePortMappingsSlice(inputs["ports"])14 portMappings, err := ParsePortMappingsSlice(inputs["ports"])
15+
16+ // Extract the container port (right side of the mapping)
17+ containerPort := extractContainerPort(portMappings)
18+
13 if err != nil {19 if err != nil {
14 return docker.ContainerCommandParams{}, err20 return docker.ContainerCommandParams{}, err
15 }21 }
@@ -28,7 +34,17 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
28 PortMappings: portMappings,34 PortMappings: portMappings,
29 }35 }
30 36
31- CreateTraefikLabels(&params)37+ err = CreateTraefikLabels(&params, containerPort, a)
38+ if err != nil {
39+ return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err)
40+ }
32 41
33 return params, nil42 return params, nil
34 }43 }
44+
45+func extractContainerPort(portMappings []docker.PortMapping) string {
46+ if len(portMappings) > 0 {
47+ return portMappings[0].ContainerPort
48+ }
49+ return ""
50+}
M internal/templating/cmdparams/traefik.go +14 -6
@@ -3,27 +3,35 @@ package cmdparams
33 import (
44 "fmt"
55
6+ "github.com/bnema/gordon/internal/server"
67 "github.com/bnema/gordon/pkg/docker"
78 )
89
910 // CreateTraefikLabels creates Traefik labels based on the provided parameters.
10-func CreateTraefikLabels(params *docker.ContainerCommandParams) {
11- entryPoint := "web"
11+func CreateTraefikLabels(params *docker.ContainerCommandParams, portEntryPoint string, a *server.App) error {
12+ entryPoint := a.Config.Traefik.EntryPoint
1213 if params.IsSSL {
13- entryPoint = "websecure"
14+ entryPoint = a.Config.Traefik.SecureEntryPoint
1415 }
16+
1517 baseRouter := "traefik.http.routers." + params.ContainerName
1618 baseService := "traefik.http.services." + params.ContainerName
17- exposedPort := params.PortMappings[0].ContainerPort
1819
1920 params.Labels = []string{
2021 "traefik.enable=true",
2122 fmt.Sprintf("%s.rule=Host(`%s.%s`)", baseRouter, params.ServiceName, params.Domain),
2223 fmt.Sprintf("%s.entrypoints=%s", baseRouter, entryPoint),
23- fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, exposedPort),
24+ fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, portEntryPoint),
25+ }
26+
27+ resolver := a.Config.Traefik.Resolver
28+ if resolver == "" {
29+ fmt.Errorf("resolver not set in config")
2430 }
2531
2632 if params.IsSSL {
27- params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=myresolver", baseRouter))
33+ params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=%s", baseRouter, resolver))
2834 }
35+
36+ return nil
2937 }
@@ -3,27 +3,35 @@ package cmdparams
3 import (3 import (
4 "fmt"4 "fmt"
5 5
6+ "github.com/bnema/gordon/internal/server"
6 "github.com/bnema/gordon/pkg/docker"7 "github.com/bnema/gordon/pkg/docker"
7 )8 )
8 9
9 // CreateTraefikLabels creates Traefik labels based on the provided parameters.10 // CreateTraefikLabels creates Traefik labels based on the provided parameters.
10-func CreateTraefikLabels(params *docker.ContainerCommandParams) {11+func CreateTraefikLabels(params *docker.ContainerCommandParams, portEntryPoint string, a *server.App) error {
11- entryPoint := "web"12+ entryPoint := a.Config.Traefik.EntryPoint
12 if params.IsSSL {13 if params.IsSSL {
13- entryPoint = "websecure"14+ entryPoint = a.Config.Traefik.SecureEntryPoint
14 }15 }
16+
15 baseRouter := "traefik.http.routers." + params.ContainerName17 baseRouter := "traefik.http.routers." + params.ContainerName
16 baseService := "traefik.http.services." + params.ContainerName18 baseService := "traefik.http.services." + params.ContainerName
17- exposedPort := params.PortMappings[0].ContainerPort
18 19
19 params.Labels = []string{20 params.Labels = []string{
20 "traefik.enable=true",21 "traefik.enable=true",
21 fmt.Sprintf("%s.rule=Host(`%s.%s`)", baseRouter, params.ServiceName, params.Domain),22 fmt.Sprintf("%s.rule=Host(`%s.%s`)", baseRouter, params.ServiceName, params.Domain),
22 fmt.Sprintf("%s.entrypoints=%s", baseRouter, entryPoint),23 fmt.Sprintf("%s.entrypoints=%s", baseRouter, entryPoint),
23- fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, exposedPort),24+ fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, portEntryPoint),
25+ }
26+
27+ resolver := a.Config.Traefik.Resolver
28+ if resolver == "" {
29+ fmt.Errorf("resolver not set in config")
24 }30 }
25 31
26 if params.IsSSL {32 if params.IsSSL {
27- params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=myresolver", baseRouter))33+ params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=%s", baseRouter, resolver))
28 }34 }
35+
36+ return nil
29 }37 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close