mirror of
https://github.com/Websoft9/websoft9.git
synced 2024-11-21 23:20:23 +00:00
improve micro service
This commit is contained in:
parent
8a6366724f
commit
63582ea263
12 changed files with 279 additions and 357 deletions
|
@ -8,9 +8,6 @@ COPY init_portainer.go /
|
|||
RUN CGO_ENABLED=0 go build -o init_portainer /init_portainer.go
|
||||
RUN chmod +x /init_portainer
|
||||
|
||||
COPY endpoint.go /
|
||||
RUN CGO_ENABLED=0 go build -o endpoint /endpoint.go
|
||||
RUN chmod +x /endpoint
|
||||
|
||||
# step2: Copy build go program to portainer
|
||||
# Dockerfile refer to: https://github.com/portainer/portainer/blob/develop/build/linux/Dockerfile
|
||||
|
@ -18,6 +15,5 @@ FROM portainer/portainer-ce:2.20.1
|
|||
LABEL maintainer="websoft9<help@websoft9.com>"
|
||||
LABEL version="2.20.1"
|
||||
COPY --from=builder /init_portainer /
|
||||
COPY --from=builder /endpoint /
|
||||
|
||||
ENTRYPOINT ["/init_portainer"]
|
||||
ENTRYPOINT ["/init_portainer"]
|
|
@ -1,3 +1,6 @@
|
|||
# Readme
|
||||
|
||||
- create local endpoint and lock
|
||||
From official Portainer image, and:
|
||||
|
||||
- Initialize username and password
|
||||
- Initialize the local environment endpoint
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
AdminUser = "admin"
|
||||
EndpointURL = "http://localhost:9000/api/endpoints"
|
||||
AuthURL = "http://localhost:9000/api/auth"
|
||||
CredentialLoc = "/data/credential"
|
||||
)
|
||||
|
||||
type Endpoint struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type EndpointCreation struct {
|
||||
Name string `json:"name"`
|
||||
EndpointCreationType int `json:"EndpointCreationType"`
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
Jwt string `json:"jwt"`
|
||||
}
|
||||
|
||||
type Credentials struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Start to create endpoint...")
|
||||
client := &http.Client{}
|
||||
|
||||
password, err := getPassword()
|
||||
if err != nil {
|
||||
fmt.Println("Failed to get password:", err)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authenticate(client, AdminUser, password)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to authenticate:", err)
|
||||
return
|
||||
}
|
||||
|
||||
endpoints, err := queryEndpoints(client, token)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to query endpoints:", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
if endpoint.Name == "local" && endpoint.URL == "unix:///var/run/docker.sock" {
|
||||
fmt.Println("Endpoint exists, exiting...")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Endpoint does not exist, creating...")
|
||||
createEndpoint(client, token)
|
||||
|
||||
fmt.Println("Endpoint created successfully")
|
||||
}
|
||||
|
||||
func getPassword() (string, error) {
|
||||
for {
|
||||
if _, err := os.Stat(CredentialLoc); os.IsNotExist(err) {
|
||||
fmt.Printf("%s does not exist, waiting for 3 seconds...\n", CredentialLoc)
|
||||
time.Sleep(3 * time.Second)
|
||||
} else {
|
||||
fmt.Printf("%s exists, proceeding...\n", CredentialLoc)
|
||||
data, err := ioutil.ReadFile(CredentialLoc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func authenticate(client *http.Client, username, password string) (string, error) {
|
||||
credentials := Credentials{Username: username, Password: password}
|
||||
credentialsJson, err := json.Marshal(credentials)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", AuthURL, bytes.NewBuffer(credentialsJson))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var authResponse AuthResponse
|
||||
err = json.Unmarshal(body, &authResponse)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return authResponse.Jwt, nil
|
||||
}
|
||||
|
||||
func queryEndpoints(client *http.Client, token string) ([]Endpoint, error) {
|
||||
req, err := http.NewRequest("GET", EndpointURL, nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var endpoints []Endpoint
|
||||
err = json.Unmarshal(body, &endpoints)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func createEndpoint(client *http.Client, token string) error {
|
||||
data := url.Values{
|
||||
"Name": {"local"},
|
||||
"EndpointCreationType": {"1"},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", EndpointURL, strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
return fmt.Errorf("Failed to create endpoint: %s, Response body: %s", resp.Status, string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,70 +1,238 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
portainerURL = "http://localhost:9000/api"
|
||||
maxRetries = 5
|
||||
retryDelay = 5 * time.Second
|
||||
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@$()_"
|
||||
credentialFilePath = "/data/credential"
|
||||
initFlagFilePath = "/data/init.flag"
|
||||
)
|
||||
|
||||
type Credentials struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
filePath := "/data/credential"
|
||||
initPath := "/data/init"
|
||||
// 检查初始化标志文件是否存在
|
||||
if _, err := os.Stat(initFlagFilePath); err == nil {
|
||||
log.Println("Initialization has already been completed by another instance.")
|
||||
startPortainer(os.Args[1:]...)
|
||||
return
|
||||
}
|
||||
|
||||
_, err := os.Stat(filePath)
|
||||
if os.IsNotExist(err) {
|
||||
// 启动 Portainer
|
||||
startPortainer(os.Args[1:]...)
|
||||
|
||||
_, err := os.Stat(initPath)
|
||||
// 等待 Portainer 启动
|
||||
waitForPortainer()
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Println("credential is not exist, create it.")
|
||||
password := generatePassword(16)
|
||||
err := writeToFile(filePath, password)
|
||||
if err != nil {
|
||||
fmt.Println("write file error:", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
fmt.Println("credential is exist, skip it.")
|
||||
}
|
||||
|
||||
// call portainer
|
||||
cmd := exec.Command("./portainer", "--admin-password-file", filePath, "--hide-label", "owner=websoft9")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println("error running compiled_program:", err)
|
||||
return
|
||||
}else{
|
||||
os.Create(initPath)
|
||||
}
|
||||
}else{
|
||||
fmt.Println("credential is exist, skip it.")
|
||||
cmd := exec.Command("./portainer", "--hide-label", "owner=websoft9")
|
||||
cmd.Run()
|
||||
}
|
||||
// 初始化 Portainer
|
||||
adminUsername := "admin"
|
||||
adminPassword := generateRandomPassword(12)
|
||||
|
||||
if err := initializePortainerUser(adminUsername, adminPassword); err != nil {
|
||||
log.Fatalf("Failed to initialize Portainer user: %v", err)
|
||||
} else {
|
||||
if err := writeCredentialsToFile(adminPassword); err != nil {
|
||||
log.Fatalf("Failed to write credentials to file: %v", err)
|
||||
} else {
|
||||
if err := initializeLocalEndpoint(adminUsername, adminPassword); err != nil {
|
||||
log.Fatalf("Failed to initialize local endpoint: %v", err)
|
||||
} else {
|
||||
fmt.Println("Portainer initialization completed successfully.")
|
||||
// 创建初始化标志文件
|
||||
if err := ioutil.WriteFile(initFlagFilePath, []byte("initialized"), 0644); err != nil {
|
||||
log.Fatalf("Failed to create initialization flag file: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generatePassword(length int) string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
func startPortainer(args ...string) {
|
||||
cmd := exec.Command("/portainer", args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
charset := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@$()_"
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Fatalf("Failed to start Portainer: %v", err)
|
||||
}
|
||||
|
||||
password := make([]byte, length)
|
||||
for i := range password {
|
||||
password[i] = charset[rand.Intn(len(charset))]
|
||||
}
|
||||
|
||||
return string(password)
|
||||
// 等待 Portainer 进程结束
|
||||
if err := cmd.Wait(); err != nil {
|
||||
log.Fatalf("Portainer process exited with error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func writeToFile(filePath , content string) error {
|
||||
func waitForPortainer() {
|
||||
timeout := time.Duration(60) * time.Second
|
||||
start := time.Now()
|
||||
|
||||
return ioutil.WriteFile(filePath , []byte(content), 0755)
|
||||
}
|
||||
for {
|
||||
resp, err := http.Get(portainerURL + "/system/status")
|
||||
if err == nil && resp.StatusCode == http.StatusOK {
|
||||
fmt.Println("Portainer is up!")
|
||||
break
|
||||
}
|
||||
|
||||
if time.Since(start) > timeout {
|
||||
fmt.Println("Timeout waiting for Portainer")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Waiting for Portainer...")
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func generateRandomPassword(length int) string {
|
||||
password := make([]byte, length)
|
||||
for i := range password {
|
||||
char, _ := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
|
||||
password[i] = charset[char.Int64()]
|
||||
}
|
||||
return string(password)
|
||||
}
|
||||
|
||||
func initializePortainerUser(username, password string) error {
|
||||
requestBody := Credentials{Username: username, Password: password}
|
||||
jsonBody, err := json.Marshal(requestBody)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshaling request body: %w", err)
|
||||
}
|
||||
|
||||
resp, err := retryRequest("POST", portainerURL+"/users/admin/init", "application/json", bytes.NewBuffer(jsonBody))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error making request to Portainer API: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusConflict {
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
return fmt.Errorf("unexpected response status: %d, body: %s", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initializeLocalEndpoint(username, password string) error {
|
||||
authBody := Credentials{Username: username, Password: password}
|
||||
jsonBody, err := json.Marshal(authBody)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshaling auth body: %w", err)
|
||||
}
|
||||
|
||||
resp, err := retryRequest("POST", portainerURL+"/auth", "application/json", bytes.NewBuffer(jsonBody))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error authenticating with Portainer API: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
return fmt.Errorf("unexpected response status: %d, body: %s", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
var authResult map[string]string
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading authentication response: %w", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &authResult)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing authentication response: %w", err)
|
||||
}
|
||||
|
||||
jwtToken := authResult["jwt"]
|
||||
|
||||
endpointBody := url.Values{}
|
||||
endpointBody.Set("Name", "local")
|
||||
endpointBody.Set("EndpointCreationType", "1")
|
||||
|
||||
req, err := http.NewRequest("POST", portainerURL+"/endpoints", strings.NewReader(endpointBody.Encode()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating endpoint request: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Authorization", "Bearer "+jwtToken)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating endpoint in Portainer API: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusConflict {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
return fmt.Errorf("unexpected response status: %d, body: %s", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusConflict {
|
||||
fmt.Println("Endpoint already exists, but this is considered a success.")
|
||||
} else {
|
||||
fmt.Println("Endpoint created successfully.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeCredentialsToFile(password string) error {
|
||||
err := ioutil.WriteFile(credentialFilePath, []byte(password), 0755)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing password to file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func retryRequest(method, url, contentType string, body *bytes.Buffer) (*http.Response, error) {
|
||||
client := &http.Client{}
|
||||
for i := 0; i < maxRetries; i++ {
|
||||
var req *http.Request
|
||||
var err error
|
||||
|
||||
if body != nil {
|
||||
req, err = http.NewRequest(method, url, bytes.NewBuffer(body.Bytes()))
|
||||
} else {
|
||||
req, err = http.NewRequest(method, url, nil)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err == nil {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
log.Printf("Request failed: %v. Retrying in %v...", err, retryDelay)
|
||||
time.Sleep(retryDelay)
|
||||
}
|
||||
return nil, fmt.Errorf("max retries reached")
|
||||
}
|
||||
|
|
|
@ -25,11 +25,7 @@ services:
|
|||
- /data/compose:/data/compose
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
#- /run/podman/podman.sock:/var/run/docker.sock
|
||||
healthcheck:
|
||||
test: ["CMD", "/endpoint"]
|
||||
interval: 10s
|
||||
timeout: 30s
|
||||
retries: 4
|
||||
command: ["--hide-label", "owner=websoft9"]
|
||||
labels:
|
||||
- "owner=websoft9"
|
||||
- "com.docker.compose.w9_http.port=9000"
|
||||
|
|
|
@ -2,18 +2,16 @@
|
|||
# from Dockerfile: https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/Dockerfile
|
||||
# from image: https://hub.docker.com/r/jc21/nginx-proxy-manager
|
||||
|
||||
FROM jc21/nginx-proxy-manager:2.11.1
|
||||
FROM jc21/nginx-proxy-manager:2.11.3
|
||||
|
||||
LABEL maintainer="Websoft9<help@websoft9.com>"
|
||||
LABEL version="2.11.1"
|
||||
LABEL version="2.11.3"
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y curl jq && rm -rf /var/lib/apt/lists/*
|
||||
COPY ./config/initproxy.conf /etc/
|
||||
COPY ./s6/w9init/setuser.sh /app/setuser.sh
|
||||
COPY ./s6/w9init/migration.sh /app/migration.sh
|
||||
COPY ./s6/w9init/setproxy.sh /app/setproxy.sh
|
||||
RUN chmod +x /app/setuser.sh /app/migration.sh /app/setproxy.sh
|
||||
COPY ./config/initproxy.conf /data/nginx/default_host/initproxy.conf
|
||||
COPY ./init_nginx.sh /app/init_nginx.sh
|
||||
RUN chmod +x /app/init_nginx.sh
|
||||
|
||||
# 修复nginx启动加载ip_ranges失败的问题
|
||||
RUN export add_ip_data="const ipDataFile={[CLOUDFRONT_URL]:'ip-ranges.json',[CLOUDFARE_V4_URL]:'ips-v4',[CLOUDFARE_V6_URL]:'ips-v6'}[url];logger.info(ipDataFile);if(ipDataFile){return fs.readFile(__dirname+'/../lib/ipData/'+ipDataFile,'utf8',(error,data)=>{if(error){logger.error('fetch '+ipDataFile+' error');reject(error);return}logger.info('fetch '+ipDataFile+' success');resolve(data)})}" && \
|
||||
sed -i "s#url);#&${add_ip_data}#g" /app/internal/ip_ranges.js && \
|
||||
mkdir -p /app/lib/ipData && cd /app/lib/ipData && \
|
||||
|
@ -21,4 +19,15 @@ RUN export add_ip_data="const ipDataFile={[CLOUDFRONT_URL]:'ip-ranges.json',[CLO
|
|||
curl -O https://www.cloudflare.com/ips-v4 && \
|
||||
curl -O https://www.cloudflare.com/ips-v6
|
||||
|
||||
CMD ["/bin/sh", "-c", "/app/migration.sh && /app/setuser.sh && /app/setproxy.sh && tail -f /dev/null"]
|
||||
|
||||
# 为所有nginx的代理统一加入websockets支持
|
||||
RUN proxy_line=("proxy_set_header Upgrade \$http_upgrade;" "proxy_set_header Connection upgrade;") && \
|
||||
proxy_path="/etc/nginx/conf.d/include/proxy.conf" && \
|
||||
length=${#proxy_line[@]} && \
|
||||
for ((i=0; i<$length; i++)); do \
|
||||
if ! grep -Fxq "${proxy_line[$i]}" $proxy_path; then \
|
||||
echo "${proxy_line[$i]}" >> $proxy_path; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
ENTRYPOINT [ "/app/init_nginx.sh" ]
|
|
@ -1,7 +1,6 @@
|
|||
# Readme
|
||||
|
||||
From official Nginx Proxy Manager image, and:
|
||||
From official Nginx Proxy Manager image, and:
|
||||
|
||||
- add init_proxy.conf to image
|
||||
- init install wizard and modify user and password
|
||||
- lock the line of BoltDB at Portainer where envrionment=1
|
||||
- Copy the initproxy.conf file to the nginx directory to initialize the custom configuration
|
||||
- Initialize username and password through environment variables
|
||||
|
|
31
docker/proxy/init_nginx.sh
Normal file
31
docker/proxy/init_nginx.sh
Normal file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 设置密码目录
|
||||
credential_path="/data/credential"
|
||||
|
||||
# 检查是否已经存在密码文件
|
||||
if [ ! -f "$credential_path" ]; then
|
||||
# 设置用户名和生成随机密码
|
||||
INITIAL_ADMIN_EMAIL="admin@mydomain.com"
|
||||
INITIAL_ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -d '/+' | cut -c1-16)
|
||||
|
||||
# 设置环境变量
|
||||
export INITIAL_ADMIN_EMAIL
|
||||
export INITIAL_ADMIN_PASSWORD
|
||||
|
||||
# 写入密码文件
|
||||
mkdir -p "$(dirname "$credential_path")"
|
||||
credential_json="{\"username\":\"$INITIAL_ADMIN_EMAIL\",\"password\":\"$INITIAL_ADMIN_PASSWORD\"}"
|
||||
echo "$credential_json" > "$credential_path"
|
||||
else
|
||||
# 从密码文件中读取用户名和密码
|
||||
INITIAL_ADMIN_EMAIL=$(jq -r '.username' "$credential_path")
|
||||
INITIAL_ADMIN_PASSWORD=$(jq -r '.password' "$credential_path")
|
||||
|
||||
# 设置环境变量
|
||||
export INITIAL_ADMIN_EMAIL
|
||||
export INITIAL_ADMIN_PASSWORD
|
||||
fi
|
||||
|
||||
# 启动 Nginx
|
||||
exec /init
|
|
@ -1,5 +0,0 @@
|
|||
# S6
|
||||
|
||||
S6 is a mulitply process management tools at Nginx Proxy Manager.
|
||||
|
||||
- nginx_proxy() at migration.sh: Migration initproxy.conf to Nginx, condition is compare Container created time and Named Volumes created time
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set +e
|
||||
|
||||
nginx_proxy(){
|
||||
|
||||
current_time=$(date +%s)
|
||||
shadow_modified_time=$(stat -c %Y /etc/shadow)
|
||||
time_difference=$((current_time - shadow_modified_time))
|
||||
|
||||
if [ ! -f /data/nginx/proxy_host/initproxy.conf ] || [ $time_difference -le 60 ]
|
||||
then
|
||||
cp /etc/initproxy.conf /data/nginx/proxy_host/
|
||||
echo "Update initproxy.conf to Nginx"
|
||||
else
|
||||
echo "Don't need to update initproxy.conf to Nginx"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
nginx_proxy
|
||||
|
||||
set -e
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set +e
|
||||
|
||||
# Define the array
|
||||
proxy_line=("proxy_set_header Upgrade \$http_upgrade;" "proxy_set_header Connection upgrade;")
|
||||
|
||||
# Define the file path
|
||||
proxy_path="/etc/nginx/conf.d/include/proxy.conf"
|
||||
|
||||
# Get the length of the array
|
||||
length=${#proxy_line[@]}
|
||||
|
||||
# Loop over the array and append each item to the file
|
||||
for ((i=0; i<$length; i++)); do
|
||||
# Check if the line already exists in the file
|
||||
if ! grep -Fxq "${proxy_line[$i]}" $proxy_path; then
|
||||
# If the line does not exist in the file, append it
|
||||
echo "${proxy_line[$i]}" >> $proxy_path
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
set -e
|
|
@ -1,61 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set +e
|
||||
username="admin@mydomain.com"
|
||||
password=$(openssl rand -base64 16 | tr -d '/+' | cut -c1-16)
|
||||
token=""
|
||||
cred_path="/data/credential"
|
||||
max_attempts=10
|
||||
|
||||
echo "Start to change nginxproxymanage users"
|
||||
if [ -e "$cred_path" ]; then
|
||||
echo "File $cred_path exists. Exiting script."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "create diretory"
|
||||
mkdir -p "$(dirname "$cred_path")"
|
||||
|
||||
sleep 10
|
||||
while [ -z "$token" ]; do
|
||||
sleep 5
|
||||
login_data=$(curl -X POST -H "Content-Type: application/json" -d '{"identity":"admin@example.com","scope":"user", "secret":"changeme"}' http://localhost:81/api/tokens)
|
||||
token=$(echo $login_data | jq -r '.token')
|
||||
done
|
||||
|
||||
echo "Change username(email)"
|
||||
for attempt in $(seq 1 $max_attempts); do
|
||||
response=$(curl -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d '{"email": "'$username'", "nickname": "admin", "is_disabled": false, "roles": ["admin"]}' http://localhost:81/api/users/1)
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Set username successful"
|
||||
break
|
||||
else
|
||||
echo "Set username failed, retrying..."
|
||||
sleep 5
|
||||
if [ $attempt -eq $max_attempts ]; then
|
||||
echo "Failed to set username after $max_attempts attempts. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Update password"
|
||||
for attempt in $(seq 1 $max_attempts); do
|
||||
response=$(curl -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d '{"type":"password","current":"changeme","secret":"'$password'"}' http://localhost:81/api/users/1/auth)
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Set password successful"
|
||||
echo "Save to credential"
|
||||
json="{\"username\":\"$username\",\"password\":\"$password\"}"
|
||||
echo "$json" > "$cred_path"
|
||||
break
|
||||
else
|
||||
echo "Set password failed, retrying..."
|
||||
sleep 5
|
||||
if [ $attempt -eq $max_attempts ]; then
|
||||
echo "Failed to set password after $max_attempts attempts. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
set -e
|
Loading…
Reference in a new issue