From 378585875c4d9777d44fd8d805796cef0ac7e1fe Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Wed, 1 Sep 2021 22:04:40 +0100 Subject: [PATCH] feat: add gitea to the docker stack --- internal/config/config.go | 27 ++++- internal/config/config_test.go | 20 +++- internal/config/testdata/config-valid.json | 22 +++- internal/docker/container.go | 1 + internal/stacks/docker.go | 112 +++++++++++------- internal/stacks/templates.go | 54 +++++++-- .../stacks/templates/gitea/Dockerfile.tmpl | 58 +++++++-- internal/stacks/templates/gitea/app.ini.tmpl | 69 ++++++----- .../templates/gitea/dynamic_git.yaml.tmpl | 34 ++++++ internal/stacks/templates/gitea/entrypoint.sh | 29 +++++ .../stacks/templates/traefik/Dockerfile.tmpl | 4 +- .../templates/traefik/entrypoint.sh.tmpl | 7 +- 12 files changed, 334 insertions(+), 103 deletions(-) create mode 100644 internal/stacks/templates/gitea/dynamic_git.yaml.tmpl create mode 100644 internal/stacks/templates/gitea/entrypoint.sh diff --git a/internal/config/config.go b/internal/config/config.go index 5fe16ab..152a86b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,8 +26,7 @@ type DockerNetworkConfig struct { Driver string `json:"driver"` } -// DockerSharedVolumeConfig contains configuration -// for creating the shared volume. +// DockerSharedVolumeConfig contains configuration for creating the shared volume. type DockerSharedVolumeConfig struct { Name string `json:"name"` } @@ -35,6 +34,7 @@ type DockerSharedVolumeConfig struct { // Services contains a list of services and their configuration. type ServicesConfig struct { Traefik TraefikConfig `json:"traefik"` + Gitea GiteaConfig `json:"gitea"` } // TraefikConfig contains configuration for the Traefik container. @@ -48,8 +48,27 @@ type TraefikConfig struct { Version string `json:"version"` } -// NewConfig creates a new Config value from a given -// JSON file. +// GiteaConfig contains configuration for the Gitea container. +type GiteaConfig struct { + AppName string `json:"appName"` + BaseUri string `json:"baseUri"` + ContainerIp string `json:"containerIp"` + DataDirectory string `json:"dataDirectory"` + Domain string `json:"domain"` + GroupId int + HttpPort int `json:"httpPort"` + InternalToken string `json:"internalToken"` + LogLevel string `json:"logLevel"` + RootUrl string `json:"rootUrl"` + RunMode string `json:"runMode"` + SecretKey string `json:"secretKey"` + SshDomain string `json:"sshDomain"` + SshPort int `json:"sshPort"` + UserId int + Version string `json:"version"` +} + +// NewConfig creates a new Config value from a given JSON file. func NewConfig(file string) (Config, error) { var c Config var err error diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 5397551..33febf8 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -31,11 +31,29 @@ func TestValidConfig(t *testing.T) { Traefik: TraefikConfig{ CheckNewVersion: true, ContainerIp: "172.17.1.2", - Domain: "forge.localhost", + Domain: "forge.test.local", LogLevel: "info", SendAnonymousUsage: false, Version: "v2.4.9", }, + Gitea: GiteaConfig{ + AppName: "A git hosting platform", + BaseUri: "git", + ContainerIp: "172.17.1.3", + DataDirectory: "/helix/data/gitea", + Domain: "forge.test.local", + GroupId: 0, + HttpPort: 3000, + InternalToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE2MjY0ODQxNjV9.Lp2v7vluALZtAng1jte5-SvF69iAUoh9pFBxf-IJ1a0", + LogLevel: "info", + RootUrl: "https://forge.test.local/git", + RunMode: "test", + SecretKey: "gBFbTiV4GTwzonAyyHNKghc9lmWvaTmFqZs5u0h14Qgx5yp1OKlrZKgw1e5LfCiE", + SshDomain: "forge.test.local", + SshPort: 2222, + UserId: 0, + Version: "1.14.4", + }, }, }, } diff --git a/internal/config/testdata/config-valid.json b/internal/config/testdata/config-valid.json index 87054c5..ff1b64f 100644 --- a/internal/config/testdata/config-valid.json +++ b/internal/config/testdata/config-valid.json @@ -13,11 +13,27 @@ "services": { "traefik": { "checkNewVersion": true, - "sendAnonymousUsage": false, - "version": "v2.4.9", "containerIp": "172.17.1.2", + "domain": "forge.test.local", "logLevel": "info", - "domain": "forge.localhost" + "sendAnonymousUsage": false, + "version": "v2.4.9" + }, + "gitea": { + "appName": "A git hosting platform", + "baseUri": "git", + "containerIp": "172.17.1.3", + "dataDirectory": "/helix/data/gitea", + "domain": "forge.test.local", + "httpPort": 3000, + "internalToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE2MjY0ODQxNjV9.Lp2v7vluALZtAng1jte5-SvF69iAUoh9pFBxf-IJ1a0", + "logLevel": "info", + "rootUrl": "https://forge.test.local/git", + "runMode": "test", + "secretKey": "gBFbTiV4GTwzonAyyHNKghc9lmWvaTmFqZs5u0h14Qgx5yp1OKlrZKgw1e5LfCiE", + "sshDomain": "forge.test.local", + "sshPort": 2222, + "version": "1.14.4" } } } diff --git a/internal/docker/container.go b/internal/docker/container.go index abf610f..af8c2b1 100644 --- a/internal/docker/container.go +++ b/internal/docker/container.go @@ -36,6 +36,7 @@ type DockerVolume struct { MountPath pulumi.StringInput } +// CreateContainer creates and runs a new container. 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. diff --git a/internal/stacks/docker.go b/internal/stacks/docker.go index 91180b9..c4cf6b3 100644 --- a/internal/stacks/docker.go +++ b/internal/stacks/docker.go @@ -2,7 +2,7 @@ package stacks import ( "context" - _ "embed" + "embed" "fmt" "os" "path/filepath" @@ -23,17 +23,8 @@ type DockerStack struct { Stack auto.Stack } -//go:embed templates/traefik/Dockerfile.tmpl -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 +//go:embed templates/* +var templates embed.FS // newContainerStack creates the ContainerStack value. func newDockerStack(ctx context.Context, project, stack string, c config.Config) (*DockerStack, error) { @@ -52,7 +43,7 @@ func newDockerStack(ctx context.Context, project, stack string, c config.Config) return &d, nil } -// Preview the proposed changes to the container stack. +// Preview the proposed changes to the docker stack. func (c *DockerStack) Preview(ctx context.Context) error { streamer := optpreview.ProgressStreams(os.Stdout) _, err := c.Stack.Preview(ctx, streamer) @@ -62,7 +53,7 @@ func (c *DockerStack) Preview(ctx context.Context) error { return nil } -// Update the container stack. +// Update the docker stack. func (c *DockerStack) Update(ctx context.Context) error { streamer := optup.ProgressStreams(os.Stdout) _, err := c.Stack.Up(ctx, streamer) @@ -72,7 +63,7 @@ func (c *DockerStack) Update(ctx context.Context) error { return nil } -// Destroy the container stack. +// Destroy the docker stack. func (c *DockerStack) Destroy(ctx context.Context) error { streamer := optdestroy.ProgressStreams(os.Stdout) _, err := c.Stack.Destroy(ctx, streamer) @@ -82,11 +73,16 @@ func (c *DockerStack) Destroy(ctx context.Context) error { return nil } -// deployDockerStack returns a Pulumi run function -// that is used to deploy the docker stack. +// 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 + sharedVolumeMountPath := "/helix/shared" + + groupId := 2239 + + services.Traefik.GroupId = groupId + + services.Gitea.GroupId = groupId + services.Gitea.UserId = 2000 return func(ctx *pulumi.Context) error { // TODO: Create the provider when we start playing with remote hosts @@ -114,43 +110,27 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service return err } - base_cache, err := os.UserCacheDir() + baseCache, err := os.UserCacheDir() if err != nil { return fmt.Errorf("unable to get the base cache directory...\n%w", err) } - // Create the Traefik service - traefikContextDir := filepath.Join(base_cache, "helix", project, "traefik") + projectCacheRoot := filepath.Join(baseCache, "helix", project) - if err := os.MkdirAll(traefikContextDir, 0700); err != nil { - return fmt.Errorf("unable to make the cache directory for traefik...\n%w", err) + // Traefik service. + if err = renderTemplates(services.Traefik, "traefik", projectCacheRoot); err != nil { + return err } - if err := generateFile(services.Traefik, templateTraefikDockerfile, "traefikDocker", filepath.Join(traefikContextDir, "Dockerfile")); err != nil { - return fmt.Errorf("unable to generate the Traefik Dockerfile from template...\n%w", err) - } - - if err := generateFile(services.Traefik, templateTraefikStaticConfig, "traefikStaticConf", filepath.Join(traefikContextDir, "traefik.yml")); err != nil { - 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")), + traefikImageInput := docker.DockerImageInput{ + BuildContext: pulumi.String(filepath.Join(projectCacheRoot, "traefik")), + Dockerfile: pulumi.String(filepath.Join(projectCacheRoot, "traefik", "Dockerfile")), ImageName: pulumi.String("helix-traefik"), ImageTag: pulumi.String(services.Traefik.Version), UniqueLabel: "traefik-image", } - traefikImage, err := docker.CreateImage(ctx, c) + traefikImage, err := docker.CreateImage(ctx, traefikImageInput) if err != nil { return err } @@ -164,7 +144,7 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service DockerVolumes: []docker.DockerVolume{ { Name: sharedVolume.Name, - MountPath: pulumi.String("/helix/shared"), + MountPath: pulumi.String(sharedVolumeMountPath), }, }, } @@ -173,6 +153,48 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service return err } + // Gitea service + if err = renderTemplates(services.Gitea, "gitea", projectCacheRoot); err != nil { + return err + } + + giteaImageInput := docker.DockerImageInput{ + BuildContext: pulumi.String(filepath.Join(projectCacheRoot, "gitea")), + Dockerfile: pulumi.String(filepath.Join(projectCacheRoot, "gitea", "Dockerfile")), + ImageName: pulumi.String("helix-gitea"), + ImageTag: pulumi.String(services.Gitea.Version), + UniqueLabel: "gitea-image", + } + + giteaImage, err := docker.CreateImage(ctx, giteaImageInput) + if err != nil { + return err + } + + giteaContainerInput := docker.DockerContainerInput{ + Image: giteaImage.ImageName, + Ipv4Address: pulumi.String(services.Gitea.ContainerIp), + Name: pulumi.String("helix-gitea"), + Network: network.Name, + DockerVolumes: []docker.DockerVolume{ + { + Name: sharedVolume.Name, + MountPath: pulumi.String(sharedVolumeMountPath), + }, + }, + HostPathVolumes: []docker.HostPathVolume{ + { + HostPath: pulumi.String(services.Gitea.DataDirectory), + MountPath: pulumi.String("/helix/gitea/data"), + }, + }, + UniqueLabel: "gitea-container", + } + + if err = docker.CreateContainer(ctx, giteaContainerInput); err != nil { + return err + } + return nil } } diff --git a/internal/stacks/templates.go b/internal/stacks/templates.go index 7b0a97a..f027135 100644 --- a/internal/stacks/templates.go +++ b/internal/stacks/templates.go @@ -3,21 +3,57 @@ package stacks import ( "fmt" "os" + "path/filepath" + "strings" "text/template" ) -// generateFile renders a given template to a given filepath. -func generateFile(data interface{}, templateString, templateName, path string) error { - file, err := os.Create(path) - if err != nil { - return fmt.Errorf("unable to create the file '%s'...\n%v", path, err) +// renderTemplates renders all template files (.tmpl) within a given directory in the +// embedded 'templates' filesystem. +func renderTemplates(data interface{}, service, projectCacheRoot string) error { + // create the context directory + contextDir := filepath.Join(projectCacheRoot, service) + + if err := os.MkdirAll(contextDir, 0700); err != nil { + return fmt.Errorf("unable to make the cache directory for %s...\n%w", service, err) } - defer file.Close() - tmpl := template.Must(template.New(templateName).Parse(templateString)) + // read the service's template directory to get the list of the template files. + templateDir := "templates/" + service - if err = tmpl.Execute(file, data); err != nil { - return fmt.Errorf("unable to execute the template at '%s'...\n%v", path, err) + fsDir, err := templates.ReadDir(templateDir) + if err != nil { + return err + } + + // render each template file (.tmpl) to the context directory. + for _, f := range fsDir { + filename := f.Name() + + content, err := templates.ReadFile(fmt.Sprintf("%s/%s", templateDir, filename)) + if err != nil { + return err + } + + outputFilename := strings.TrimSuffix(filename, ".tmpl") + outputPath := filepath.Join(contextDir, outputFilename) + + file, err := os.Create(outputPath) + if err != nil { + return fmt.Errorf("unable to create the file '%s'...\n%v", outputPath, err) + } + defer file.Close() + + if !strings.HasSuffix(filename, ".tmpl") { + fmt.Fprint(file, string(content)) + return nil + } + + tmpl := template.Must(template.New(filename).Parse(string(content))) + + if err = tmpl.Execute(file, data); err != nil { + return fmt.Errorf("unable to execute the template at '%s'...\n%v", outputFilename, err) + } } return nil diff --git a/internal/stacks/templates/gitea/Dockerfile.tmpl b/internal/stacks/templates/gitea/Dockerfile.tmpl index efe198e..97c31ca 100644 --- a/internal/stacks/templates/gitea/Dockerfile.tmpl +++ b/internal/stacks/templates/gitea/Dockerfile.tmpl @@ -1,15 +1,55 @@ -{{/* vim: set ft=dockerfile : */}} +# This is a helix flavoured Dockerfile for Gitea which is inspired from +# the official Dockerfile.rootless from https://github.com/go-gitea/gitea/ -ARG GITEA_VERSION={{ .Version }} +FROM alpine:3.14.0 AS verifier -FROM gitea/gitea:${GITEA_VERSION} +RUN apk --no-cache add gnupg curl && \ + curl -L https://dl.gitea.io/gitea/{{ .Version }}/gitea-{{ .Version }}-linux-amd64 -o /gitea && \ + curl -L https://dl.gitea.io/gitea/{{ .Version }}/gitea-{{ .Version }}-linux-amd64.asc -o /gitea.asc && \ + gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2 && \ + gpg --verify /gitea.asc /gitea -ENV USER_UID=1000 \ - USER_GID=1000 \ - GITEA_CUSTOM=/helix/gitea/custom -ADD files app.ini /helix/gitea/custom/app.ini +FROM alpine:3.14.0 -RUN chown -R ${USER_ID}:${USER_GID} /helix +RUN apk --no-cache add \ + bash \ + ca-certificates \ + gettext \ + git \ + curl \ + gnupg -EXPOSE {{ .App.HttpPort }} {{ .App.SshPort }} +RUN addgroup -S -g {{ .GroupId }} git && \ + adduser -S -H -D -h /helix/gitea/data/home -s /bin/bash -u {{ .UserId }} -G git git && \ + mkdir -p /helix/gitea/data /helix/gitea/tmp && \ + chown git:git /helix/gitea/data && chmod 0700 /helix/gitea/data && \ + chown git:git /helix/gitea/tmp && chmod 0700 /helix/gitea/tmp + +COPY --from=verifier --chown=root:root /gitea /usr/local/bin/gitea +ADD app.ini /helix/gitea/config/ +ADD entrypoint.sh /usr/local/bin/entrypoint.sh +ADD --chown={{ .UserId }}:{{ .GroupId }} dynamic_git.yaml /helix/gitea/tmp/ + +RUN chown -R git:git /helix/gitea/config/app.ini && \ + chmod 0400 /helix/gitea/config/app.ini && \ + chmod a+x /usr/local/bin/gitea && \ + chmod a+x /usr/local/bin/entrypoint.sh + +ENV GITEA_WORK_DIR=/helix/gitea/data \ + GITEA_CUSTOM=/helix/gitea/data/custom \ + GITEA_APP_INI=/helix/gitea/config/app.ini \ + GITEA_BIN=/usr/local/bin/gitea \ + HOME=/helix/gitea/data/home + +USER {{ .UserId }}:{{ .GroupId }} + +WORKDIR /helix/gitea/data + +VOLUME ["/helix/gitea/data"] + +EXPOSE {{ .HttpPort }} {{ .SshPort }} + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD [] diff --git a/internal/stacks/templates/gitea/app.ini.tmpl b/internal/stacks/templates/gitea/app.ini.tmpl index d7557b3..f1df12a 100644 --- a/internal/stacks/templates/gitea/app.ini.tmpl +++ b/internal/stacks/templates/gitea/app.ini.tmpl @@ -1,16 +1,16 @@ -{{/* vim: set ft=dosini : */}} -APP_NAME = {{ .App.Name }} -RUN_MODE = {{ .App.RunMode }} +APP_NAME = {{ .AppName }} +RUN_USER = git +RUN_MODE = {{ .RunMode }} [repository] -ROOT = /data/gitea/repositories +ROOT = /helix/gitea/data/git/repositories DEFAULT_BRANCH = main [repository.local] -LOCAL_COPY_PATH = /data/gitea/tmp/local-repo +LOCAL_COPY_PATH = /helix/gitea/tmp/local-repo [repository.upload] -TEMP_PATH = /data/gitea/uploads +TEMP_PATH = /helix/gitea/tmp/uploads [repository.signing] ; Gitea will sign initial commits only if the user has a public key. @@ -20,17 +20,18 @@ INITIAL_COMMIT = pubkey DEFAULT_THEME = arc-green [server] -APP_DATA_PATH = /data/gitea -DOMAIN = {{ .App.Domain }} -HTTP_ADDR = {{ .Container.Ip }} -HTTP_PORT = {{ .App.HttpPort }} -ROOT_URL = {{ .App.RootUrl }} -DISABLE_SSH = false -SSH_DOMAIN = {{ .App.SshDomain }} -SSH_PORT = {{ .App.SshPort }} -SSH_LISTEN_PORT = {{ .App.SshPort }} -LFS_START_SERVER = false -LFS_CONTENT_PATH = /data/gitea/lfs +APP_DATA_PATH = /helix/gitea/data/git +DOMAIN = {{ .Domain }} +HTTP_ADDR = {{ .ContainerIp }} +HTTP_PORT = {{ .HttpPort }} +ROOT_URL = {{ .RootUrl }} +DISABLE_SSH = false +SSH_DOMAIN = {{ .SshDomain }} +SSH_PORT = {{ .SshPort }} +SSH_LISTEN_PORT = {{ .SshPort }} +BUILTIN_SSH_SERVER_USER = git +LFS_START_SERVER = false +LFS_CONTENT_PATH = /helix/gitea/data/git/lfs [ssh.minimum_key_sizes] ED25519 = 256 @@ -40,16 +41,20 @@ DSA = -1 [database] DB_TYPE = sqlite3 -PATH = /data/gitea/database/gitea.db +PATH = /helix/gitea/data/database/gitea.db +HOST = localhost:3306 +NAME = gitea +USER = gitea +PASSWD = [indexer] -ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve +ISSUE_INDEXER_PATH = /helix/gitea/data/indexers/issues.bleve [session] -PROVIDER_CONFIG = /data/gitea/sessions +PROVIDER_CONFIG = /helix/gitea/data/sessions [queue] -DATADIR = /data/gitea/queues +DATADIR = /helix/gitea/data/queues [admin] DISABLE_REGULAR_ORG_CREATION = true @@ -57,27 +62,30 @@ DEFAULT_EMAIL_NOTIFICATION = disabled [security] INSTALL_LOCK = true -SECRET_KEY = {{ .App.SecretKey }} +SECRET_KEY = {{ .SecretKey }} +INTERNAL_TOKEN = {{ .InternalToken }} LOGIN_REMEMBER_DAYS = 1 MIN_PASSWORD_LENGTH = 12 PASSWORD_COMPLEXITY = lower,upper,digit [service] -DISABLED_REGISTRATION = true -REQUIRE_SIGNIN_VIEW = false +DISABLE_REGISTRATION = true + +[service.explore] +REQUIRE_SIGNIN_VIEW = false [picture] -AVATAR_UPLOAD_PATH = /data/gitea/avatars -REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars +AVATAR_UPLOAD_PATH = /helix/gitea/data/avatars +REPOSITORY_AVATAR_UPLOAD_PATH = /helix/gitea/data/repo-avatars [attachment] ENABLED = true -PATH = /data/gitea/attachments +PATH = /helix/gitea/data/attachments [log] -ROOT_PATH = /data/gitea/log +ROOT_PATH = /helix/gitea/data/log MODE = console -LEVEL = {{ .App.LogLevel }} +LEVEL = {{ .LogLevel }} [log.console] STDERR = false @@ -90,3 +98,6 @@ NAMES = English SHOW_FOOTER_BRANDING = true SHOW_FOOTER_VERSION = false SHOW_FOOTER_TEMPLATE_LOAD_TIME = false + +[oauth2] +ENABLE = false diff --git a/internal/stacks/templates/gitea/dynamic_git.yaml.tmpl b/internal/stacks/templates/gitea/dynamic_git.yaml.tmpl new file mode 100644 index 0000000..30cdedb --- /dev/null +++ b/internal/stacks/templates/gitea/dynamic_git.yaml.tmpl @@ -0,0 +1,34 @@ +--- +http: + routers: + gitea: + entryPoints: + - "https" + rule: "Host(`{{ .Domain }}`) && PathPrefix(`/{{ .BaseUri }}`)" + service: "git" + middlewares: + - "git-strip-prefix" + tls: {} + middlewares: + git-strip-prefix: + stripPrefix: + prefixes: + - "/{{ .BaseUri }}" + services: + git: + loadBalancer: + servers: + - url: "http://{{ .ContainerIp }}:{{ .HttpPort }}/" + +tcp: + routers: + gitSSH: + entryPoints: + - "ssh" + rule: "HostSNI(`*`)" + service: "gitSSH" + services: + gitSSH: + loadBalancer: + servers: + - address: "{{ .ContainerIp }}:{{ .SshPort }}" diff --git a/internal/stacks/templates/gitea/entrypoint.sh b/internal/stacks/templates/gitea/entrypoint.sh new file mode 100644 index 0000000..7521cb5 --- /dev/null +++ b/internal/stacks/templates/gitea/entrypoint.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -euo pipefail + +TRAEFIK_CONFIG_SRC="/helix/gitea/tmp/dynamic_git.yaml" +TRAEFIK_CONFIG_DEST="/helix/shared/traefik/dynamic/dynamic_git.yaml" + +# Create the home directory. +if ! [ -d ${HOME} ]; then + mkdir -p ${HOME} + chmod 0700 ${HOME} +fi + +# Create the custom directory. +if ! [ -d ${GITEA_CUSTOM} ]; then + mkdir -p ${GITEA_CUSTOM} + chmod 0500 ${GITEA_CUSTOM} +fi + +# Move the dynamic Traefik config to the shared volume. +if [ -f ${TRAEFIK_CONFIG_SRC} ]; then + mv ${TRAEFIK_CONFIG_SRC} ${TRAEFIK_CONFIG_DEST} +fi + +if [ $# -gt 0 ]; then + exec "$@" +else + exec ${GITEA_BIN} -c ${GITEA_APP_INI} web +fi diff --git a/internal/stacks/templates/traefik/Dockerfile.tmpl b/internal/stacks/templates/traefik/Dockerfile.tmpl index f43e3e6..c8d197a 100644 --- a/internal/stacks/templates/traefik/Dockerfile.tmpl +++ b/internal/stacks/templates/traefik/Dockerfile.tmpl @@ -1,6 +1,6 @@ FROM traefik:{{ .Version }} -ADD traefik.yml /helix/traefik/ +ADD traefik.yaml /helix/traefik/ ADD entrypoint.sh / @@ -10,4 +10,4 @@ RUN chmod +x /entrypoint.sh EXPOSE 22 80 443 -CMD ["--configfile=/helix/traefik/traefik.yml"] +CMD ["--configfile=/helix/traefik/traefik.yaml"] diff --git a/internal/stacks/templates/traefik/entrypoint.sh.tmpl b/internal/stacks/templates/traefik/entrypoint.sh.tmpl index f53aa28..3063ccc 100644 --- a/internal/stacks/templates/traefik/entrypoint.sh.tmpl +++ b/internal/stacks/templates/traefik/entrypoint.sh.tmpl @@ -1,13 +1,18 @@ #!/bin/sh set -e +DASHBOARD_CONFIG_SRC="/tmp/dynamic_dashboard.yaml" +DASHBOARD_CONFIG_DEST="/helix/shared/traefik/dynamic/dashboard.yaml" + # 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 +if [ -f ${DASHBOARD_CONFIG_SRC} ]; then + mv ${DASHBOARD_CONFIG_SRC} ${DASHBOARD_CONFIG_DEST} +fi # first arg is `-f` or `--some-option` if [ "${1#-}" != "$1" ]; then