feat: add gitea to the docker stack

This commit is contained in:
Dan Anglin 2021-09-01 22:04:40 +01:00
parent fdf2db9e4e
commit 378585875c
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
12 changed files with 334 additions and 103 deletions

View file

@ -26,8 +26,7 @@ type DockerNetworkConfig struct {
Driver string `json:"driver"` Driver string `json:"driver"`
} }
// DockerSharedVolumeConfig contains configuration // DockerSharedVolumeConfig contains configuration for creating the shared volume.
// for creating the shared volume.
type DockerSharedVolumeConfig struct { type DockerSharedVolumeConfig struct {
Name string `json:"name"` Name string `json:"name"`
} }
@ -35,6 +34,7 @@ type DockerSharedVolumeConfig struct {
// Services contains a list of services and their configuration. // Services contains a list of services and their configuration.
type ServicesConfig struct { type ServicesConfig struct {
Traefik TraefikConfig `json:"traefik"` Traefik TraefikConfig `json:"traefik"`
Gitea GiteaConfig `json:"gitea"`
} }
// TraefikConfig contains configuration for the Traefik container. // TraefikConfig contains configuration for the Traefik container.
@ -48,8 +48,27 @@ type TraefikConfig struct {
Version string `json:"version"` Version string `json:"version"`
} }
// NewConfig creates a new Config value from a given // GiteaConfig contains configuration for the Gitea container.
// JSON file. 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) { func NewConfig(file string) (Config, error) {
var c Config var c Config
var err error var err error

View file

@ -31,11 +31,29 @@ func TestValidConfig(t *testing.T) {
Traefik: TraefikConfig{ Traefik: TraefikConfig{
CheckNewVersion: true, CheckNewVersion: true,
ContainerIp: "172.17.1.2", ContainerIp: "172.17.1.2",
Domain: "forge.localhost", Domain: "forge.test.local",
LogLevel: "info", LogLevel: "info",
SendAnonymousUsage: false, SendAnonymousUsage: false,
Version: "v2.4.9", 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",
},
}, },
}, },
} }

View file

@ -13,11 +13,27 @@
"services": { "services": {
"traefik": { "traefik": {
"checkNewVersion": true, "checkNewVersion": true,
"sendAnonymousUsage": false,
"version": "v2.4.9",
"containerIp": "172.17.1.2", "containerIp": "172.17.1.2",
"domain": "forge.test.local",
"logLevel": "info", "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"
} }
} }
} }

View file

@ -36,6 +36,7 @@ type DockerVolume struct {
MountPath pulumi.StringInput MountPath pulumi.StringInput
} }
// CreateContainer creates and runs a new container.
func CreateContainer(ctx *pulumi.Context, c DockerContainerInput) error { func CreateContainer(ctx *pulumi.Context, c DockerContainerInput) error {
// all containers will mount the host's timezone and localtime files // all containers will mount the host's timezone and localtime files
// to ensure the correct time is synced. // to ensure the correct time is synced.

View file

@ -2,7 +2,7 @@ package stacks
import ( import (
"context" "context"
_ "embed" "embed"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -23,17 +23,8 @@ type DockerStack struct {
Stack auto.Stack Stack auto.Stack
} }
//go:embed templates/traefik/Dockerfile.tmpl //go:embed templates/*
var templateTraefikDockerfile string var templates embed.FS
//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. // newContainerStack creates the ContainerStack value.
func newDockerStack(ctx context.Context, project, stack string, c config.Config) (*DockerStack, error) { 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 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 { func (c *DockerStack) Preview(ctx context.Context) error {
streamer := optpreview.ProgressStreams(os.Stdout) streamer := optpreview.ProgressStreams(os.Stdout)
_, err := c.Stack.Preview(ctx, streamer) _, err := c.Stack.Preview(ctx, streamer)
@ -62,7 +53,7 @@ func (c *DockerStack) Preview(ctx context.Context) error {
return nil return nil
} }
// Update the container stack. // Update the docker stack.
func (c *DockerStack) Update(ctx context.Context) error { func (c *DockerStack) Update(ctx context.Context) error {
streamer := optup.ProgressStreams(os.Stdout) streamer := optup.ProgressStreams(os.Stdout)
_, err := c.Stack.Up(ctx, streamer) _, err := c.Stack.Up(ctx, streamer)
@ -72,7 +63,7 @@ func (c *DockerStack) Update(ctx context.Context) error {
return nil return nil
} }
// Destroy the container stack. // Destroy the docker stack.
func (c *DockerStack) Destroy(ctx context.Context) error { func (c *DockerStack) Destroy(ctx context.Context) error {
streamer := optdestroy.ProgressStreams(os.Stdout) streamer := optdestroy.ProgressStreams(os.Stdout)
_, err := c.Stack.Destroy(ctx, streamer) _, err := c.Stack.Destroy(ctx, streamer)
@ -82,11 +73,16 @@ func (c *DockerStack) Destroy(ctx context.Context) error {
return nil return nil
} }
// deployDockerStack returns a Pulumi run function // deployDockerStack returns a Pulumi run function that is used to deploy the docker stack.
// that is used to deploy the docker stack.
func deployDockerStack(project string, dockerConfig config.DockerConfig, services config.ServicesConfig) pulumi.RunFunc { func deployDockerStack(project string, dockerConfig config.DockerConfig, services config.ServicesConfig) pulumi.RunFunc {
groupID := 2239 sharedVolumeMountPath := "/helix/shared"
services.Traefik.GroupId = groupID
groupId := 2239
services.Traefik.GroupId = groupId
services.Gitea.GroupId = groupId
services.Gitea.UserId = 2000
return func(ctx *pulumi.Context) error { return func(ctx *pulumi.Context) error {
// TODO: Create the provider when we start playing with remote hosts // 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 return err
} }
base_cache, err := os.UserCacheDir() baseCache, err := os.UserCacheDir()
if err != nil { if err != nil {
return fmt.Errorf("unable to get the base cache directory...\n%w", err) return fmt.Errorf("unable to get the base cache directory...\n%w", err)
} }
// Create the Traefik service projectCacheRoot := filepath.Join(baseCache, "helix", project)
traefikContextDir := filepath.Join(base_cache, "helix", project, "traefik")
if err := os.MkdirAll(traefikContextDir, 0700); err != nil { // Traefik service.
return fmt.Errorf("unable to make the cache directory for traefik...\n%w", err) if err = renderTemplates(services.Traefik, "traefik", projectCacheRoot); err != nil {
return err
} }
if err := generateFile(services.Traefik, templateTraefikDockerfile, "traefikDocker", filepath.Join(traefikContextDir, "Dockerfile")); err != nil { traefikImageInput := docker.DockerImageInput{
return fmt.Errorf("unable to generate the Traefik Dockerfile from template...\n%w", err) BuildContext: pulumi.String(filepath.Join(projectCacheRoot, "traefik")),
} Dockerfile: pulumi.String(filepath.Join(projectCacheRoot, "traefik", "Dockerfile")),
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")),
ImageName: pulumi.String("helix-traefik"), ImageName: pulumi.String("helix-traefik"),
ImageTag: pulumi.String(services.Traefik.Version), ImageTag: pulumi.String(services.Traefik.Version),
UniqueLabel: "traefik-image", UniqueLabel: "traefik-image",
} }
traefikImage, err := docker.CreateImage(ctx, c) traefikImage, err := docker.CreateImage(ctx, traefikImageInput)
if err != nil { if err != nil {
return err return err
} }
@ -164,7 +144,7 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
DockerVolumes: []docker.DockerVolume{ DockerVolumes: []docker.DockerVolume{
{ {
Name: sharedVolume.Name, 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 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 return nil
} }
} }

View file

@ -3,21 +3,57 @@ package stacks
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings"
"text/template" "text/template"
) )
// generateFile renders a given template to a given filepath. // renderTemplates renders all template files (.tmpl) within a given directory in the
func generateFile(data interface{}, templateString, templateName, path string) error { // embedded 'templates' filesystem.
file, err := os.Create(path) func renderTemplates(data interface{}, service, projectCacheRoot string) error {
if err != nil { // create the context directory
return fmt.Errorf("unable to create the file '%s'...\n%v", path, err) 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 { fsDir, err := templates.ReadDir(templateDir)
return fmt.Errorf("unable to execute the template at '%s'...\n%v", path, err) 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 return nil

View file

@ -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 []

View file

@ -1,16 +1,16 @@
{{/* vim: set ft=dosini : */}} APP_NAME = {{ .AppName }}
APP_NAME = {{ .App.Name }} RUN_USER = git
RUN_MODE = {{ .App.RunMode }} RUN_MODE = {{ .RunMode }}
[repository] [repository]
ROOT = /data/gitea/repositories ROOT = /helix/gitea/data/git/repositories
DEFAULT_BRANCH = main DEFAULT_BRANCH = main
[repository.local] [repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo LOCAL_COPY_PATH = /helix/gitea/tmp/local-repo
[repository.upload] [repository.upload]
TEMP_PATH = /data/gitea/uploads TEMP_PATH = /helix/gitea/tmp/uploads
[repository.signing] [repository.signing]
; Gitea will sign initial commits only if the user has a public key. ; Gitea will sign initial commits only if the user has a public key.
@ -20,17 +20,18 @@ INITIAL_COMMIT = pubkey
DEFAULT_THEME = arc-green DEFAULT_THEME = arc-green
[server] [server]
APP_DATA_PATH = /data/gitea APP_DATA_PATH = /helix/gitea/data/git
DOMAIN = {{ .App.Domain }} DOMAIN = {{ .Domain }}
HTTP_ADDR = {{ .Container.Ip }} HTTP_ADDR = {{ .ContainerIp }}
HTTP_PORT = {{ .App.HttpPort }} HTTP_PORT = {{ .HttpPort }}
ROOT_URL = {{ .App.RootUrl }} ROOT_URL = {{ .RootUrl }}
DISABLE_SSH = false DISABLE_SSH = false
SSH_DOMAIN = {{ .App.SshDomain }} SSH_DOMAIN = {{ .SshDomain }}
SSH_PORT = {{ .App.SshPort }} SSH_PORT = {{ .SshPort }}
SSH_LISTEN_PORT = {{ .App.SshPort }} SSH_LISTEN_PORT = {{ .SshPort }}
LFS_START_SERVER = false BUILTIN_SSH_SERVER_USER = git
LFS_CONTENT_PATH = /data/gitea/lfs LFS_START_SERVER = false
LFS_CONTENT_PATH = /helix/gitea/data/git/lfs
[ssh.minimum_key_sizes] [ssh.minimum_key_sizes]
ED25519 = 256 ED25519 = 256
@ -40,16 +41,20 @@ DSA = -1
[database] [database]
DB_TYPE = sqlite3 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] [indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve ISSUE_INDEXER_PATH = /helix/gitea/data/indexers/issues.bleve
[session] [session]
PROVIDER_CONFIG = /data/gitea/sessions PROVIDER_CONFIG = /helix/gitea/data/sessions
[queue] [queue]
DATADIR = /data/gitea/queues DATADIR = /helix/gitea/data/queues
[admin] [admin]
DISABLE_REGULAR_ORG_CREATION = true DISABLE_REGULAR_ORG_CREATION = true
@ -57,27 +62,30 @@ DEFAULT_EMAIL_NOTIFICATION = disabled
[security] [security]
INSTALL_LOCK = true INSTALL_LOCK = true
SECRET_KEY = {{ .App.SecretKey }} SECRET_KEY = {{ .SecretKey }}
INTERNAL_TOKEN = {{ .InternalToken }}
LOGIN_REMEMBER_DAYS = 1 LOGIN_REMEMBER_DAYS = 1
MIN_PASSWORD_LENGTH = 12 MIN_PASSWORD_LENGTH = 12
PASSWORD_COMPLEXITY = lower,upper,digit PASSWORD_COMPLEXITY = lower,upper,digit
[service] [service]
DISABLED_REGISTRATION = true DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[service.explore]
REQUIRE_SIGNIN_VIEW = false
[picture] [picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars AVATAR_UPLOAD_PATH = /helix/gitea/data/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars REPOSITORY_AVATAR_UPLOAD_PATH = /helix/gitea/data/repo-avatars
[attachment] [attachment]
ENABLED = true ENABLED = true
PATH = /data/gitea/attachments PATH = /helix/gitea/data/attachments
[log] [log]
ROOT_PATH = /data/gitea/log ROOT_PATH = /helix/gitea/data/log
MODE = console MODE = console
LEVEL = {{ .App.LogLevel }} LEVEL = {{ .LogLevel }}
[log.console] [log.console]
STDERR = false STDERR = false
@ -90,3 +98,6 @@ NAMES = English
SHOW_FOOTER_BRANDING = true SHOW_FOOTER_BRANDING = true
SHOW_FOOTER_VERSION = false SHOW_FOOTER_VERSION = false
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
[oauth2]
ENABLE = false

View file

@ -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 }}"

View file

@ -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

View file

@ -1,6 +1,6 @@
FROM traefik:{{ .Version }} FROM traefik:{{ .Version }}
ADD traefik.yml /helix/traefik/ ADD traefik.yaml /helix/traefik/
ADD entrypoint.sh / ADD entrypoint.sh /
@ -10,4 +10,4 @@ RUN chmod +x /entrypoint.sh
EXPOSE 22 80 443 EXPOSE 22 80 443
CMD ["--configfile=/helix/traefik/traefik.yml"] CMD ["--configfile=/helix/traefik/traefik.yaml"]

View file

@ -1,13 +1,18 @@
#!/bin/sh #!/bin/sh
set -e 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. # Create the dynamic config directory in the shared volume.
mkdir -p /helix/shared/traefik/dynamic mkdir -p /helix/shared/traefik/dynamic
chgrp {{ .GroupId }} /helix/shared/traefik/dynamic chgrp {{ .GroupId }} /helix/shared/traefik/dynamic
chmod a-rwx,u+rwx,g+rwx /helix/shared/traefik/dynamic chmod a-rwx,u+rwx,g+rwx /helix/shared/traefik/dynamic
# Move the dashboard config to the new directory. # 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` # first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then if [ "${1#-}" != "$1" ]; then