Skip to content

Commit

Permalink
feat(devcontainer): multi node
Browse files Browse the repository at this point in the history
  • Loading branch information
0xJacky committed Feb 3, 2025
1 parent c85a570 commit b090564
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 49 deletions.
10 changes: 1 addition & 9 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,7 @@ RUN apt-get update && \
\
# Update package information and install Nginx
apt-get update && \
apt-get install -y --no-install-recommends nginx && \
\
# Install the latest Node.js via NodeSource setup script
curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \
apt-get update && \
apt-get install -y nodejs && \
\
# Install pnpm globally using npm
npm install -g pnpm && \
apt-get install -y --no-install-recommends nginx inotify-tools file && \
\
# Automatically retrieve the latest stable Go version and install it,
# download the appropriate binary based on system architecture (amd64 or arm64)
Expand Down
6 changes: 4 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installOhMyZsh": true
}
},
"ghcr.io/devcontainers/features/node:1": {}
},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
Expand All @@ -27,7 +28,8 @@
"antfu.unocss",
"github.copilot",
"golang.go",
"vue.volar"
"vue.volar",
"ms-azuretools.vscode-docker"
]
}
},
Expand Down
18 changes: 17 additions & 1 deletion .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
services:
nginx-ui:
build: .
image: nginx-ui-dev
container_name: nginx-ui
volumes:
- ../..:/workspaces:cached
- ./go-path:/root/go
- ./nginx:/etc/nginx
- ./data/nginx:/etc/nginx
command: sleep infinity
environment:
- NGINX_UI_CERT_CA_DIR=https://pebble:14000/dir
networks:
nginxui:
nginx-ui-2:
image: nginx-ui-dev
container_name: nginx-ui-2
volumes:
- ../..:/workspaces:cached
- ./data/nginx-ui-2/nginx:/etc/nginx
- ./data/nginx-ui-2/nginx-ui:/etc/nginx-ui
working_dir: /workspaces/nginx-ui
command: ./.devcontainer/node-supervisor.sh
depends_on:
- nginx-ui
networks:
nginxui:

pebble:
image: ghcr.io/letsencrypt/pebble:latest
volumes:
Expand Down
6 changes: 6 additions & 0 deletions .devcontainer/init-nginx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# init nginx config dir
if [ "$(ls -A /etc/nginx)" = "" ]; then
echo "Initialing Nginx config dir"
cp -rp /etc/nginx.orig/* /etc/nginx/
echo "Initialed Nginx config dir"
fi
87 changes: 87 additions & 0 deletions .devcontainer/node-supervisor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash

# Configurable variables
SOURCE_FILE=/workspaces/nginx-ui/tmp/main
TARGET_PATH=/usr/local/bin/nginx-ui
CONFIG_FILE=/etc/nginx-ui/app.ini

# init nginx
./.devcontainer/init-nginx.sh

LOG_PREFIX="[Supervisor]"

# Debug initial state
echo "$LOG_PREFIX Starting supervisor with:"
echo "$LOG_PREFIX SOURCE_FILE: $SOURCE_FILE"
echo "$LOG_PREFIX TARGET_PATH: $TARGET_PATH"
echo "$LOG_PREFIX CONFIG_FILE: $CONFIG_FILE"

# Wait for initial file creation
while [[ ! -f "$SOURCE_FILE" ]]; do
echo "$LOG_PREFIX Waiting for $SOURCE_FILE to be created..."
sleep 1
done

# Initial copy and start
echo "$LOG_PREFIX Initial file detected, starting service..."
cp -fv "$SOURCE_FILE" "$TARGET_PATH"
chmod +x "$TARGET_PATH"
pkill -x nginx-ui || echo "$LOG_PREFIX No existing process to kill"
nohup "$TARGET_PATH" -config "$CONFIG_FILE" > /proc/1/fd/1 2>&1 &

# Use proper field separation for inotify output
inotifywait -m -e close_write,moved_to,create,delete \
--format "%T|%w%f|%e" \
--timefmt "%F-%H:%M:%S" \
"$(dirname "$SOURCE_FILE")" |
while IFS='|' read -r TIME FILE EVENT; do
echo "$LOG_PREFIX [${TIME}] Event: ${EVENT} - ${FILE}"

# Handle atomic save operations
if [[ "$FILE" =~ .*-tmp-umask$ ]] || [[ "$EVENT" == "DELETE" ]]; then
echo "$LOG_PREFIX Detected build intermediate file, checking main..."
sleep 0.3 # Allow atomic replace completion

if [[ -f "$SOURCE_FILE" ]]; then
echo "$LOG_PREFIX Valid main file detected after build"
FILE="$SOURCE_FILE"
else
echo "$LOG_PREFIX Main file missing after build operation"
continue
fi
fi

if [[ "$FILE" == "$SOURCE_FILE" ]]; then
# Stability checks
echo "$LOG_PREFIX File metadata:"
ls -l "$FILE"
file "$FILE"

# Wait for file stability with retries
retries=5
while ((retries-- > 0)); do
if file "$FILE" | grep -q "executable"; then
break
fi
echo "$LOG_PREFIX Waiting for valid executable (${retries} retries left)..."
sleep 1
done

if ((retries <= 0)); then
echo "$LOG_PREFIX ERROR: File validation failed after 5 retries"
continue
fi

# Copy and restart service
echo "$LOG_PREFIX Updating service..."
cp -fv "$FILE" "$TARGET_PATH"
chmod +x "$TARGET_PATH"

echo "$LOG_PREFIX Killing existing process..."
pkill -x nginx-ui || echo "$LOG_PREFIX No process to kill"

echo "$LOG_PREFIX Starting new process..."
nohup "$TARGET_PATH" -config "$CONFIG_FILE" > /proc/1/fd/1 2>&1 &
echo "$LOG_PREFIX Restart complete. New PID: $(pgrep nginx-ui)"
fi
done
6 changes: 1 addition & 5 deletions .devcontainer/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ if ! grep -q "zsh-autosuggestions" ~/.zshrc; then
fi

# init nginx config dir
if [ "$(ls -A /etc/nginx)" = "" ]; then
echo "Initialing Nginx config dir"
cp -rp /etc/nginx.orig/* /etc/nginx/
echo "Initialed Nginx config dir"
fi
./.devcontainer/init-nginx.sh

# install app dependencies
echo "Installing app dependencies"
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ app/.status_hash
.idea/deployment.xml
.idea/webServers.xml
.devcontainer/go-path
.devcontainer/nginx
.devcontainer/data
.devcontainer/casdoor.pem
28 changes: 8 additions & 20 deletions api/cluster/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"io"
"net/http"
"time"

"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/analytic"
"github.com/0xJacky/Nginx-UI/internal/cluster"
Expand All @@ -14,9 +18,6 @@ import (
"github.com/spf13/cast"
"github.com/uozi-tech/cosy"
"gorm.io/gorm"
"io"
"net/http"
"time"
)

func GetEnvironment(c *gin.Context) {
Expand Down Expand Up @@ -151,23 +152,10 @@ func EditEnvironment(c *gin.Context) {
}

func DeleteEnvironment(c *gin.Context) {
id := cast.ToUint64(c.Param("id"))
envQuery := query.Environment

env, err := envQuery.FirstByID(id)
if err != nil {
api.ErrHandler(c, err)
return
}
err = envQuery.DeleteByID(env.ID)
if err != nil {
api.ErrHandler(c, err)
return
}

go analytic.RestartRetrieveNodesStatus()

c.JSON(http.StatusNoContent, nil)
cosy.Core[model.Environment](c).
ExecutedHook(func(c *cosy.Ctx[model.Environment]) {
go analytic.RestartRetrieveNodesStatus()
}).Destroy()
}

func LoadEnvironmentFromSettings(c *gin.Context) {
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/StdDesign/StdDataDisplay/StdCurd.vue
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function handleBatchUpdated() {
v-if="!disableAdd && !inTrash"
type="link"
size="small"
@click="add"
@click="add()"
>
{{ $gettext('Add') }}
</AButton>
Expand Down
2 changes: 1 addition & 1 deletion app/src/version.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"2.0.0-rc.1","build_id":1,"total_build":375}
{"version":"2.0.0-rc.1","build_id":7,"total_build":381}
15 changes: 14 additions & 1 deletion app/src/views/environment/Environment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import BatchUpgrader from '@/views/environment/BatchUpgrader.vue'
import envColumns from '@/views/environment/envColumns'
import { message } from 'ant-design-vue'
const route = useRoute()
const curd = ref()
function loadFromSettings() {
environment.load_from_settings().then(() => {
Expand All @@ -20,6 +21,18 @@ const refUpgrader = ref()
function batchUpgrade() {
refUpgrader.value.open(selectedNodeIds, selectedNodes)
}
const inTrash = computed(() => {
return route.query.trash === 'true'
})
// const timer = setInterval(() => {
// curd.value.get_list()
// }, 10000)
// onUnmounted(() => {
// clearInterval(timer)
// })
</script>

<template>
Expand All @@ -43,7 +56,7 @@ function batchUpgrade() {

<BatchUpgrader ref="refUpgrader" />

<FooterToolBar>
<FooterToolBar v-if="!inTrash">
<ATooltip
:title="$gettext('Please select at least one node to upgrade')"
placement="topLeft"
Expand Down
8 changes: 4 additions & 4 deletions app/src/views/environment/envColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ const columns: Column[] = [{
placeholder: () => 'https://10.0.0.1:9000',
},
},
width: 300,
width: 260,
}, {
title: () => $gettext('Version'),
dataIndex: 'version',
pithy: true,
width: 150,
width: 120,
}, {
title: () => 'NodeSecret',
dataIndex: 'token',
Expand Down Expand Up @@ -65,7 +65,7 @@ const columns: Column[] = [{
},
sorter: true,
pithy: true,
width: 200,
width: 120,
}, {
title: () => $gettext('Enabled'),
dataIndex: 'enabled',
Expand All @@ -85,7 +85,7 @@ const columns: Column[] = [{
},
sorter: true,
pithy: true,
width: 150,
width: 120,
}, {
title: () => $gettext('Updated at'),
dataIndex: 'updated_at',
Expand Down
7 changes: 4 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package main

import (
"errors"
"flag"
"fmt"
"net/http"
"time"

"github.com/0xJacky/Nginx-UI/internal/kernel"
"github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/router"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"github.com/jpillora/overseer"
"errors"
"github.com/uozi-tech/cosy"
cKernel "github.com/uozi-tech/cosy/kernel"
"github.com/uozi-tech/cosy/logger"
cRouter "github.com/uozi-tech/cosy/router"
cSettings "github.com/uozi-tech/cosy/settings"
"net/http"
"time"
)

func Program(confPath string) func(state overseer.State) {
Expand Down
2 changes: 1 addition & 1 deletion model/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Environment struct {
Name string `json:"name"`
URL string `json:"url"`
Token string `json:"token"`
Enabled bool `json:"enabled" gorm:"default:true"`
Enabled bool `json:"enabled" gorm:"default:false"`
}

func (e *Environment) GetUrl(uri string) (decodedUri string, err error) {
Expand Down

0 comments on commit b090564

Please sign in to comment.