update files for agent, deps upgrade

This commit is contained in:
yusing 2025-02-10 09:36:05 +08:00
parent 9626b65593
commit ecb89f80a0
12 changed files with 250 additions and 141 deletions

View file

@ -42,6 +42,9 @@ GODOXY_HTTPS_ADDR=:443
# API listening address # API listening address
GODOXY_API_ADDR=127.0.0.1:8888 GODOXY_API_ADDR=127.0.0.1:8888
# Frontend listening port
GODOXY_FRONTEND_PORT=3000
# Prometheus Metrics # Prometheus Metrics
GODOXY_PROMETHEUS_ENABLED=true GODOXY_PROMETHEUS_ENABLED=true

View file

@ -0,0 +1,12 @@
name: Docker Image CI (agent)
on:
push:
tags: ["*"]
jobs:
call-main-workflow:
uses: ./.github/workflows/docker-image.yml
with:
make_args: "agent=1"
image_name: ${{ github.repository }}-agent

View file

@ -0,0 +1,9 @@
name: Docker Image CI (main)
on:
push:
tags: ["*"]
jobs:
call-main-workflow:
uses: ./.github/workflows/docker-image.yml

View file

@ -1,128 +1,139 @@
name: Docker Image CI name: Docker Image CI
on: on:
push: workflow_call:
tags: ["*"] inputs:
make_args:
description: "Arguments to pass to make"
type: string
required: false
default: ""
image_name:
description: "Image name"
type: string
required: false
default: ${{ github.repository }}
env: env:
REGISTRY: ghcr.io REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }} IMAGE_NAME: ${{ inputs.image_name }}
jobs: jobs:
build: build:
name: Build multi-platform Docker image name: Build multi-platform Docker image
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
packages: write packages: write
id-token: write id-token: write
attestations: write attestations: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: platform:
- linux/amd64 - linux/amd64
# - linux/arm/v6 # - linux/arm/v6
# - linux/arm/v7 # - linux/arm/v7
- linux/arm64 - linux/arm64
steps: steps:
- name: Prepare - name: Prepare
run: | run: |
platform=${{ matrix.platform }} platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Docker meta - name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Login to registry - name: Login to registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push by digest - name: Build and push by digest
id: build id: build
uses: docker/build-push-action@v6 uses: docker/build-push-action@v6
with: with:
platforms: ${{ matrix.platform }} platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
build-args: | build-args: |
VERSION=${{ github.ref_name }} VERSION=${{ github.ref_name }}
MAKE_ARGS=${{ inputs.make_args }}
- name: Generate artifact attestation - name: Generate artifact attestation
uses: actions/attest-build-provenance@v1 uses: actions/attest-build-provenance@v1
with: with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.build.outputs.digest }} subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true push-to-registry: true
- name: Export digest - name: Export digest
run: | run: |
mkdir -p /tmp/digests mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}" digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}" touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest - name: Upload digest
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: digests-${{ env.PLATFORM_PAIR }} name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/* path: /tmp/digests/*
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 1
merge: merge:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
needs: needs:
- build - build
permissions: permissions:
contents: read contents: read
packages: write packages: write
id-token: write id-token: write
steps: steps:
- name: Download digests - name: Download digests
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
path: /tmp/digests path: /tmp/digests
pattern: digests-* pattern: digests-*
merge-multiple: true merge-multiple: true
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Docker meta - name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Login to registry - name: Login to registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push - name: Create manifest list and push
id: push id: push
working-directory: /tmp/digests working-directory: /tmp/digests
run: | run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect image - name: Inspect image
run: | run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}

5
.gitignore vendored
View file

@ -29,4 +29,7 @@ mtrace.json
test.Dockerfile test.Dockerfile
node_modules/ node_modules/
tsconfig.tsbuildinfo tsconfig.tsbuildinfo
!agent.compose.yml
!agent/pkg/**

View file

@ -1,5 +1,5 @@
# Stage 1: Builder # Stage 1: Builder
FROM golang:1.23.5-alpine AS builder FROM golang:1.23.6-alpine AS builder
HEALTHCHECK NONE HEALTHCHECK NONE
# package version does not matter # package version does not matter
@ -21,18 +21,19 @@ COPY Makefile /src/
COPY cmd /src/cmd COPY cmd /src/cmd
COPY internal /src/internal COPY internal /src/internal
COPY pkg /src/pkg COPY pkg /src/pkg
COPY agent /src/agent
ARG VERSION ARG VERSION
ENV VERSION=${VERSION} ENV VERSION=${VERSION}
ARG BUILD_FLAGS ARG MAKE_ARGS
ENV BUILD_FLAGS=${BUILD_FLAGS} ENV MAKE_ARGS=${MAKE_ARGS}
RUN --mount=type=cache,target="/go/pkg/mod" \ RUN --mount=type=cache,target="/go/pkg/mod" \
--mount=type=cache,target="/root/.cache/go-build" \ --mount=type=cache,target="/root/.cache/go-build" \
make build && \ make ${MAKE_ARGS} build create-docker-entrypoint && \
mkdir -p /app/error_pages /app/certs && \ mv bin /app/ && \
mv bin/godoxy /app/godoxy mkdir -p /app/error_pages /app/certs
# Stage 2: Final image # Stage 2: Final image
FROM scratch FROM scratch
@ -53,12 +54,7 @@ COPY config.example.yml /app/config/config.yml
COPY --from=builder /etc/ssl/certs /etc/ssl/certs COPY --from=builder /etc/ssl/certs /etc/ssl/certs
ENV DOCKER_HOST=unix:///var/run/docker.sock ENV DOCKER_HOST=unix:///var/run/docker.sock
ENV GODOXY_DEBUG=0
EXPOSE 80
EXPOSE 8888
EXPOSE 443
WORKDIR /app WORKDIR /app
CMD ["/app/godoxy"] CMD ["/app/entrypoint.sh"]

View file

@ -4,16 +4,27 @@ export GOOS = linux
LDFLAGS = -X github.com/yusing/go-proxy/pkg.version=${VERSION} LDFLAGS = -X github.com/yusing/go-proxy/pkg.version=${VERSION}
ifeq ($(agent), 1)
NAME = godoxy-agent
CMD_PATH = ./agent/cmd
else
NAME = godoxy
CMD_PATH = ./cmd
endif
ifeq ($(trace), 1) ifeq ($(trace), 1)
debug = 1 debug = 1
GODOXY_TRACE ?= 1 GODOXY_TRACE ?= 1
endif endif
ifeq ($(debug), 1) ifeq ($(debug), 1)
CGO_ENABLED = 0 CGO_ENABLED = 0
GODOXY_DEBUG = 1 GODOXY_DEBUG = 1
BUILD_FLAGS = -tags production BUILD_FLAGS ?= -tags production
else ifeq ($(pprof), 1) endif
ifeq ($(pprof), 1)
CGO_ENABLED = 1 CGO_ENABLED = 1
GODEBUG = gctrace=1 inittrace=1 schedtrace=3000 GODEBUG = gctrace=1 inittrace=1 schedtrace=3000
GORACE = log_path=logs/pprof strip_path_prefix=$(shell pwd)/ GORACE = log_path=logs/pprof strip_path_prefix=$(shell pwd)/
@ -23,12 +34,14 @@ else ifeq ($(pprof), 1)
else else
CGO_ENABLED = 0 CGO_ENABLED = 0
LDFLAGS += -s -w LDFLAGS += -s -w
BUILD_FLAGS = -pgo=auto -tags production BUILD_FLAGS = -pgo=auto -tags production
DOCKER_TAG = latest DOCKER_TAG = latest
endif endif
BUILD_FLAGS += -ldflags='$(LDFLAGS)' BUILD_FLAGS += -ldflags='$(LDFLAGS)'
export NAME
export CMD_PATH
export CGO_ENABLED export CGO_ENABLED
export GODOXY_DEBUG export GODOXY_DEBUG
export GODOXY_TRACE export GODOXY_TRACE
@ -45,14 +58,14 @@ get:
build: build:
mkdir -p bin mkdir -p bin
go build ${BUILD_FLAGS} -o bin/godoxy ./cmd go build ${BUILD_FLAGS} -o bin/${NAME} ${CMD_PATH}
if [ $(shell id -u) -eq 0 ]; \ if [ $(shell id -u) -eq 0 ]; \
then setcap CAP_NET_BIND_SERVICE=+eip bin/godoxy; \ then setcap CAP_NET_BIND_SERVICE=+eip bin/${NAME}; \
else sudo setcap CAP_NET_BIND_SERVICE=+eip bin/godoxy; \ else sudo setcap CAP_NET_BIND_SERVICE=+eip bin/${NAME}; \
fi fi
run: run:
[ -f .env ] && godotenv -f .env go run ${BUILD_FLAGS} ./cmd [ -f .env ] && godotenv -f .env go run ${BUILD_FLAGS} ${CMD_PATH}
mtrace: mtrace:
bin/godoxy debug-ls-mtrace > mtrace.json bin/godoxy debug-ls-mtrace > mtrace.json
@ -76,18 +89,25 @@ push-docker-io:
BUILDER=build docker buildx build \ BUILDER=build docker buildx build \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
-f Dockerfile \ -f Dockerfile \
-t docker.io/yusing/godoxy-nightly:${DOCKER_TAG} \ -t docker.io/yusing/${NAME}-nightly:${DOCKER_TAG} \
-t docker.io/yusing/godoxy-nightly:${VERSION}-${BUILD_DATE} \ -t docker.io/yusing/${NAME}-nightly:${VERSION}-${BUILD_DATE} \
--build-arg VERSION="${VERSION}-nightly-${BUILD_DATE}" \ --build-arg VERSION="${VERSION}-nightly-${BUILD_DATE}" \
--build-arg BUILD_FLAGS="${BUILD_FLAGS}" \ --build-arg BUILD_FLAGS="${BUILD_FLAGS}" \
--build-arg MAKE_ARGS="agent=${agent}" \
--push . --push .
build-docker: build-docker:
docker build -t godoxy-nightly \ docker build -t ${NAME}-nightly \
--build-arg VERSION="${VERSION}-nightly-${BUILD_DATE}" \ --build-arg VERSION="${VERSION}-nightly-${BUILD_DATE}" \
--build-arg BUILD_FLAGS="${BUILD_FLAGS}" \ --build-arg BUILD_FLAGS="${BUILD_FLAGS}" \
--build-arg MAKE_ARGS="agent=${agent}" \
. .
create-docker-entrypoint:
printf '#!/bin/sh\n/app/${NAME}\n' > bin/entrypoint.sh
chmod +x bin/entrypoint.sh
# To generate schema # To generate schema
# comment out this part from typescript-json-schema.js#L884 # comment out this part from typescript-json-schema.js#L884
# #

View file

@ -59,11 +59,21 @@ For full documentation, check out **[Wiki](https://github.com/yusing/go-proxy/wi
## Prerequisites ## Prerequisites
Setup DNS Records point to machine which runs `GoDoxy`, e.g. 1. Setup DNS Records point to machine which runs `GoDoxy`, e.g.
- A Record: `*.y.z` -> `10.0.10.1` - A Record: `*.y.z` -> `10.0.10.1`
- AAAA Record: `*.y.z` -> `::ffff:a00:a01` - AAAA Record: `*.y.z` -> `::ffff:a00:a01`
2. Create shell alias:
```shell
# for main server
alias godoxy="docker exec godoxy /app/godoxy"
# for agent server
alias godoxy-agent="docker exec godoxy-agent /app/godoxy-agent"
```
## Setup ## Setup
**NOTE:** GoDoxy is designed to be (and only works when) running in `host` network mode, do not change it. To change listening ports, modify `.env`. **NOTE:** GoDoxy is designed to be (and only works when) running in `host` network mode, do not change it. To change listening ports, modify `.env`.

12
agent.compose.yml Normal file
View file

@ -0,0 +1,12 @@
services:
godoxy-agent:
image: ghcr.io/yusing/godoxy-agent:latest
container_name: godoxy-agent
restart: always
network_mode: host # do not change this
environment:
GODOXY_AGENT_NAME: "agent-1"
GODOXY_AGENT_PORT: "8890"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./certs:/app/certs # store Agent CA cert and Agent SSL cert

View file

@ -4,14 +4,17 @@ services:
image: ghcr.io/yusing/go-proxy-frontend:latest image: ghcr.io/yusing/go-proxy-frontend:latest
container_name: godoxy-frontend container_name: godoxy-frontend
restart: unless-stopped restart: unless-stopped
network_mode: host network_mode: host # do not change this
env_file: .env env_file: .env
depends_on: depends_on:
- app - app
environment:
PORT: ${GODOXY_FRONTEND_PORT:-3000}
# modify below to fit your needs # modify below to fit your needs
labels: labels:
proxy.aliases: godoxy proxy.aliases: godoxy
proxy.godoxy.port: 3000 proxy.godoxy.port: ${GODOXY_FRONTEND_PORT:-3000}
# proxy.godoxy.middlewares.cidr_whitelist: | # proxy.godoxy.middlewares.cidr_whitelist: |
# status: 403 # status: 403
# message: IP not allowed # message: IP not allowed
@ -24,7 +27,7 @@ services:
image: ghcr.io/yusing/go-proxy:latest image: ghcr.io/yusing/go-proxy:latest
container_name: godoxy container_name: godoxy
restart: always restart: always
network_mode: host network_mode: host # do not change this
env_file: .env env_file: .env
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock

2
go.mod
View file

@ -1,6 +1,6 @@
module github.com/yusing/go-proxy module github.com/yusing/go-proxy
go 1.23.5 go 1.23.6
require ( require (
github.com/PuerkitoBio/goquery v1.10.1 github.com/PuerkitoBio/goquery v1.10.1

View file

@ -1,6 +1,36 @@
GoDoxy v0.9.1 expected changes ## GoDoxy v0.10.0
- Support Ntfy notifications ### Agent Mode
- Prometheus metrics server now inside API server under `/v1/metrics`
- `GODOXY_PROMETHEUS_ADDR` removed listen only on Agent API server, authenticate with mTLS. Maintain secure connection between GoDoxy main and GoDoxy agent server
- `GODOXY_PROMETHEUS_ENABLED` added, default `false`
Main benefits:
- No more exposing docker socket: drops the need of `docker-socket-proxy`
- No more exposing app ports: fewer attack surface
```yaml
services:
app:
...
# ports: # this part is not needed on agent server
# - 6789
```
- Secure: no one can connect to it except GoDoxy main server because of mTLS
- Fetch info from agent server, e.g. CPU usage, Memory usage, container list, container logs, etc... (to be ready for beszel and dockge like features in WebUI)
### How to setup
1. Agent server generates CA cert, SSL certificate and Client certificate on first run.
2. Follow the output on screen to run `godoxy new-agent <ip>:<port> ...` on GoDoxy main server to store generated certs
3. Add config output to GoDoxy main server in `config.yml` under `providers.agents`
```yaml
providers:
agents:
- 12.34.5.6:8889
```
### How does it work
1. Main server and agent server negotiate mTLS
2. Agent server verify main server's client cert and check if server version matches agent version
3. Agent server now acts as a http proxy and docker socket proxy