build: automation with Go and Mage
We shall now use Go and Mage to manage the Flow services. The templates have been converted to Go templates, Mage has replaced Make and the helper bash scripts have been rewritten in Go.
This commit is contained in:
parent
74d1638ce5
commit
3340ddc475
29 changed files with 689 additions and 358 deletions
|
@ -1,11 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
SERVICE=$1
|
|
||||||
|
|
||||||
export $(cat ./config/flow-platform-services.cfg | grep DOCKER_HOST | tr -d "\"")
|
|
||||||
|
|
||||||
docker compose --project-directory ./build/compose up -d --build "${SERVICE}"
|
|
|
@ -1,15 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
#
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
SERVICE=$1
|
|
||||||
|
|
||||||
export $(xargs < ./config/flow-platform-services.cfg)
|
|
||||||
mkdir -p build/${SERVICE}
|
|
||||||
|
|
||||||
for i in $(find "./templates/${SERVICE}" -mindepth 1 -type f); do
|
|
||||||
file=$(basename ${i})
|
|
||||||
envsubst < "./templates/${SERVICE}/${file}" > "./build/${SERVICE}/${file}"
|
|
||||||
done
|
|
26
Makefile
26
Makefile
|
@ -1,26 +0,0 @@
|
||||||
clean:
|
|
||||||
@find ./build -mindepth 1 -maxdepth 1 -not -iname *.gitkeep | xargs rm -rf
|
|
||||||
|
|
||||||
compose:
|
|
||||||
bash ./.helpers/render.sh compose
|
|
||||||
|
|
||||||
traefik-files: compose
|
|
||||||
bash ./.helpers/render.sh traefik
|
|
||||||
|
|
||||||
traefik: traefik-files
|
|
||||||
bash ./.helpers/deploy.sh traefik
|
|
||||||
|
|
||||||
forgejo-binary:
|
|
||||||
bash ./.helpers/download-forgejo.sh
|
|
||||||
|
|
||||||
forgejo-files: forgejo-binary compose
|
|
||||||
bash ./.helpers/render.sh forgejo
|
|
||||||
|
|
||||||
forgejo: forgejo-files
|
|
||||||
bash ./.helpers/deploy.sh forgejo
|
|
||||||
|
|
||||||
gotosocial-files: compose
|
|
||||||
bash ./.helpers/render.sh gotosocial
|
|
||||||
|
|
||||||
gotosocial: gotosocial-files
|
|
||||||
bash ./.helpers/deploy.sh gotosocial
|
|
2
config
2
config
|
@ -1 +1 @@
|
||||||
Subproject commit 214ea82fd352ea290d41ee42170db34f54a9ef7f
|
Subproject commit b2d4b0b766802f32f70ed2e9c1775476b19b9b6a
|
5
go.mod
Normal file
5
go.mod
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module flow/services
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require github.com/magefile/mage v1.14.0
|
2
go.sum
Normal file
2
go.sum
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
|
||||||
|
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
90
magefiles/config.go
Normal file
90
magefiles/config.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
//go:build mage
|
||||||
|
// +build mage
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
RootDomain string `json:"rootDomain"`
|
||||||
|
FlowGID int32 `json:"flowGID"`
|
||||||
|
DockerNetworkSubnet string `json:"dockerNetworkSubnet"`
|
||||||
|
DockerHost string `json:"dockerHost"`
|
||||||
|
Traefik traefikConfig `json:"traefik"`
|
||||||
|
Forgejo forgejoConfig `json:"forgejo"`
|
||||||
|
GoToSocial gotosocialConfig `json:"gotosocial"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type traefikConfig struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
CheckNewVersion bool `json:"checkNewVersion"`
|
||||||
|
ExternalSSHPort int32 `json:"externalSSHPort"`
|
||||||
|
LogLevel string `json:"logLevel"`
|
||||||
|
SendAnonymousUsage bool `json:"sendAnonymousUsage"`
|
||||||
|
ContainerIpv4Address string `json:"containerIpv4Address"`
|
||||||
|
AcmeEmail string `json:"acmeEmail"`
|
||||||
|
SharedMountPoint string `json:"sharedMountPoint"`
|
||||||
|
TlsHostDirectory string `json:"tlsHostDirectory"`
|
||||||
|
TlsContainerDirectory string `json:"tlsContainerDirectory"`
|
||||||
|
PilotToken string `json:"pilotToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type forgejoConfig struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Subdomain string `json:"subdomain"`
|
||||||
|
ContainerIpv4Address string `json:"containerIpv4Address"`
|
||||||
|
SshPort int32 `json:"sshPort"`
|
||||||
|
HttpPort int32 `json:"httpPort"`
|
||||||
|
RunMode string `json:"runMode"`
|
||||||
|
LogLevel string `json:"logLevel"`
|
||||||
|
LinuxUID int32 `json:"linuxUID"`
|
||||||
|
DataHostDirectory string `json:"dataHostDirectory"`
|
||||||
|
DataContainerDirectory string `json:"dataContainerDirectory"`
|
||||||
|
Home string `json:"home"`
|
||||||
|
Work string `json:"work"`
|
||||||
|
Custom string `json:"custom"`
|
||||||
|
AppIni string `json:"appIni"`
|
||||||
|
Bin string `json:"bin"`
|
||||||
|
Tmp string `json:"tmp"`
|
||||||
|
SecretHostDirectory string `json:"secretHostDirectory"`
|
||||||
|
SecretContainerDirectory string `json:"secretContainerDirectory"`
|
||||||
|
SecretKey string `json:"secretKey"`
|
||||||
|
InternalToken string `json:"internalToken"`
|
||||||
|
LfsJwtSecret string `json:"lfsJwtSecret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type gotosocialConfig struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
DockerImageDigest string `json:"dockerImageDigest"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
LogLevel string `json:"logLevel"`
|
||||||
|
LinuxUID int32 `json:"linuxUID"`
|
||||||
|
Subdomain string `json:"subdomain"`
|
||||||
|
ContainerIpv4Address string `json:"containerIpv4Address"`
|
||||||
|
Port int32 `json:"port"`
|
||||||
|
DataHostDirectory string `json:"dataHostDirectory"`
|
||||||
|
DataContainerDirectory string `json:"dataContainerDirectory"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func newConfig(path string) (config, error) {
|
||||||
|
var c config
|
||||||
|
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return c, fmt.Errorf("unable to open the file; %w", err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(f)
|
||||||
|
|
||||||
|
if err = decoder.Decode(&c); err != nil {
|
||||||
|
return c, fmt.Errorf("unable to decode JSON data; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
10
magefiles/data/forgejo.json
Normal file
10
magefiles/data/forgejo.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"1.18.3-1": {
|
||||||
|
"binary": "https://codeberg.org/attachments/be5952ea-6cfb-4be5-a593-3564c4bd8cc9",
|
||||||
|
"signature": "https://codeberg.org/attachments/07685af6-ca06-4626-8028-302c83ee041c"
|
||||||
|
},
|
||||||
|
"1.18.3-0": {
|
||||||
|
"binary": "https://codeberg.org/attachments/af34fbfc-d651-41b1-aaff-2b9cc7134051",
|
||||||
|
"signature": "https://codeberg.org/attachments/f064c1a9-66f7-41a9-be03-4dc5e2298370"
|
||||||
|
}
|
||||||
|
}
|
126
magefiles/download_forgejo.go
Normal file
126
magefiles/download_forgejo.go
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
//go:build mage
|
||||||
|
// +build mage
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/magefile/mage/sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
type forgejoDownload map[string]map[string]string
|
||||||
|
|
||||||
|
const (
|
||||||
|
forgejoDownloadFileFormat string = "forgejo-%s-linux-amd64"
|
||||||
|
forgejoBinariesJson string = "./magefiles/data/forgejo.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func downloadForgejo(version string) error {
|
||||||
|
downloadFolder := filepath.Join(rootBuildDir, "forgejo")
|
||||||
|
|
||||||
|
if err := os.MkdirAll(downloadFolder, 0o750); err != nil {
|
||||||
|
return fmt.Errorf("unable to make %s; %w", downloadFolder, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryPath := filepath.Join(
|
||||||
|
downloadFolder,
|
||||||
|
fmt.Sprintf(forgejoDownloadFileFormat, version),
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err := os.Stat(binaryPath)
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf("Forgejo %s is already downloaded.\n", version)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := newForgejoDownloadMap()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
binary, err := os.Create(binaryPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer binary.Close()
|
||||||
|
|
||||||
|
client := http.Client{
|
||||||
|
CheckRedirect: func(r *http.Request, via []*http.Request) error {
|
||||||
|
r.URL.Opaque = r.URL.Path
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryURL := m[version]["binary"]
|
||||||
|
|
||||||
|
resp, err := client.Get(binaryURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
size, err := io.Copy(binary, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Downloaded %s with size %d.\n", binaryPath, size)
|
||||||
|
|
||||||
|
signaturePath := binaryPath + ".asc"
|
||||||
|
|
||||||
|
signature, err := os.Create(signaturePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer signature.Close()
|
||||||
|
|
||||||
|
signatureURL := m[version]["signature"]
|
||||||
|
|
||||||
|
sigResp, err := client.Get(signatureURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer sigResp.Body.Close()
|
||||||
|
|
||||||
|
size, err = io.Copy(signature, sigResp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Downloaded %s with size %d.\n", signaturePath, size)
|
||||||
|
|
||||||
|
if err = sh.Run(
|
||||||
|
"gpg",
|
||||||
|
"--verify",
|
||||||
|
signaturePath,
|
||||||
|
binaryPath,
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("GPG verification failed; %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newForgejoDownloadMap() (forgejoDownload, error) {
|
||||||
|
m := make(forgejoDownload)
|
||||||
|
|
||||||
|
f, err := os.Open(forgejoBinariesJson)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(f)
|
||||||
|
|
||||||
|
if err = decoder.Decode(&m); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
91
magefiles/mage.go
Normal file
91
magefiles/mage.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
//go:build mage
|
||||||
|
// +build mage
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/magefile/mage/sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
configFile string = "./config/services.json"
|
||||||
|
rootBuildDir string = "./build"
|
||||||
|
templateExtension string = ".gotmpl"
|
||||||
|
rootTemplatesDir string = "./templates"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clean cleans the workspace.
|
||||||
|
func Clean() error {
|
||||||
|
buildDir := "./build"
|
||||||
|
|
||||||
|
objects, err := os.ReadDir(buildDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range objects {
|
||||||
|
name := objects[i].Name()
|
||||||
|
|
||||||
|
if name != ".gitkeep" {
|
||||||
|
if err := sh.Rm(buildDir + "/" + name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render renders the template files.
|
||||||
|
func Render(name string) error {
|
||||||
|
cfg, err := newConfig(configFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load the configuration; %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := render(cfg, name); err != nil {
|
||||||
|
return fmt.Errorf("an error occurred whilst rendering the templates; %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deploy deploys the services to the Flow Platform.
|
||||||
|
func Deploy(name string) error {
|
||||||
|
cfg, err := newConfig(configFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load the configuration; %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Setenv("DOCKER_HOST", cfg.DockerHost)
|
||||||
|
|
||||||
|
return sh.Run(
|
||||||
|
"docker",
|
||||||
|
"compose",
|
||||||
|
"--project-directory",
|
||||||
|
rootBuildDir+"/compose",
|
||||||
|
"up",
|
||||||
|
"-d",
|
||||||
|
"--build",
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DownloadForgejo downloads the Forgejo binary from Codeberg.
|
||||||
|
func DownloadForgejo() error {
|
||||||
|
cfg, err := newConfig(configFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load the configuration; %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
version := cfg.Forgejo.Version
|
||||||
|
|
||||||
|
if err := downloadForgejo(version); err != nil {
|
||||||
|
return fmt.Errorf("unable to download Forgejo %s; %w", version, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
62
magefiles/render.go
Normal file
62
magefiles/render.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
//go:build mage
|
||||||
|
// +build mage
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func render(cfg config, component string) error {
|
||||||
|
buildDirName := filepath.Join(rootBuildDir, component)
|
||||||
|
if err := os.MkdirAll(buildDirName, 0o750); err != nil {
|
||||||
|
return fmt.Errorf("unable to make %s; %w", buildDirName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
templateDirName := filepath.Join(rootTemplatesDir, component)
|
||||||
|
|
||||||
|
files, err := os.ReadDir(templateDirName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read files from %s; %w ", templateDirName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
err := func() error {
|
||||||
|
templateFilename := f.Name()
|
||||||
|
|
||||||
|
if f.IsDir() || !strings.HasSuffix(templateFilename, templateExtension) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFilename := strings.TrimSuffix(templateFilename, templateExtension)
|
||||||
|
outputPath := filepath.Join(buildDirName, outputFilename)
|
||||||
|
|
||||||
|
file, err := os.Create(outputPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create the file '%s'; %w", outputPath, err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
templatePath := filepath.Join(templateDirName, templateFilename)
|
||||||
|
tmpl, err := template.New(templateFilename).ParseFiles(templatePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create a new template value from '%s'; %w", templateFilename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tmpl.Execute(file, cfg); err != nil {
|
||||||
|
return fmt.Errorf("unable to render the template to '%s'; %w", outputPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("an error occurred whilst rendering the templates for '%s'; %w", component, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,3 +1,13 @@
|
||||||
|
{{- define "defaultVolumes" }}
|
||||||
|
- type: "bind"
|
||||||
|
source: "/etc/timezone"
|
||||||
|
target: "/etc/timezone"
|
||||||
|
read_only: true
|
||||||
|
- type: "bind"
|
||||||
|
source: "/etc/localtime"
|
||||||
|
target: "/etc/localtime"
|
||||||
|
read_only: true
|
||||||
|
{{- end -}}
|
||||||
---
|
---
|
||||||
version: "3.9"
|
version: "3.9"
|
||||||
|
|
||||||
|
@ -7,7 +17,7 @@ networks:
|
||||||
ipam:
|
ipam:
|
||||||
driver: "default"
|
driver: "default"
|
||||||
config:
|
config:
|
||||||
- subnet: "${NETWORK_FORGE_FLOW_SUBNET}"
|
- subnet: "{{ .DockerNetworkSubnet }}"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
traefik-shared:
|
traefik-shared:
|
||||||
|
@ -17,12 +27,12 @@ services:
|
||||||
# -- Traffic flow --
|
# -- Traffic flow --
|
||||||
traefik:
|
traefik:
|
||||||
container_name: "traffic-flow"
|
container_name: "traffic-flow"
|
||||||
image: localhost/flow/traefik:${TRAEFIK_VERSION}
|
image: "localhost/flow/traefik:{{ .Traefik.Version }}"
|
||||||
build:
|
build:
|
||||||
context: "../traefik"
|
context: "../traefik"
|
||||||
networks:
|
networks:
|
||||||
flow:
|
flow:
|
||||||
ipv4_address: "${TRAEFIK_CONTAINER_IPV4_ADDRESS}"
|
ipv4_address: "{{ .Traefik.ContainerIpv4Address }}"
|
||||||
ports:
|
ports:
|
||||||
- target: 80
|
- target: 80
|
||||||
published: 80
|
published: 80
|
||||||
|
@ -32,81 +42,63 @@ services:
|
||||||
published: 443
|
published: 443
|
||||||
protocol: "tcp"
|
protocol: "tcp"
|
||||||
mode: "host"
|
mode: "host"
|
||||||
- target: ${TRAEFIK_EXTERNAL_SSH_PORT}
|
- target: {{ .Traefik.ExternalSSHPort }}
|
||||||
published: ${TRAEFIK_EXTERNAL_SSH_PORT}
|
published: {{ .Traefik.ExternalSSHPort }}
|
||||||
protocol: "tcp"
|
protocol: "tcp"
|
||||||
mode: "host"
|
mode: "host"
|
||||||
restart: "always"
|
restart: "always"
|
||||||
volumes:
|
volumes:
|
||||||
|
{{- template "defaultVolumes" }}
|
||||||
|
# Shared volume
|
||||||
- type: "volume"
|
- type: "volume"
|
||||||
source: "traefik-shared"
|
source: "traefik-shared"
|
||||||
target: "${TRAEFIK_SHARED_MOUNT_POINT}"
|
target: "{{ .Traefik.SharedMountPoint }}"
|
||||||
- type: "bind"
|
|
||||||
source: "/etc/timezone"
|
|
||||||
target: "/etc/timezone"
|
|
||||||
read_only: true
|
|
||||||
- type: "bind"
|
|
||||||
source: "/etc/localtime"
|
|
||||||
target: "/etc/localtime"
|
|
||||||
read_only: true
|
|
||||||
# Traefik TLS volume
|
# Traefik TLS volume
|
||||||
- type: "bind"
|
- type: "bind"
|
||||||
source: "${TRAEFIK_TLS_HOST_DIR}"
|
source: "{{ .Traefik.TlsHostDirectory }}"
|
||||||
target: "${TRAEFIK_TLS_CONTAINER_DIR}"
|
target: "{{ .Traefik.TlsContainerDirectory }}"
|
||||||
# -- Code flow --
|
# -- Code flow --
|
||||||
forgejo:
|
forgejo:
|
||||||
container_name: "code-flow"
|
container_name: "code-flow"
|
||||||
image: localhost/flow/forgejo:${FORGEJO_VERSION}
|
image: "localhost/flow/forgejo:{{ .Forgejo.Version }}"
|
||||||
build:
|
build:
|
||||||
context: "../forgejo"
|
context: "../forgejo"
|
||||||
expose:
|
expose:
|
||||||
- "${FORGEJO_SSH_PORT}"
|
- "{{ .Forgejo.SshPort }}"
|
||||||
- "${FORGEJO_HTTP_PORT}"
|
- "{{ .Forgejo.HttpPort }}"
|
||||||
networks:
|
networks:
|
||||||
flow:
|
flow:
|
||||||
ipv4_address: "${FORGEJO_CONTAINER_IPV4_ADDRESS}"
|
ipv4_address: "{{ .Forgejo.ContainerIpv4Address }}"
|
||||||
restart: "always"
|
restart: "always"
|
||||||
volumes:
|
volumes:
|
||||||
|
{{- template "defaultVolumes" }}
|
||||||
|
# Shared volume
|
||||||
- type: "volume"
|
- type: "volume"
|
||||||
source: "traefik-shared"
|
source: "traefik-shared"
|
||||||
target: "${TRAEFIK_SHARED_MOUNT_POINT}"
|
target: "{{ .Traefik.SharedMountPoint }}"
|
||||||
|
# Forgejo data volume
|
||||||
- type: "bind"
|
- type: "bind"
|
||||||
source: "/etc/timezone"
|
source: "{{ .Forgejo.DataHostDirectory }}"
|
||||||
target: "/etc/timezone"
|
target: "{{ .Forgejo.DataContainerDirectory }}"
|
||||||
read_only: true
|
|
||||||
- type: "bind"
|
|
||||||
source: "/etc/localtime"
|
|
||||||
target: "/etc/localtime"
|
|
||||||
read_only: true
|
|
||||||
# ForgeJo data volume
|
|
||||||
- type: "bind"
|
|
||||||
source: "${FORGEJO_DATA_HOST_DIR}"
|
|
||||||
target: "${FORGEJO_DATA_CONTAINER_DIR}"
|
|
||||||
# -- Free Flow 2 --
|
# -- Free Flow 2 --
|
||||||
gotosocial:
|
gotosocial:
|
||||||
container_name: "free-flow"
|
container_name: "free-flow"
|
||||||
image: localhost/flow/gotosocial:${GTS_VERSION}
|
image: "localhost/flow/gotosocial:{{ .GoToSocial.Version }}"
|
||||||
build:
|
build:
|
||||||
context: "../gotosocial"
|
context: "../gotosocial"
|
||||||
expose:
|
expose:
|
||||||
- "${GTS_PORT}"
|
- "{{ .GoToSocial.Port }}"
|
||||||
networks:
|
networks:
|
||||||
flow:
|
flow:
|
||||||
ipv4_address: "${GTS_CONTAINER_IPV4_ADDRESS}"
|
ipv4_address: "{{ .GoToSocial.ContainerIpv4Address }}"
|
||||||
restart: "always"
|
restart: "always"
|
||||||
volumes:
|
volumes:
|
||||||
|
{{- template "defaultVolumes" }}
|
||||||
|
# Shared volume
|
||||||
- type: "volume"
|
- type: "volume"
|
||||||
source: "traefik-shared"
|
source: "traefik-shared"
|
||||||
target: "${TRAEFIK_SHARED_MOUNT_POINT}"
|
target: "{{ .Traefik.SharedMountPoint }}"
|
||||||
- type: "bind"
|
|
||||||
source: "/etc/timezone"
|
|
||||||
target: "/etc/timezone"
|
|
||||||
read_only: true
|
|
||||||
- type: "bind"
|
|
||||||
source: "/etc/localtime"
|
|
||||||
target: "/etc/localtime"
|
|
||||||
read_only: true
|
|
||||||
# Go To Social data volume
|
# Go To Social data volume
|
||||||
- type: "bind"
|
- type: "bind"
|
||||||
source: "${GTS_DATA_HOST_DIR}"
|
source: "{{ .GoToSocial.DataHostDirectory }}"
|
||||||
target: "${GTS_DATA_CONTAINER_DIR}"
|
target: "{{ .GoToSocial.DataContainerDirectory }}"
|
|
@ -1,44 +0,0 @@
|
||||||
# This is a custom made Dockerfile for Gitea which is inspired from
|
|
||||||
# the official Dockerfile.rootless from https://github.com/go-gitea/gitea/
|
|
||||||
FROM alpine:3.17
|
|
||||||
|
|
||||||
ENV FORGEJO_WORK_DIR=${FORGEJO_WORK_DIR} \
|
|
||||||
FORGEJO_CUSTOM=${FORGEJO_CUSTOM} \
|
|
||||||
FORGEJO_APP_INI=${FORGEJO_APP_INI} \
|
|
||||||
FORGEJO_BIN=${FORGEJO_BIN} \
|
|
||||||
FORGEJO_VERSION=${FORGEJO_VERSION} \
|
|
||||||
HOME=${FORGEJO_HOME}
|
|
||||||
|
|
||||||
RUN apk update && apk upgrade && apk --no-cache add \
|
|
||||||
bash \
|
|
||||||
ca-certificates \
|
|
||||||
gettext \
|
|
||||||
git \
|
|
||||||
curl \
|
|
||||||
gnupg \
|
|
||||||
openssh-keygen \
|
|
||||||
&& addgroup -S -g ${FLOW_GID} flow \
|
|
||||||
&& adduser -S -H -D -h ${FORGEJO_HOME} -s /bin/bash -u ${FORGEJO_FLOW_UID} -G flow git \
|
|
||||||
&& mkdir -p ${FORGEJO_DATA_CONTAINER_DIR} ${FORGEJO_TMP} \
|
|
||||||
&& chown git ${FORGEJO_DATA_CONTAINER_DIR} && chmod 0700 ${FORGEJO_DATA_CONTAINER_DIR} \
|
|
||||||
&& chown git ${FORGEJO_TMP} && chmod 0700 ${FORGEJO_TMP}
|
|
||||||
|
|
||||||
ADD --chown=root:root forgejo-${FORGEJO_VERSION}-linux-amd64 ${FORGEJO_BIN}
|
|
||||||
ADD app.ini ${FORGEJO_APP_INI}
|
|
||||||
ADD entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
||||||
ADD --chown=${FORGEJO_FLOW_UID}:${FLOW_GID} dynamic_git.yaml ${FORGEJO_TMP}/
|
|
||||||
|
|
||||||
RUN chown -R ${FORGEJO_FLOW_UID}:${FORGEJO_FLOW_UID} ${FORGEJO_APP_INI} \
|
|
||||||
&& chmod 0400 ${FORGEJO_APP_INI} \
|
|
||||||
&& chmod a+x ${FORGEJO_BIN} \
|
|
||||||
&& chmod a+rx /usr/local/bin/entrypoint.sh
|
|
||||||
|
|
||||||
USER ${FORGEJO_FLOW_UID}:${FLOW_GID}
|
|
||||||
|
|
||||||
WORKDIR /flow/gitea/data
|
|
||||||
|
|
||||||
VOLUME ["/flow/gitea/data"]
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
|
||||||
|
|
||||||
CMD []
|
|
44
templates/forgejo/Dockerfile.gotmpl
Normal file
44
templates/forgejo/Dockerfile.gotmpl
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# This is a custom made Dockerfile for Gitea which is inspired from
|
||||||
|
# the official Dockerfile.rootless from https://github.com/go-gitea/gitea/
|
||||||
|
FROM alpine:3.17
|
||||||
|
|
||||||
|
ENV FORGEJO_WORK_DIR={{ .Forgejo.Work }} \
|
||||||
|
FORGEJO_CUSTOM={{ .Forgejo.Custom }} \
|
||||||
|
FORGEJO_APP_INI={{ .Forgejo.AppIni }} \
|
||||||
|
FORGEJO_BIN={{ .Forgejo.Bin }} \
|
||||||
|
FORGEJO_VERSION={{ .Forgejo.Version }} \
|
||||||
|
HOME={{ .Forgejo.Home }}
|
||||||
|
|
||||||
|
RUN apk update && apk upgrade && apk --no-cache add \
|
||||||
|
bash \
|
||||||
|
ca-certificates \
|
||||||
|
gettext \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
openssh-keygen \
|
||||||
|
&& addgroup -S -g {{ .FlowGID }} flow \
|
||||||
|
&& adduser -S -H -D -h {{ .Forgejo.Home }} -s /bin/bash -u {{ .Forgejo.LinuxUID }} -G flow git \
|
||||||
|
&& mkdir -p {{ .Forgejo.DataContainerDirectory }} {{ .Forgejo.Tmp }} \
|
||||||
|
&& chown git {{ .Forgejo.DataContainerDirectory }} && chmod 0700 {{ .Forgejo.DataContainerDirectory }} \
|
||||||
|
&& chown git {{ .Forgejo.Tmp }} && chmod 0700 {{ .Forgejo.Tmp }}
|
||||||
|
|
||||||
|
ADD --chown=root:root forgejo-{{ .Forgejo.Version }}-linux-amd64 {{ .Forgejo.Bin }}
|
||||||
|
ADD app.ini {{ .Forgejo.AppIni }}
|
||||||
|
ADD entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
ADD --chown={{ .Forgejo.LinuxUID }}:{{ .FlowGID }} dynamic_git.yaml {{ .Forgejo.Tmp }}/
|
||||||
|
|
||||||
|
RUN chown -R {{ .Forgejo.LinuxUID }}:{{ .Forgejo.LinuxUID }} {{ .Forgejo.AppIni }} \
|
||||||
|
&& chmod 0400 {{ .Forgejo.AppIni }} \
|
||||||
|
&& chmod a+x {{ .Forgejo.Bin }} \
|
||||||
|
&& chmod a+rx /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
USER {{ .Forgejo.LinuxUID }}:{{ .FlowGID }}
|
||||||
|
|
||||||
|
WORKDIR /flow/gitea/data
|
||||||
|
|
||||||
|
VOLUME ["/flow/gitea/data"]
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
|
||||||
|
CMD []
|
|
@ -1,112 +0,0 @@
|
||||||
APP_NAME = "${FORGEJO_APP_NAME_01} ${FORGEJO_APP_NAME_02}"
|
|
||||||
RUN_USER = git
|
|
||||||
RUN_MODE = ${FORGEJO_RUN_MODE}
|
|
||||||
|
|
||||||
[repository]
|
|
||||||
ROOT = ${FORGEJO_DATA_CONTAINER_DIR}/git/repositories
|
|
||||||
DEFAULT_BRANCH = main
|
|
||||||
|
|
||||||
[repository.local]
|
|
||||||
LOCAL_COPY_PATH = ${FORGEJO_TMP}/local-repo
|
|
||||||
|
|
||||||
[repository.upload]
|
|
||||||
TEMP_PATH = ${FORGEJO_TMP}/uploads
|
|
||||||
|
|
||||||
[repository.signing]
|
|
||||||
INITIAL_COMMIT = pubkey, twofa
|
|
||||||
MERGES = pubkey, twofa, basesigned, commitssigned
|
|
||||||
|
|
||||||
[ui]
|
|
||||||
DEFAULT_THEME = forgejo-dark
|
|
||||||
|
|
||||||
[server]
|
|
||||||
APP_DATA_PATH = ${FORGEJO_DATA_CONTAINER_DIR}/git
|
|
||||||
DOMAIN = ${FORGEJO_DOMAIN}
|
|
||||||
HTTP_ADDR = ${FORGEJO_CONTAINER_IPV4_ADDRESS}
|
|
||||||
HTTP_PORT = ${FORGEJO_HTTP_PORT}
|
|
||||||
ROOT_URL = https://${FORGEJO_DOMAIN}
|
|
||||||
DISABLE_SSH = false
|
|
||||||
START_SSH_SERVER = true
|
|
||||||
SSH_DOMAIN = ${FORGEJO_DOMAIN}
|
|
||||||
SSH_PORT = ${TRAEFIK_EXTERNAL_SSH_PORT}
|
|
||||||
SSH_LISTEN_HOST = ${FORGEJO_CONTAINER_IPV4_ADDRESS}
|
|
||||||
SSH_LISTEN_PORT = ${FORGEJO_SSH_PORT}
|
|
||||||
BUILTIN_SSH_SERVER_USER = git
|
|
||||||
LFS_START_SERVER = true
|
|
||||||
LFS_JWT_SECRET = ${FORGEJO_LFS_JWT_SECRET}
|
|
||||||
|
|
||||||
[lfs]
|
|
||||||
STORAGE_TYPE = local
|
|
||||||
PATH = ${FORGEJO_DATA_CONTAINER_DIR}/git/lfs
|
|
||||||
|
|
||||||
[ssh.minimum_key_sizes]
|
|
||||||
ED25519 = 256
|
|
||||||
ECDSA = 256
|
|
||||||
RSA = 4096
|
|
||||||
DSA = -1
|
|
||||||
|
|
||||||
[database]
|
|
||||||
DB_TYPE = sqlite3
|
|
||||||
PATH = ${FORGEJO_DATA_CONTAINER_DIR}/database/gitea.db
|
|
||||||
HOST = localhost:3306
|
|
||||||
NAME = gitea
|
|
||||||
USER = gitea
|
|
||||||
PASSWD =
|
|
||||||
|
|
||||||
[indexer]
|
|
||||||
ISSUE_INDEXER_PATH = ${FORGEJO_DATA_CONTAINER_DIR}/indexers/issues.bleve
|
|
||||||
|
|
||||||
[session]
|
|
||||||
PROVIDER_CONFIG = ${FORGEJO_DATA_CONTAINER_DIR}/sessions
|
|
||||||
|
|
||||||
[queue]
|
|
||||||
DATADIR = ${FORGEJO_DATA_CONTAINER_DIR}/queues
|
|
||||||
|
|
||||||
[admin]
|
|
||||||
DISABLE_REGULAR_ORG_CREATION = true
|
|
||||||
DEFAULT_EMAIL_NOTIFICATION = disabled
|
|
||||||
|
|
||||||
[security]
|
|
||||||
INSTALL_LOCK = true
|
|
||||||
SECRET_KEY = ${FORGEJO_SECRET_KEY}
|
|
||||||
INTERNAL_TOKEN = ${FORGEJO_INTERNAL_TOKEN}
|
|
||||||
LOGIN_REMEMBER_DAYS = 1
|
|
||||||
MIN_PASSWORD_LENGTH = 16
|
|
||||||
PASSWORD_COMPLEXITY = lower,upper,digit
|
|
||||||
|
|
||||||
[service]
|
|
||||||
DISABLE_REGISTRATION = true
|
|
||||||
|
|
||||||
[service.explore]
|
|
||||||
REQUIRE_SIGNIN_VIEW = false
|
|
||||||
|
|
||||||
[picture]
|
|
||||||
AVATAR_UPLOAD_PATH = ${FORGEJO_DATA_CONTAINER_DIR}/avatars
|
|
||||||
REPOSITORY_AVATAR_UPLOAD_PATH = ${FORGEJO_DATA_CONTAINER_DIR}/repo-avatars
|
|
||||||
|
|
||||||
[attachment]
|
|
||||||
ENABLED = true
|
|
||||||
PATH = ${FORGEJO_DATA_CONTAINER_DIR}/attachments
|
|
||||||
|
|
||||||
[log]
|
|
||||||
ROOT_PATH = ${FORGEJO_DATA_CONTAINER_DIR}/log
|
|
||||||
MODE = console
|
|
||||||
LEVEL = ${FORGEJO_LOG_LEVEL}
|
|
||||||
|
|
||||||
[log.console]
|
|
||||||
STDERR = false
|
|
||||||
|
|
||||||
[i18n]
|
|
||||||
LANGS = en-US
|
|
||||||
NAMES = English
|
|
||||||
|
|
||||||
[other]
|
|
||||||
SHOW_FOOTER_BRANDING = true
|
|
||||||
SHOW_FOOTER_VERSION = false
|
|
||||||
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
|
||||||
|
|
||||||
[oauth2]
|
|
||||||
ENABLE = false
|
|
||||||
|
|
||||||
[federation]
|
|
||||||
ENABLED = true
|
|
112
templates/forgejo/app.ini.gotmpl
Normal file
112
templates/forgejo/app.ini.gotmpl
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
APP_NAME = "{{ .Forgejo.Name }}"
|
||||||
|
RUN_USER = git
|
||||||
|
RUN_MODE = {{ .Forgejo.RunMode }}
|
||||||
|
|
||||||
|
[repository]
|
||||||
|
ROOT = {{ .Forgejo.DataContainerDirectory }}/git/repositories
|
||||||
|
DEFAULT_BRANCH = main
|
||||||
|
|
||||||
|
[repository.local]
|
||||||
|
LOCAL_COPY_PATH = {{ .Forgejo.Tmp }}/local-repo
|
||||||
|
|
||||||
|
[repository.upload]
|
||||||
|
TEMP_PATH = {{ .Forgejo.Tmp }}/uploads
|
||||||
|
|
||||||
|
[repository.signing]
|
||||||
|
INITIAL_COMMIT = pubkey, twofa
|
||||||
|
MERGES = pubkey, twofa, basesigned, commitssigned
|
||||||
|
|
||||||
|
[ui]
|
||||||
|
DEFAULT_THEME = forgejo-dark
|
||||||
|
|
||||||
|
[server]
|
||||||
|
APP_DATA_PATH = {{ .Forgejo.DataContainerDirectory }}/git
|
||||||
|
DOMAIN = {{ .Forgejo.Subdomain }}.{{ .RootDomain }}
|
||||||
|
HTTP_ADDR = {{ .Forgejo.ContainerIpv4Address }}
|
||||||
|
HTTP_PORT = {{ .Forgejo.HttpPort }}
|
||||||
|
ROOT_URL = https://{{ .Forgejo.Subdomain }}.{{ .RootDomain }}
|
||||||
|
DISABLE_SSH = false
|
||||||
|
START_SSH_SERVER = true
|
||||||
|
SSH_DOMAIN = {{ .Forgejo.Subdomain }}.{{ .RootDomain }}
|
||||||
|
SSH_PORT = {{ .Traefik.ExternalSSHPort }}
|
||||||
|
SSH_LISTEN_HOST = {{ .Forgejo.ContainerIpv4Address }}
|
||||||
|
SSH_LISTEN_PORT = {{ .Forgejo.SshPort }}
|
||||||
|
BUILTIN_SSH_SERVER_USER = git
|
||||||
|
LFS_START_SERVER = true
|
||||||
|
LFS_JWT_SECRET = {{ .Forgejo.LfsJwtSecret }}
|
||||||
|
|
||||||
|
[lfs]
|
||||||
|
STORAGE_TYPE = local
|
||||||
|
PATH = {{ .Forgejo.DataContainerDirectory }}/git/lfs
|
||||||
|
|
||||||
|
[ssh.minimum_key_sizes]
|
||||||
|
ED25519 = 256
|
||||||
|
ECDSA = 256
|
||||||
|
RSA = 4096
|
||||||
|
DSA = -1
|
||||||
|
|
||||||
|
[database]
|
||||||
|
DB_TYPE = sqlite3
|
||||||
|
PATH = {{ .Forgejo.DataContainerDirectory }}/database/gitea.db
|
||||||
|
HOST = localhost:3306
|
||||||
|
NAME = gitea
|
||||||
|
USER = gitea
|
||||||
|
PASSWD =
|
||||||
|
|
||||||
|
[indexer]
|
||||||
|
ISSUE_INDEXER_PATH = {{ .Forgejo.DataContainerDirectory }}/indexers/issues.bleve
|
||||||
|
|
||||||
|
[session]
|
||||||
|
PROVIDER_CONFIG = {{ .Forgejo.DataContainerDirectory }}/sessions
|
||||||
|
|
||||||
|
[queue]
|
||||||
|
DATADIR = {{ .Forgejo.DataContainerDirectory }}/queues
|
||||||
|
|
||||||
|
[admin]
|
||||||
|
DISABLE_REGULAR_ORG_CREATION = true
|
||||||
|
DEFAULT_EMAIL_NOTIFICATION = disabled
|
||||||
|
|
||||||
|
[security]
|
||||||
|
INSTALL_LOCK = true
|
||||||
|
SECRET_KEY = {{ .Forgejo.SecretKey }}
|
||||||
|
INTERNAL_TOKEN = {{ .Forgejo.InternalToken }}
|
||||||
|
LOGIN_REMEMBER_DAYS = 1
|
||||||
|
MIN_PASSWORD_LENGTH = 16
|
||||||
|
PASSWORD_COMPLEXITY = lower,upper,digit
|
||||||
|
|
||||||
|
[service]
|
||||||
|
DISABLE_REGISTRATION = true
|
||||||
|
|
||||||
|
[service.explore]
|
||||||
|
REQUIRE_SIGNIN_VIEW = false
|
||||||
|
|
||||||
|
[picture]
|
||||||
|
AVATAR_UPLOAD_PATH = {{ .Forgejo.DataContainerDirectory }}/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = {{ .Forgejo.DataContainerDirectory }}/repo-avatars
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
ENABLED = true
|
||||||
|
PATH = {{ .Forgejo.DataContainerDirectory }}/attachments
|
||||||
|
|
||||||
|
[log]
|
||||||
|
ROOT_PATH = {{ .Forgejo.DataContainerDirectory }}/log
|
||||||
|
MODE = console
|
||||||
|
LEVEL = {{ .Forgejo.LogLevel }}
|
||||||
|
|
||||||
|
[log.console]
|
||||||
|
STDERR = false
|
||||||
|
|
||||||
|
[i18n]
|
||||||
|
LANGS = en-US
|
||||||
|
NAMES = English
|
||||||
|
|
||||||
|
[other]
|
||||||
|
SHOW_FOOTER_BRANDING = true
|
||||||
|
SHOW_FOOTER_VERSION = false
|
||||||
|
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
||||||
|
|
||||||
|
[oauth2]
|
||||||
|
ENABLE = false
|
||||||
|
|
||||||
|
[federation]
|
||||||
|
ENABLED = true
|
|
@ -4,7 +4,7 @@ http:
|
||||||
gitea:
|
gitea:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- "https"
|
- "https"
|
||||||
rule: "Host(`${FORGEJO_DOMAIN}`)"
|
rule: "Host(`{{ .Forgejo.Subdomain }}.{{ .RootDomain }}`)"
|
||||||
service: "git"
|
service: "git"
|
||||||
tls:
|
tls:
|
||||||
certResolver: resolver
|
certResolver: resolver
|
||||||
|
@ -12,7 +12,7 @@ http:
|
||||||
git:
|
git:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: "http://${FORGEJO_CONTAINER_IPV4_ADDRESS}:${FORGEJO_HTTP_PORT}/"
|
- url: "http://{{ .Forgejo.ContainerIpv4Address }}:{{ .Forgejo.HttpPort }}/"
|
||||||
|
|
||||||
tcp:
|
tcp:
|
||||||
routers:
|
routers:
|
||||||
|
@ -25,4 +25,4 @@ tcp:
|
||||||
gitSSH:
|
gitSSH:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- address: "${FORGEJO_CONTAINER_IPV4_ADDRESS}:${FORGEJO_SSH_PORT}"
|
- address: "{{ .Forgejo.ContainerIpv4Address }}:{{ .Forgejo.SshPort }}"
|
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Create the home directory.
|
|
||||||
if ! [ -d ${FORGEJO_HOME} ]; then
|
|
||||||
mkdir -p ${FORGEJO_HOME}
|
|
||||||
chmod 0700 ${FORGEJO_HOME}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create the custom directory.
|
|
||||||
if ! [ -d ${FORGEJO_CUSTOM} ]; then
|
|
||||||
mkdir -p ${FORGEJO_CUSTOM}
|
|
||||||
chmod 0500 ${FORGEJO_CUSTOM}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Move the dynamic Traefik config to the shared volume.
|
|
||||||
if [ -f /flow/gitea/tmp/dynamic_git.yaml ]; then
|
|
||||||
mv /flow/gitea/tmp/dynamic_git.yaml ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic/dynamic_git.yaml
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $# -gt 0 ]; then
|
|
||||||
exec "$@"
|
|
||||||
else
|
|
||||||
exec ${FORGEJO_BIN} -c ${FORGEJO_APP_INI} web
|
|
||||||
fi
|
|
28
templates/forgejo/entrypoint.sh.gotmpl
Normal file
28
templates/forgejo/entrypoint.sh.gotmpl
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# Create the home directory.
|
||||||
|
if ! [ -d {{ .Forgejo.Home }} ]; then
|
||||||
|
mkdir -p {{ .Forgejo.Home }}
|
||||||
|
chmod 0700 {{ .Forgejo.Home }}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the custom directory.
|
||||||
|
if ! [ -d {{ .Forgejo.Custom }} ]; then
|
||||||
|
mkdir -p {{ .Forgejo.Custom }}
|
||||||
|
chmod 0500 {{ .Forgejo.Custom }}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move the dynamic Traefik config to the shared volume.
|
||||||
|
if [ -f /flow/gitea/tmp/dynamic_git.yaml ]; then
|
||||||
|
mv /flow/gitea/tmp/dynamic_git.yaml {{ .Traefik.SharedMountPoint }}/dynamic/dynamic_git.yaml
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
exec "$@"
|
||||||
|
else
|
||||||
|
exec {{ .Forgejo.Bin }} -c {{ .Forgejo.AppIni }} web
|
||||||
|
fi
|
|
@ -1,19 +0,0 @@
|
||||||
FROM superseriousbusiness/gotosocial:${GTS_VERSION}@${GTS_DOCKER_IMAGE_DIGEST}
|
|
||||||
|
|
||||||
USER 0
|
|
||||||
|
|
||||||
RUN apk update && apk upgrade && apk add bash \
|
|
||||||
&& addgroup -S -g ${FLOW_GID} flow \
|
|
||||||
&& adduser -S -H -D -s /bin/bash -u ${GTS_UID} -G flow gts \
|
|
||||||
&& chown -R ${GTS_UID}:${GTS_UID} /gotosocial \
|
|
||||||
&& mkdir -p /flow/gts/tmp /flow/gts/config && chown -R ${GTS_UID}:${GTS_UID} /flow/gts
|
|
||||||
|
|
||||||
COPY --chown=${GTS_UID}:${GTS_UID} entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
||||||
COPY --chown=${GTS_UID}:${GTS_UID} config.yaml /flow/gts/config/config.yaml
|
|
||||||
COPY --chown=${GTS_UID}:${FLOW_GID} traefik_gotosocial.yaml /flow/gts/tmp/traefik_gotosocial.yaml
|
|
||||||
|
|
||||||
RUN chmod a+x /usr/local/bin/entrypoint.sh
|
|
||||||
|
|
||||||
USER ${GTS_UID}:${FLOW_GID}
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
|
19
templates/gotosocial/Dockerfile.gotmpl
Normal file
19
templates/gotosocial/Dockerfile.gotmpl
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
FROM superseriousbusiness/gotosocial:{{ .GoToSocial.Version }}@{{ .GoToSocial.DockerImageDigest }}
|
||||||
|
|
||||||
|
USER 0
|
||||||
|
|
||||||
|
RUN apk update && apk upgrade && apk add bash \
|
||||||
|
&& addgroup -S -g {{ .FlowGID }} flow \
|
||||||
|
&& adduser -S -H -D -s /bin/bash -u {{ .GoToSocial.LinuxUID }} -G flow gts \
|
||||||
|
&& chown -R {{ .GoToSocial.LinuxUID }}:{{ .GoToSocial.LinuxUID }} /gotosocial \
|
||||||
|
&& mkdir -p /flow/gts/tmp /flow/gts/config && chown -R {{ .GoToSocial.LinuxUID }}:{{ .GoToSocial.LinuxUID }} /flow/gts
|
||||||
|
|
||||||
|
COPY --chown={{ .GoToSocial.LinuxUID }}:{{ .GoToSocial.LinuxUID }} entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
COPY --chown={{ .GoToSocial.LinuxUID }}:{{ .GoToSocial.LinuxUID }} config.yaml /flow/gts/config/config.yaml
|
||||||
|
COPY --chown={{ .GoToSocial.LinuxUID }}:{{ .FlowGID }} traefik_gotosocial.yaml /flow/gts/tmp/traefik_gotosocial.yaml
|
||||||
|
|
||||||
|
RUN chmod a+x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
USER {{ .GoToSocial.LinuxUID }}:{{ .FlowGID }}
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
|
@ -21,7 +21,7 @@
|
||||||
# String. Log level to use throughout the application. Must be lower-case.
|
# String. Log level to use throughout the application. Must be lower-case.
|
||||||
# Options: ["trace","debug","info","warn","error","fatal"]
|
# Options: ["trace","debug","info","warn","error","fatal"]
|
||||||
# Default: "info"
|
# Default: "info"
|
||||||
log-level: "${GTS_LOG_LEVEL}"
|
log-level: "{{ .GoToSocial.LogLevel }}"
|
||||||
|
|
||||||
# Bool. Log database queries when log-level is set to debug or trace.
|
# Bool. Log database queries when log-level is set to debug or trace.
|
||||||
# This setting produces verbose logs, so it's better to only enable it
|
# This setting produces verbose logs, so it's better to only enable it
|
||||||
|
@ -33,14 +33,14 @@ log-db-queries: false
|
||||||
# String. Application name to use internally.
|
# String. Application name to use internally.
|
||||||
# Examples: ["My Application","gotosocial"]
|
# Examples: ["My Application","gotosocial"]
|
||||||
# Default: "gotosocial"
|
# Default: "gotosocial"
|
||||||
application-name: "${GTS_APPLICATION_NAME_01} ${GTS_APPLICATION_NAME_02}"
|
application-name: "{{ .GoToSocial.Name }}"
|
||||||
|
|
||||||
# String. Hostname that this server will be reachable at. Defaults to localhost for local testing,
|
# String. Hostname that this server will be reachable at. Defaults to localhost for local testing,
|
||||||
# but you should *definitely* change this when running for real, or your server won't work at all.
|
# but you should *definitely* change this when running for real, or your server won't work at all.
|
||||||
# DO NOT change this after your server has already run once, or you will break things!
|
# DO NOT change this after your server has already run once, or you will break things!
|
||||||
# Examples: ["gts.example.org","some.server.com"]
|
# Examples: ["gts.example.org","some.server.com"]
|
||||||
# Default: "localhost"
|
# Default: "localhost"
|
||||||
host: "${GTS_HOST}"
|
host: "{{ .GoToSocial.Subdomain }}.{{ .RootDomain }}"
|
||||||
|
|
||||||
# String. Domain to use when federating profiles. This is useful when you want your server to be at
|
# String. Domain to use when federating profiles. This is useful when you want your server to be at
|
||||||
# eg., "gts.example.org", but you want the domain on accounts to be "example.org" because it looks better
|
# eg., "gts.example.org", but you want the domain on accounts to be "example.org" because it looks better
|
||||||
|
@ -69,7 +69,7 @@ protocol: "https"
|
||||||
# you have specific networking requirements.
|
# you have specific networking requirements.
|
||||||
# Examples: ["0.0.0.0", "172.128.0.16", "localhost", "[::]", "[2001:db8::fed1]"]
|
# Examples: ["0.0.0.0", "172.128.0.16", "localhost", "[::]", "[2001:db8::fed1]"]
|
||||||
# Default: "0.0.0.0"
|
# Default: "0.0.0.0"
|
||||||
bind-address: "${GTS_CONTAINER_IPV4_ADDRESS}"
|
bind-address: "{{ .GoToSocial.ContainerIpv4Address }}"
|
||||||
|
|
||||||
# Int. Listen port for the GoToSocial webserver + API. If you're running behind a reverse proxy and/or in a docker,
|
# Int. Listen port for the GoToSocial webserver + API. If you're running behind a reverse proxy and/or in a docker,
|
||||||
# container, just set this to whatever you like (or leave the default), and make sure it's forwarded properly.
|
# container, just set this to whatever you like (or leave the default), and make sure it's forwarded properly.
|
||||||
|
@ -78,7 +78,7 @@ bind-address: "${GTS_CONTAINER_IPV4_ADDRESS}"
|
||||||
# This *MUST NOT* be the same as the letsencrypt port specified below, unless letsencrypt is turned off.
|
# This *MUST NOT* be the same as the letsencrypt port specified below, unless letsencrypt is turned off.
|
||||||
# Examples: [443, 6666, 8080]
|
# Examples: [443, 6666, 8080]
|
||||||
# Default: 8080
|
# Default: 8080
|
||||||
port: ${GTS_PORT}
|
port: {{ .GoToSocial.Port }}
|
||||||
|
|
||||||
# Array of string. CIDRs or IP addresses of proxies that should be trusted when determining real client IP from behind a reverse proxy.
|
# Array of string. CIDRs or IP addresses of proxies that should be trusted when determining real client IP from behind a reverse proxy.
|
||||||
# If you're running inside a Docker container behind Traefik or Nginx, for example, add the subnet of your docker network,
|
# If you're running inside a Docker container behind Traefik or Nginx, for example, add the subnet of your docker network,
|
||||||
|
@ -86,7 +86,7 @@ port: ${GTS_PORT}
|
||||||
# Example: ["127.0.0.1/32", "172.20.0.1"]
|
# Example: ["127.0.0.1/32", "172.20.0.1"]
|
||||||
# Default: ["127.0.0.1/32"] (localhost)
|
# Default: ["127.0.0.1/32"] (localhost)
|
||||||
trusted-proxies:
|
trusted-proxies:
|
||||||
- "${NETWORK_FORGE_FLOW_SUBNET}"
|
- "{{ .DockerNetworkSubnet }}"
|
||||||
|
|
||||||
############################
|
############################
|
||||||
##### DATABASE CONFIG ######
|
##### DATABASE CONFIG ######
|
||||||
|
@ -112,7 +112,7 @@ db-type: "sqlite"
|
||||||
#
|
#
|
||||||
# Examples: ["localhost","my.db.host","127.0.0.1","192.111.39.110",":memory:", "sqlite.db"]
|
# Examples: ["localhost","my.db.host","127.0.0.1","192.111.39.110",":memory:", "sqlite.db"]
|
||||||
# Default: ""
|
# Default: ""
|
||||||
db-address: "${GTS_DATA_CONTAINER_DIR}/database/gts.db"
|
db-address: "{{ .GoToSocial.DataContainerDirectory }}/database/gts.db"
|
||||||
|
|
||||||
# Int. Port for database connection.
|
# Int. Port for database connection.
|
||||||
# Examples: [5432, 1234, 6969]
|
# Examples: [5432, 1234, 6969]
|
||||||
|
@ -306,7 +306,7 @@ storage-backend: "local"
|
||||||
# Only required when running with the local storage backend.
|
# Only required when running with the local storage backend.
|
||||||
# Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"]
|
# Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"]
|
||||||
# Default: "/gotosocial/storage"
|
# Default: "/gotosocial/storage"
|
||||||
storage-local-base-path: "${GTS_DATA_CONTAINER_DIR}/storage"
|
storage-local-base-path: "{{ .GoToSocial.DataContainerDirectory }}/storage"
|
||||||
|
|
||||||
# String. API endpoint of the S3 compatible service.
|
# String. API endpoint of the S3 compatible service.
|
||||||
# Only required when running with the s3 storage backend.
|
# Only required when running with the s3 storage backend.
|
|
@ -1,12 +1,14 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -euo pipefail
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
# Move the dynamic traefik config to the shared volume
|
# Move the dynamic traefik config to the shared volume
|
||||||
if [ -f /flow/gts/tmp/traefik_gotosocial.yaml ]; then
|
if [ -f /flow/gts/tmp/traefik_gotosocial.yaml ]; then
|
||||||
mv /flow/gts/tmp/traefik_gotosocial.yaml ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic/traefik_gotosocial.yaml
|
mv /flow/gts/tmp/traefik_gotosocial.yaml {{ .Traefik.SharedMountPoint }}/dynamic/traefik_gotosocial.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p ${GTS_DATA_CONTAINER_DIR}/database
|
mkdir -p {{ .GoToSocial.DataContainerDirectory }}/database
|
||||||
|
|
||||||
exec /gotosocial/gotosocial --config-path /flow/gts/config/config.yaml server start
|
exec /gotosocial/gotosocial --config-path /flow/gts/config/config.yaml server start
|
|
@ -4,7 +4,7 @@ http:
|
||||||
gotosocial:
|
gotosocial:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- "https"
|
- "https"
|
||||||
rule: "Host(`${GTS_HOST}`)"
|
rule: "Host(`{{ .GoToSocial.Subdomain }}.{{ .RootDomain }}`)"
|
||||||
service: "gotosocial"
|
service: "gotosocial"
|
||||||
tls:
|
tls:
|
||||||
certResolver: resolver
|
certResolver: resolver
|
||||||
|
@ -12,4 +12,4 @@ http:
|
||||||
gotosocial:
|
gotosocial:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: "http://${GTS_CONTAINER_IPV4_ADDRESS}:${GTS_PORT}/"
|
- url: "http://{{ .GoToSocial.ContainerIpv4Address }}:{{ .GoToSocial.Port }}/"
|
|
@ -1,4 +1,4 @@
|
||||||
FROM traefik:${TRAEFIK_VERSION}
|
FROM traefik:{{ .Traefik.Version }}
|
||||||
|
|
||||||
ADD traefik.yaml /flow/traefik/
|
ADD traefik.yaml /flow/traefik/
|
||||||
|
|
|
@ -4,5 +4,5 @@ http:
|
||||||
dashboard:
|
dashboard:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- "https"
|
- "https"
|
||||||
rule: "Host(`${ROOT_DOMAIN}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
|
rule: "Host(`{{ .RootDomain }}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
|
||||||
service: "api@internal"
|
service: "api@internal"
|
|
@ -1,14 +1,15 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Create the dynamic config directory in the shared volume.
|
# Create the dynamic config directory in the shared volume.
|
||||||
mkdir -p ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic
|
mkdir -p {{ .Traefik.SharedMountPoint }}/dynamic
|
||||||
chgrp ${FLOW_GID} ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic
|
chgrp {{ .FlowGID }} {{ .Traefik.SharedMountPoint }}/dynamic
|
||||||
chmod a-rwx,u+rwx,g+rwx ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic
|
chmod a-rwx,u+rwx,g+rwx {{ .Traefik.SharedMountPoint }}/dynamic
|
||||||
|
|
||||||
# Move the dashboard config to the new directory.
|
# Move the dashboard config to the new directory.
|
||||||
if [ -f /tmp/dynamic_dashboard.yaml ]; then
|
if [ -f /tmp/dynamic_dashboard.yaml ]; then
|
||||||
mv /tmp/dynamic_dashboard.yaml ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic/dynamic_dashboard.yaml
|
mv /tmp/dynamic_dashboard.yaml {{ .Traefik.SharedMountPoint }}/dynamic/dynamic_dashboard.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# first arg is `-f` or `--some-option`
|
# first arg is `-f` or `--some-option`
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
global:
|
|
||||||
checkNewVersion: ${TRAEFIK_CHECK_NEW_VERSION}
|
|
||||||
sendAnonymousUsage: ${TRAEFIK_SEND_ANONYMOUS_USAGE}
|
|
||||||
api:
|
|
||||||
insecure: false
|
|
||||||
dashboard: true
|
|
||||||
debug: false
|
|
||||||
entryPoints:
|
|
||||||
http:
|
|
||||||
address: "${TRAEFIK_CONTAINER_IPV4_ADDRESS}:80"
|
|
||||||
http:
|
|
||||||
redirections:
|
|
||||||
entryPoint:
|
|
||||||
to: "https"
|
|
||||||
scheme: "https"
|
|
||||||
permanent: true
|
|
||||||
https:
|
|
||||||
address: "${TRAEFIK_CONTAINER_IPV4_ADDRESS}:443"
|
|
||||||
gitSSH:
|
|
||||||
address: "${TRAEFIK_CONTAINER_IPV4_ADDRESS}:${TRAEFIK_EXTERNAL_SSH_PORT}"
|
|
||||||
providers:
|
|
||||||
file:
|
|
||||||
watch: true
|
|
||||||
directory: "${TRAEFIK_SHARED_MOUNT_POINT}/dynamic"
|
|
||||||
certificatesResolvers:
|
|
||||||
resolver:
|
|
||||||
acme:
|
|
||||||
email: "${TRAEFIK_ACME_EMAIL}"
|
|
||||||
storage: "${TRAEFIK_TLS_CONTAINER_DIR}/acme.json"
|
|
||||||
keyType: "RSA4096"
|
|
||||||
tlsChallenge: {}
|
|
||||||
log:
|
|
||||||
level: "${TRAEFIK_LOG_LEVEL}"
|
|
||||||
pilot:
|
|
||||||
token: "${TRAEFIK_PILOT_TOKEN}"
|
|
36
templates/traefik/traefik.yaml.gotmpl
Normal file
36
templates/traefik/traefik.yaml.gotmpl
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
global:
|
||||||
|
checkNewVersion: {{ .Traefik.CheckNewVersion }}
|
||||||
|
sendAnonymousUsage: {{ .Traefik.SendAnonymousUsage }}
|
||||||
|
api:
|
||||||
|
insecure: false
|
||||||
|
dashboard: true
|
||||||
|
debug: false
|
||||||
|
entryPoints:
|
||||||
|
http:
|
||||||
|
address: "{{ .Traefik.ContainerIpv4Address }}:80"
|
||||||
|
http:
|
||||||
|
redirections:
|
||||||
|
entryPoint:
|
||||||
|
to: "https"
|
||||||
|
scheme: "https"
|
||||||
|
permanent: true
|
||||||
|
https:
|
||||||
|
address: "{{ .Traefik.ContainerIpv4Address }}:443"
|
||||||
|
gitSSH:
|
||||||
|
address: "{{ .Traefik.ContainerIpv4Address }}:{{ .Traefik.ExternalSSHPort }}"
|
||||||
|
providers:
|
||||||
|
file:
|
||||||
|
watch: true
|
||||||
|
directory: "{{ .Traefik.SharedMountPoint }}/dynamic"
|
||||||
|
certificatesResolvers:
|
||||||
|
resolver:
|
||||||
|
acme:
|
||||||
|
email: "{{ .Traefik.AcmeEmail }}"
|
||||||
|
storage: "{{ .Traefik.TlsContainerDirectory }}/acme.json"
|
||||||
|
keyType: "RSA4096"
|
||||||
|
tlsChallenge: {}
|
||||||
|
log:
|
||||||
|
level: "{{ .Traefik.LogLevel }}"
|
||||||
|
pilot:
|
||||||
|
token: "{{ .Traefik.PilotToken }}"
|
Loading…
Reference in a new issue