15 Commits

Author SHA1 Message Date
Ducky SSH User
999a595b9c Remove jq dependency from release workflow
Some checks failed
Build and Release / build (push) Failing after 12s
- Replace jq with grep for parsing JSON responses
- Use curl -w to capture HTTP response codes
- Improve error handling and logging
- Check HTTP response codes for upload success
- Should work on runners without jq installed
- Fixes 'command not found' error on release creation
2025-12-20 06:28:25 +00:00
Ducky SSH User
e6f705486d Fix git tag checkout in Gitea Actions workflow
Some checks failed
Build and Release / build (push) Failing after 10s
- For tags: fetch with explicit ref mapping to refs/tags/
- For branches: fetch with explicit ref mapping to refs/remotes/origin/
- Properly checkout tag refs using refs/tags/ path
- Fixes 'pathspec did not match any file(s)' error on tag builds
2025-12-20 06:24:56 +00:00
Ducky SSH User
66734923cb Update GITEA_SETUP.md for binary-only CI/CD pipeline
Some checks failed
Build and Release / build (push) Failing after 1s
- Clarify Docker is not required for CI/CD
- Note that Docker images are built manually
- Simplify troubleshooting section
- Remove Docker setup instructions from setup guide
- Link to manual Docker build documentation
2025-12-20 06:21:37 +00:00
Ducky SSH User
48d2d7f83d Update RELEASE.md to reflect binary-only CI/CD pipeline
- Remove references to Docker image CI/CD builds
- Clarify Docker images are built manually or with docker-compose
- Simplify deployment options (binaries, Docker, Docker Compose)
- Update troubleshooting to focus on binary releases
- Remove Docker-specific troubleshooting steps
- Keep Dockerfiles for manual builds
2025-12-20 06:21:18 +00:00
Ducky SSH User
444bda7263 Remove Docker-specific runner documentation
- Remove GITEA_RUNNER_DOCKER.md (no longer needed)
- Docker builds removed from CI/CD pipeline
- Dockerfiles and docker-compose remain for manual builds
2025-12-20 06:20:35 +00:00
Ducky SSH User
99fc1a28ad Simplify CI/CD pipeline to focus on binary releases only
- Remove docker-build job entirely
- Keep focus on cross-platform binary builds (Linux, macOS, Windows)
- Generate SHA256 checksums for all binaries
- Upload binaries and checksums to Gitea releases
- Keep Dockerfiles and docker-compose for manual builds
- Much simpler and more reliable workflow
2025-12-20 06:20:32 +00:00
Ducky SSH User
2075cd2901 Fix Docker builds in Gitea runner with proper Docker-in-Docker detection
- Use 'docker info' instead of 'command -v docker' for reliable detection
- Add 30-second wait for Docker daemon startup (for DinD startup delay)
- Improve Docker build step with better error handling
- Build Docker images when available, skip gracefully if not
- Add comprehensive GITEA_RUNNER_DOCKER.md setup guide
- Document Docker socket mounting for runners
- Include troubleshooting and complete docker-compose example
2025-12-20 06:16:10 +00:00
Ducky SSH User
f4ec33fe53 Update GITEA_SETUP.md with optional Docker configuration
- Document Docker installation on runner for image builds
- Clarify that Docker is optional (not required for binary builds)
- Add instructions for running the runner user with Docker permissions
- Update troubleshooting section with Docker-specific guidance
- Explain graceful handling when Docker is not available
- Add Docker installation link in support section
2025-12-20 06:13:53 +00:00
Ducky SSH User
3080cb1e87 Make Docker build optional in Gitea Actions workflow
- Check if Docker is available before attempting to use it
- Skip Docker image builds gracefully if Docker is not installed
- Provide helpful instructions for enabling Docker support
- Add error handling for Docker build failures
- Allow workflow to succeed even without Docker
- Binary builds will still complete successfully
2025-12-20 06:13:34 +00:00
Ducky SSH User
89fb5bbf7d Fix git checkout for tag builds in Gitea Actions
Some checks failed
Build and Release / build (push) Failing after 0s
Build and Release / docker-build (push) Failing after 0s
- Add conditional logic to handle tag vs branch checkouts
- Tags don't exist on 'origin/tagname' so use direct checkout
- Branches can be checked out as 'origin/branchname'
- Fixes 'fatal: origin/v0.0.1 is not a commit' error
2025-12-20 06:09:43 +00:00
Ducky SSH User
6c6bc0d57f Add Gitea server setup guide
Some checks failed
Build and Release / build (push) Failing after 0s
Build and Release / docker-build (push) Failing after 0s
- Document GITEA_TOKEN secret configuration
- Provide API token creation instructions
- Include Gitea Actions enablement steps
- Add runner verification and setup instructions
- Include testing procedures for the complete setup
- Add troubleshooting for common configuration issues
- Explain the workflow execution flow after setup
2025-12-20 06:06:21 +00:00
Ducky SSH User
3dbd60ac27 Update RELEASE.md with Gitea Actions setup and troubleshooting
- Add detailed Gitea configuration instructions
- Document how to create and configure API tokens as repository secrets
- Explain the automated release workflow step-by-step
- List all artifacts created during release (binaries, checksums, Docker images)
- Add comprehensive troubleshooting section with solutions
- Include workflow monitoring and log inspection guide
- Add information about manual trigger testing
2025-12-20 06:06:04 +00:00
Ducky SSH User
5664105111 Fix Gitea Actions workflow for compatibility
- Replace GitHub Actions with native Gitea Actions syntax
- Remove dependency on Node.js-based actions
- Use manual git checkout instead of actions/checkout
- Download Go directly instead of using actions/setup-go
- Use native curl/bash for release creation and uploads
- Support both main and master branch pushes
- Simplify Docker image building without external actions
- Add proper Gitea API token handling for releases
2025-12-20 06:05:29 +00:00
Ducky SSH User
b87c61ea99 Add Docker Compose quick reference guide
Some checks failed
Build and Release / build (push) Failing after 37s
Build and Release / docker-build (push) Failing after 1m13s
- Document common docker-compose commands
- Provide configuration examples
- Include troubleshooting section
- Add environment variables reference table
- Include production tips and best practices
2025-12-20 05:57:20 +00:00
Ducky SSH User
98ecc61624 Add docker-compose support with environment variable configuration
- Create docker-compose.yml with server and agent services
- Add environment variable support to Dockerfiles via entrypoint scripts
- Configure server with ADDR, PORT, USERNAME, PASSWORD vars
- Configure agent with SERVER, INTERVAL, AGENT_ID vars
- Add health check to server service for container orchestration
- Add service dependencies to ensure server starts before agent
- Create .dockerignore to optimize Docker builds
- Update QUICKSTART.md with Docker Compose instructions
- Support running server only, agent only, or full stack
- Support multiple agents with custom identifiers
2025-12-20 05:57:09 +00:00
9 changed files with 824 additions and 163 deletions

39
.dockerignore Normal file
View File

@@ -0,0 +1,39 @@
# Git
.git
.gitignore
.gitattributes
# Development
.vscode
.idea
*.swp
*.swo
*~
.DS_Store
# Build artifacts
bin/
dist/
*.o
*.a
*.so
# Dependencies
vendor/
# Documentation
*.md
RELEASE.md
README.md
QUICKSTART.md
AGENTS.md
# Other
docker-compose.yml
Dockerfile
Dockerfile.server
Dockerfile.agent
.dockerignore
.github
.gitea
scripts/

View File

@@ -3,6 +3,7 @@ name: Build and Release
on:
push:
branches:
- main
- master
tags:
- 'v*'
@@ -12,129 +13,138 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
run: |
cd $GITHUB_WORKSPACE
git init
git remote add origin ${{ github.server_url }}/${{ github.repository }}.git
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
# For tags, fetch the specific tag and checkout the commit it points to
git fetch origin ${{ github.ref }}:refs/tags/${{ github.ref_name }}
git checkout refs/tags/${{ github.ref_name }}
else
# For branches, fetch and checkout with tracking
git fetch origin ${{ github.ref_name }}:refs/remotes/origin/${{ github.ref_name }}
git checkout -b ${{ github.ref_name }} origin/${{ github.ref_name }}
fi
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.24.4'
run: |
wget https://go.dev/dl/go1.24.4.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.24.4.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
- name: Generate version
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${{ github.ref_name }}
else
VERSION=dev-${{ github.sha }}
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_ENV
- name: Build all binaries
run: |
export PATH=$PATH:/usr/local/go/bin
mkdir -p bin
# Generate templ first
go run github.com/a-h/templ/cmd/templ@latest generate
# Linux AMD64
echo "Building Linux AMD64..."
GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-server-linux-amd64 ./cmd/server
GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-agent-linux-amd64 ./cmd/agent
# Linux ARM64
echo "Building Linux ARM64..."
GOOS=linux GOARCH=arm64 go build -ldflags="-w -s" -o bin/nerd-monitor-server-linux-arm64 ./cmd/server
GOOS=linux GOARCH=arm64 go build -ldflags="-w -s" -o bin/nerd-monitor-agent-linux-arm64 ./cmd/agent
# macOS AMD64
echo "Building macOS AMD64..."
GOOS=darwin GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-server-darwin-amd64 ./cmd/server
GOOS=darwin GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-agent-darwin-amd64 ./cmd/agent
# macOS ARM64
echo "Building macOS ARM64..."
GOOS=darwin GOARCH=arm64 go build -ldflags="-w -s" -o bin/nerd-monitor-server-darwin-arm64 ./cmd/server
GOOS=darwin GOARCH=arm64 go build -ldflags="-w -s" -o bin/nerd-monitor-agent-darwin-arm64 ./cmd/agent
# Windows AMD64
echo "Building Windows AMD64..."
GOOS=windows GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-server-windows-amd64.exe ./cmd/server
GOOS=windows GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-agent-windows-amd64.exe ./cmd/agent
echo "Build complete! Files:"
ls -lh bin/
- name: Create checksums
run: |
cd bin
sha256sum * > SHA256SUMS
cd ..
echo "Checksums:"
cat bin/SHA256SUMS
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: binaries-${{ steps.version.outputs.version }}
path: bin/
retention-days: 30
- name: Create Release
if: startsWith(github.ref, 'refs/tags/')
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Upload release assets
- name: Create Release and Upload
if: startsWith(github.ref, 'refs/tags/')
run: |
# This step uploads binaries to the release
# Note: Gitea Actions may require additional configuration
export GITEA_TOKEN="${{ secrets.GITEA_TOKEN }}"
export GITEA_URL="${{ github.server_url }}"
export REPO_OWNER="${{ github.repository_owner }}"
export REPO_NAME="${{ github.repository }}"
export REPO_NAME=${REPO_NAME#*/}
TAG=${{ github.ref_name }}
echo "Creating release for tag: $TAG"
echo "Repository: $REPO_OWNER/$REPO_NAME"
# Create release using Gitea API
echo "Creating new release..."
RESPONSE=$(curl -s -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"Release $TAG\",\"draft\":false,\"prerelease\":false}" \
"$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/releases")
# Extract release ID using grep instead of jq
RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*')
if [ -z "$RELEASE_ID" ]; then
echo "Failed to create release. Response:"
echo "$RESPONSE"
exit 1
fi
echo "Created release ID: $RELEASE_ID"
# Upload all binaries
echo "Uploading release artifacts..."
for file in bin/*; do
if [ -f "$file" ]; then
echo "Uploading $file to release"
filename=$(basename "$file")
echo " Uploading: $filename"
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-F "attachment=@$file" \
"$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/releases/$RELEASE_ID/assets")
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -n 1)
if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then
echo " ✓ $filename uploaded (HTTP $HTTP_CODE)"
else
echo " ✗ Failed to upload $filename (HTTP $HTTP_CODE)"
echo "Response: $(echo "$UPLOAD_RESPONSE" | head -n -1)"
fi
fi
done
docker-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Generate version
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
else
VERSION=dev-${{ github.sha }}
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Build and push server image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.server
push: false
outputs: type=docker,dest=/tmp/nerd-monitor-server.tar
tags: |
nerd-monitor-server:latest
nerd-monitor-server:${{ steps.version.outputs.version }}
- name: Build and push agent image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.agent
push: false
outputs: type=docker,dest=/tmp/nerd-monitor-agent.tar
tags: |
nerd-monitor-agent:latest
nerd-monitor-agent:${{ steps.version.outputs.version }}
- name: Upload Docker images
uses: actions/upload-artifact@v4
with:
name: docker-images-${{ steps.version.outputs.version }}
path: /tmp/nerd-monitor-*.tar
retention-days: 30
echo ""
echo "Release completed!"
echo "View at: $GITEA_URL/$REPO_OWNER/$REPO_NAME/releases/tag/$TAG"

158
DOCKER_COMPOSE.md Normal file
View File

@@ -0,0 +1,158 @@
# Docker Compose Quick Reference
## Quick Start
### Full Stack (Server + Agent)
```bash
docker-compose up
```
Access dashboard: http://localhost:8080
Login: admin / admin
### Server Only
```bash
docker-compose up server
```
### Agent Only
```bash
SERVER=your-server:8080 docker-compose up agent
```
## Common Commands
```bash
# Start services in background
docker-compose up -d
# Stop all services
docker-compose down
# View logs
docker-compose logs -f
# View logs for specific service
docker-compose logs -f server
docker-compose logs -f agent
# Restart services
docker-compose restart
# Remove volumes/data
docker-compose down -v
# Rebuild images
docker-compose build --no-cache
```
## Configuration
### Change Server Credentials
Edit `docker-compose.yml`:
```yaml
environment:
USERNAME: "myuser"
PASSWORD: "mysecurepassword"
```
### Change Agent Reporting Interval
```yaml
environment:
INTERVAL: "30s" # Report every 30 seconds instead of 15
```
### Set Custom Agent ID
```yaml
environment:
AGENT_ID: "my-machine"
```
### Run Multiple Agents
```bash
# Terminal 1: Start server
docker-compose up server
# Terminal 2: Run agent 1
docker-compose run --name agent1 -e AGENT_ID=machine1 agent
# Terminal 3: Run agent 2
docker-compose run --name agent2 -e AGENT_ID=machine2 agent
```
## Docker Commands
### View Running Containers
```bash
docker-compose ps
```
### Execute Commands in Container
```bash
# Connect to server
docker-compose exec server sh
# View server config
docker-compose exec server ps aux
```
### View Resource Usage
```bash
docker stats
```
## Troubleshooting
### Agent can't connect to server
```bash
# Check if server is running and healthy
docker-compose ps
# Check server logs
docker-compose logs server
# Check if containers are on same network
docker network inspect nerd-monitor
```
### Clear Everything and Start Fresh
```bash
docker-compose down -v
docker-compose build --no-cache
docker-compose up
```
### Port Already in Use
If port 8080 is already in use, edit `docker-compose.yml`:
```yaml
ports:
- "8090:8080" # Maps host port 8090 to container port 8080
```
## Environment Variables Reference
### Server
| Variable | Default | Description |
|----------|---------|-------------|
| ADDR | 0.0.0.0 | Bind address |
| PORT | 8080 | Server port |
| USERNAME | admin | Admin username |
| PASSWORD | admin | Admin password |
### Agent
| Variable | Default | Description |
| SERVER | server:8080 | Server address |
| INTERVAL | 15s | Reporting interval |
| AGENT_ID | (auto) | Agent identifier |
## Production Tips
1. **Change credentials**: Update USERNAME and PASSWORD in docker-compose.yml
2. **Use external volumes**: Add volume mounts for data persistence
3. **Set resource limits**: Uncomment resource limits in docker-compose.yml
4. **Enable restart policies**: Already set to `unless-stopped`
5. **Use environment files**: Create `.env` file for sensitive data:
```bash
USERNAME=myuser
PASSWORD=mysecurepass
```
Then in docker-compose.yml: `env_file: .env`

View File

@@ -29,6 +29,17 @@ COPY --from=builder /app/nerd-monitor-agent .
RUN addgroup -D appgroup && adduser -D appuser -G appgroup
USER appuser
# Create entrypoint script to handle environment variables
RUN echo '#!/bin/sh\n\
SERVER=${SERVER:-localhost:8080}\n\
INTERVAL=${INTERVAL:-15s}\n\
AGENT_ID=${AGENT_ID:-}\n\
if [ -z "$AGENT_ID" ]; then\n\
exec ./nerd-monitor-agent --server "$SERVER" --interval "$INTERVAL"\n\
else\n\
exec ./nerd-monitor-agent --server "$SERVER" --interval "$INTERVAL" --id "$AGENT_ID"\n\
fi\n\
' > /app/entrypoint.sh && chmod +x /app/entrypoint.sh
# Run the agent
ENTRYPOINT ["./nerd-monitor-agent"]
CMD ["--server", "localhost:8080"]
ENTRYPOINT ["/app/entrypoint.sh"]

View File

@@ -43,6 +43,14 @@ EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:8080/login || exit 1
# Create entrypoint script to handle environment variables
RUN echo '#!/bin/sh\n\
ADDR=${ADDR:-0.0.0.0}\n\
PORT=${PORT:-8080}\n\
USERNAME=${USERNAME:-admin}\n\
PASSWORD=${PASSWORD:-admin}\n\
exec ./nerd-monitor-server -addr "$ADDR" -port "$PORT" -username "$USERNAME" -password "$PASSWORD"\n\
' > /app/entrypoint.sh && chmod +x /app/entrypoint.sh
# Run the server
ENTRYPOINT ["./nerd-monitor-server"]
CMD ["-addr", "0.0.0.0", "-port", "8080"]
ENTRYPOINT ["/app/entrypoint.sh"]

164
GITEA_SETUP.md Normal file
View File

@@ -0,0 +1,164 @@
# Gitea Actions Setup - Server Configuration Checklist
This document outlines the changes needed on your Gitea server to make the CI/CD pipeline work.
## What You Need to Do
### 1. Add GITEA_TOKEN Secret to Repository
1. **Log into Gitea** with your user account
2. **Navigate to** your nerd-monitor repository
3. **Go to Settings → Secrets**
4. **Create a new secret**:
- Name: `GITEA_TOKEN`
- Value: [Your Gitea API token - see below for how to create]
5. **Save the secret**
### 2. Create an API Token (if you haven't already)
1. **Log into Gitea** with your user account
2. **Go to Settings → Applications**
3. **Click "Generate New Token"**
4. **Fill in the form**:
- Token Name: `release-automation`
- Scopes: Select at least `repo` (full repository access)
5. **Click "Generate"**
6. **Copy the token immediately** (you won't see it again)
7. **Use this token** for the secret in step 1
### 3. Verify Gitea Actions is Enabled (Server Admin)
These steps require SSH access to your Gitea server:
```bash
# SSH into your Gitea server
ssh user@your-gitea-server
# Edit the Gitea configuration
sudo vi /etc/gitea/app.ini
# Verify or add this section:
[actions]
ENABLED = true
# Save and exit (Esc, :wq, Enter)
# Restart Gitea for changes to take effect
sudo systemctl restart gitea
```
### 4. Verify Your Runner is Online (Server Admin)
1. **Log into Gitea** as admin
2. **Go to Administration → Actions → Runners**
3. **Verify** at least one runner is listed and shows as "Online" or "Idle"
4. If no runners:
- You need to set up a Gitea Actions runner on a machine with Docker and Go
- See "Setting Up a Runner" below
## Setting Up a Runner (if needed)
If you don't have any runners yet, you need to set one up. This can be on the Gitea server itself or any machine with Docker and Go.
### Quick Runner Setup
1. **On your Gitea server or runner machine**:
```bash
# Download the Gitea Actions runner
wget https://github.com/gitea/act_runner/releases/download/v0.6.10/act_runner-0.6.10-linux-amd64
chmod +x act_runner-0.6.10-linux-amd64
# Register the runner with your Gitea instance
./act_runner-0.6.10-linux-amd64 register \
--instance https://git.nerdnest.dev \
--token <your-runner-token>
# Run the runner in the background
./act_runner-0.6.10-linux-amd64 daemon &
```
To get a runner token:
1. Log into Gitea as **admin**
2. Go to **Administration → Actions → Runners**
3. Click **Create new runner**
4. Follow the registration steps
### Installing Docker on the Runner (Optional)
Docker is **not required** for the CI/CD pipeline. Binary builds work without Docker.
If you want to manually build Docker images:
```bash
# Build server image
docker build -t nerd-monitor-server -f Dockerfile.server .
# Build agent image
docker build -t nerd-monitor-agent -f Dockerfile.agent .
# Or use docker-compose for both
docker-compose build
docker-compose up
```
## What Happens Next
Once you've set everything up:
1. **Every push to main/master** triggers the build job:
- Compiles all platform binaries (Linux, macOS, Windows)
- Creates SHA256 checksums
- Artifacts available for 30 days
2. **Every git tag push** (e.g., `v1.0.0`) triggers the full release:
- Does all of the above
- Creates a Gitea Release
- Uploads all binaries and checksums to the release (permanent storage)
3. **Releases are available in**:
- Repository Releases tab in Gitea
- All binaries ready for download
- SHA256SUMS file for verification
Note: Docker images are not built automatically. To build Docker images manually, use:
```bash
docker build -t nerd-monitor-server -f Dockerfile.server .
docker build -t nerd-monitor-agent -f Dockerfile.agent .
# Or use docker-compose: docker-compose build
```
## Troubleshooting
### "docker: command not found" in workflow
- Docker support is not required - the workflow builds binaries without it
- Binary builds will always succeed
- Docker images must be built manually using: `docker build -f Dockerfile.server .`
- See QUICKSTART.md or DOCKER_COMPOSE.md for manual Docker build instructions
### "Action not found" error
- Make sure Gitea Actions is enabled
- Restart Gitea if you just enabled it: `sudo systemctl restart gitea`
### No runners available
- Runner must be registered: Administration → Actions → Runners
- Runner machine must have Go installed (1.24.4 or later)
- Docker is optional (for building Docker images)
- Check if runner is online in the UI
### "GITEA_TOKEN" not found
- Make sure the secret is named exactly `GITEA_TOKEN` (case-sensitive)
- Go to Settings → Secrets and verify it's there
- If it's there, try re-running the workflow
### Build fails with permission denied (Docker)
- Make sure the runner user has permission to run Docker commands
- On the runner machine: `sudo usermod -aG docker $USER`
- Logout and log back in for the group change to take effect
## Support
- Gitea Actions Docs: https://docs.gitea.io/en-us/actions/
- Act Runner Docs: https://gitea.com/gitea/act_runner
- Docker Installation: https://docs.docker.com/install/
- For issues with the workflow itself, check the Actions tab logs

View File

@@ -1,6 +1,45 @@
# Nerd Monitor - Quick Start Guide
## Building
## Docker Compose (Easiest)
The easiest way to get started is using Docker Compose:
### Run Full Stack (Server + Agent)
```bash
docker-compose up
```
Access the dashboard at: **http://localhost:8080**
### Run Server Only
```bash
docker-compose up server
```
### Run Agent Only (with external server)
```bash
SERVER=your-server:8080 docker-compose up agent
```
### Run Multiple Agents
```bash
# Start the server
docker-compose up -d server
# Run agents with custom IDs
docker-compose run --name agent1 -e AGENT_ID=machine1 agent
docker-compose run --name agent2 -e AGENT_ID=machine2 agent
```
### Docker Compose Configuration
Edit `docker-compose.yml` to customize:
- Server credentials: `USERNAME` and `PASSWORD`
- Agent reporting interval: `INTERVAL`
- Agent custom ID: `AGENT_ID`
## Native Binaries
### Building
```bash
# Build for current OS
@@ -111,6 +150,8 @@ Change these when starting the server:
./bin/nerd-monitor-server -username myuser -password mysecurepass
```
Or with Docker Compose, edit the `USERNAME` and `PASSWORD` environment variables in `docker-compose.yml`.
## Architecture
- **Server**: Web UI, API endpoint for agent stats, in-memory storage
@@ -134,3 +175,8 @@ Change these when starting the server:
- Verify server is running: `http://localhost:8080`
- Check firewall rules allow the agent port
- Ensure correct server address and port are specified
### Docker Compose agents can't reach server
- Verify server is healthy: `docker ps` (server should show healthy status)
- Check both containers are on the same network: `docker network inspect nerd-monitor`
- Ensure `SERVER` environment variable is set to `server:8080` (the service name)

View File

@@ -2,7 +2,7 @@
## Overview
This project uses **Gitea Actions** to automatically build and release binaries and Docker images when you push to the `master` branch or create a new tag.
This project uses **Gitea Actions** to automatically build and release cross-platform binaries when you push to the `master` branch or create a new tag.
## Automatic Release Pipeline
@@ -11,13 +11,12 @@ This project uses **Gitea Actions** to automatically build and release binaries
1. **Master Branch Push**: When you push to `master`, the workflow:
- Builds all platform binaries (Linux/macOS/Windows, amd64/arm64)
- Generates checksums (SHA256)
- Uploads artifacts for 30 days
- Builds Docker images (server & agent)
- Binaries are available as build artifacts for 30 days
2. **Tag Creation**: When you create a tag (e.g., `v1.0.0`), the workflow:
- Does all of the above
- Creates a GitHub Release
- Uploads all binaries and Docker images to the release
- Creates a Gitea Release
- Uploads all binaries and checksums to the release (permanent storage)
### Supported Platforms
@@ -26,56 +25,81 @@ Binaries are built for:
- **macOS**: amd64 (Intel), arm64 (Apple Silicon)
- **Windows**: amd64
Docker images are built for Linux containers.
### What Gets Built and Released
When you push a tag, the workflow automatically creates:
**Binaries** (10 files total):
- `nerd-monitor-server-linux-amd64` - Server for Linux x86_64
- `nerd-monitor-server-linux-arm64` - Server for Linux ARM64 (Raspberry Pi, etc.)
- `nerd-monitor-server-darwin-amd64` - Server for macOS Intel
- `nerd-monitor-server-darwin-arm64` - Server for macOS Apple Silicon
- `nerd-monitor-server-windows-amd64.exe` - Server for Windows
- `nerd-monitor-agent-linux-amd64` - Agent for Linux x86_64
- `nerd-monitor-agent-linux-arm64` - Agent for Linux ARM64
- `nerd-monitor-agent-darwin-amd64` - Agent for macOS Intel
- `nerd-monitor-agent-darwin-arm64` - Agent for macOS Apple Silicon
- `nerd-monitor-agent-windows-amd64.exe` - Agent for Windows
**Checksums**:
- `SHA256SUMS` - SHA256 checksums for all binaries (for verification)
## Workflow Configuration
The Gitea Actions workflow is defined in `.gitea/workflows/release.yml`
### Trigger Events
- Push to `master` branch
- Push of git tags (e.g., `v1.0.0`)
- Push to `master` or `main` branch (builds only, no release)
- Push of git tags (e.g., `v1.0.0`) - triggers full release with uploads
### Jobs
- `build`: Compiles all platform binaries and generates checksums
- `docker-build`: Builds Docker images for server and agent
### Creating a Release
## Creating a Release
#### Step 1: Create and Push a Tag
### Option 1: Automatic Release (Recommended)
1. Create a new tag:
```bash
# Create an annotated tag
git tag -a v1.0.0 -m "Release version 1.0.0"
# Push the tag to Gitea
git push origin v1.0.0
```
2. Gitea Actions will automatically:
- Build all binaries
- Create a release in Gitea
- Upload all artifacts
#### Step 2: Monitor the Workflow
3. View the release in Gitea: `Releases` tab on your repository
1. Go to your repository on Gitea
2. Click the **Actions** tab
3. You'll see the workflow running:
- `build` job: Compiles all binaries (5-10 minutes)
- `docker-build` job: Builds Docker images (5-10 minutes)
### Option 2: Manual Release Upload
#### Step 3: Verify the Release
If you need to manually upload binaries to Gitea:
Once the workflow completes:
```bash
# Set your Gitea token (create one in Gitea Settings → Applications → Generate Token)
export GITEA_TOKEN=your_token_here
1. Go to the **Releases** tab
2. You'll see a new release with:
- All platform binaries (Linux, macOS, Windows)
- SHA256SUMS file with checksums
- Docker image files (.tar)
# Build all binaries
make build-all
### What Gets Built and Released
# Upload to release
./scripts/upload-release.sh v1.0.0
```
When you push a tag, the workflow automatically:
Environment variables (optional):
- `GITEA_URL`: Gitea server URL (default: `https://git.nerdnest.dev`)
- `REPO_OWNER`: Repository owner (default: `ducky`)
- `REPO_NAME`: Repository name (default: `nerd-monitor`)
**Binaries** (10 files total):
- `nerd-monitor-server-linux-amd64` - Server for Linux x86_64
- `nerd-monitor-server-linux-arm64` - Server for Linux ARM64 (Raspberry Pi, etc.)
- `nerd-monitor-server-darwin-amd64` - Server for macOS Intel
- `nerd-monitor-server-darwin-arm64` - Server for macOS Apple Silicon
- `nerd-monitor-server-windows-amd64.exe` - Server for Windows
- `nerd-monitor-agent-linux-amd64` - Agent for Linux x86_64
- `nerd-monitor-agent-linux-arm64` - Agent for Linux ARM64
- `nerd-monitor-agent-darwin-amd64` - Agent for macOS Intel
- `nerd-monitor-agent-darwin-arm64` - Agent for macOS Apple Silicon
- `nerd-monitor-agent-windows-amd64.exe` - Agent for Windows
**Checksums**:
- `SHA256SUMS` - SHA256 checksums for all binaries (for verification)
## Local Building
@@ -94,51 +118,86 @@ make clean
Binaries are created in the `bin/` directory.
## Docker Images
## Docker Images (Manual Build)
Two Docker images are built:
Docker images are available but not built automatically by CI/CD. To build them manually:
### Server Image
```bash
docker pull nerd-monitor-server:latest
docker run -p 8080:8080 nerd-monitor-server
# Build server image
docker build -t nerd-monitor-server:latest -f Dockerfile.server .
# Build agent image
docker build -t nerd-monitor-agent:latest -f Dockerfile.agent .
# Or use Docker Compose
docker-compose build
# Or use Docker Compose to run both
docker-compose up
```
### Agent Image
```bash
docker pull nerd-monitor-agent:latest
docker run nerd-monitor-agent --server your-server:8080
```
See `DOCKER_COMPOSE.md` and `QUICKSTART.md` for detailed instructions.
## Gitea Configuration
### Enable Gitea Actions
### Prerequisites
1. SSH into your Gitea server
2. Edit `app.ini`:
```ini
Before the CI/CD pipeline can create releases automatically, you need to:
1. **Ensure Gitea Actions is enabled** on your Gitea server
2. **Create a Gitea API Token** with release permissions
3. **Add the token as an Actions secret** in your repository
### Setup Instructions
#### 1. Enable Gitea Actions (Server Admin)
SSH into your Gitea server and verify Actions is enabled:
```bash
# Edit the Gitea configuration
sudo vi /etc/gitea/app.ini
# Add or verify:
[actions]
ENABLED = true
```
3. Restart Gitea:
Then restart Gitea:
```bash
systemctl restart gitea
sudo systemctl restart gitea
```
### Create an API Token (for manual uploads)
#### 2. Create an API Token
1. Go to Settings → Applications
2. Click "Generate New Token"
3. Name it (e.g., "Release Upload")
4. Give it `repo` permissions
5. Copy the token
1. Log in to Gitea with your user account
2. Go to **Settings****Applications**
3. Click **Generate New Token**
4. Fill in:
- **Token Name**: `release-automation` (or any descriptive name)
- **Scopes**: Select `repo` (full repository access)
5. Click **Generate Token**
6. **Copy the token** (you won't be able to see it again)
Use it with the upload script:
```bash
./scripts/upload-release.sh v1.0.0 <your_token>
```
#### 3. Add Token as Repository Secret
## Release Files
1. Go to your repository on Gitea
2. Navigate to **Settings****Secrets**
3. Click **Add Secret**
4. Fill in:
- **Secret Name**: `GITEA_TOKEN`
- **Secret Value**: Paste the token you copied
5. Click **Save**
Now the workflow will be able to create releases automatically!
### Workflow Configuration
The Gitea Actions workflow is defined in `.gitea/workflows/release.yml`
### Trigger Events
- Push to `master` or `main` branch (builds only, no release)
- Push of git tags (e.g., `v1.0.0`) - triggers full release with uploads
Each release includes:
@@ -158,35 +217,93 @@ nerd-monitor-agent-windows-amd64.exe
SHA256SUMS (checksums for all binaries)
```
## Coolify Integration
## Deployment Options
If you want to use Coolify for deployment:
### Option 1: Use Pre-Built Binaries (Recommended)
Download the native binaries from the Releases tab and run directly:
- Smallest footprint
- No Docker required
- Easiest to deploy to existing machines
1. **For Server Deployment**:
- Use `Dockerfile.server` as the build context
- Coolify will auto-build on `master` branch pushes
- Deploy the server container to Coolify
### Option 2: Use Docker (Manual Build)
Build Docker images manually and deploy:
```bash
docker build -t nerd-monitor-server:latest -f Dockerfile.server .
docker run -p 8080:8080 nerd-monitor-server:latest
```
2. **For Agent Deployment**:
- Use `Dockerfile.agent` as the build context
- Deploy the agent container to machines that need monitoring
See `docker-compose.yml` for running both server and agent together.
### Option 3: Use Docker Compose
For quick development/testing with both server and agent:
```bash
docker-compose up
```
See `DOCKER_COMPOSE.md` and `QUICKSTART.md` for details.
## Troubleshooting
### Actions not running
- Ensure Gitea Actions is enabled on your server
- Check that your runner is available (`Settings → Actions`)
- Review action logs in the `Actions` tab
### Workflow Not Triggering
### Release not created
- Ensure the tag format matches semantic versioning (v1.0.0)
- Check workflow logs for build errors
- Verify Go 1.24.4 is available in the runner environment
**Problem**: I pushed a tag but the workflow didn't start
### Docker images not building
- Ensure Docker/Buildx is available in the runner
- Check the Dockerfile syntax
- Review build logs in the Actions tab
**Solutions**:
1. Check that the tag is pushed: `git push origin v1.0.0`
2. Verify Gitea Actions is enabled: Settings → Actions → Status should show "Enabled"
3. Check Actions tab for any error messages
4. Ensure your runner is online: Settings → Runners
### Token Authentication Failed
**Problem**: `"message":"Unauthorized"` or token-related errors in the logs
**Solutions**:
1. Verify the `GITEA_TOKEN` secret is set correctly: Repository → Settings → Secrets
2. Ensure the token has `repo` scope permissions
3. Token should not be expired - regenerate if needed
4. Double-check there are no extra spaces in the token
### Build Fails with "Go not found"
**Problem**: Workflow fails when trying to build, says Go is not available
**Solutions**:
1. This is usually a temporary issue - runner environment might not have been fully initialized
2. Retry the workflow: Go to Actions tab → Click the failed workflow → Click "Re-run jobs"
3. Check if the runner has enough disk space: `df -h` on the runner machine
### Binaries Not Uploaded to Release
**Problem**: Workflow completes but binaries don't appear in the release
**Solutions**:
1. Check the workflow logs: Actions tab → Click the workflow → View logs
2. Look for "Uploading" messages and any error messages
3. Verify the release was created: Go to Releases tab
4. Check that `GITEA_TOKEN` secret is still valid (tokens can expire)
### How to Check Workflow Logs
1. Go to your Gitea repository
2. Click the **Actions** tab
3. Click on the workflow run (should show the tag name)
4. Click on the `build` job
5. Scroll through the log to find error messages
6. Look for red `❌` marks indicating failures
### Manual Trigger for Testing
If you want to test the workflow without creating a full release:
```bash
# Push to main/master branch (triggers build only, no release)
git push origin main
# Then push a tag when you're ready (triggers full release)
git tag -a v1.0.0 -m "Release"
git push origin v1.0.0
```
## Additional Resources
@@ -194,3 +311,4 @@ If you want to use Coolify for deployment:
- [Project README](./README.md)
- [Quick Start Guide](./QUICKSTART.md)
- [Agent Guidelines](./AGENTS.md)
- [Docker Compose Guide](./DOCKER_COMPOSE.md)

107
docker-compose.yml Normal file
View File

@@ -0,0 +1,107 @@
version: '3.8'
# ============================================================================
# Nerd Monitor Docker Compose Configuration
# ============================================================================
#
# This file provides multiple ways to run Nerd Monitor:
#
# 1. Full Stack (Server + Agent):
# docker-compose up
#
# 2. Server Only:
# docker-compose up server
#
# 3. Agent Only (requires external server):
# docker-compose up agent
# (Set SERVER env var: SERVER=your-server:8080 docker-compose up agent)
#
# 4. Multiple Agents:
# docker-compose up -d server
# docker-compose run --name agent1 -e AGENT_ID=machine1 agent
# docker-compose run --name agent2 -e AGENT_ID=machine2 agent
#
# ============================================================================
services:
# =========================================================================
# Nerd Monitor Server
# =========================================================================
# Web UI and API endpoint for collecting agent statistics
#
# Environment Variables:
# ADDR: Server bind address (default: 0.0.0.0)
# PORT: Server port (default: 8080)
# USERNAME: Admin username (default: admin)
# PASSWORD: Admin password (default: admin) - CHANGE IN PRODUCTION
#
server:
build:
context: .
dockerfile: Dockerfile.server
container_name: nerd-monitor-server
image: nerd-monitor-server:latest
ports:
- "8080:8080"
environment:
# Server configuration
ADDR: "0.0.0.0"
PORT: "8080"
# IMPORTANT: Change these credentials in production!
USERNAME: "admin"
PASSWORD: "admin"
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/login"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
restart: unless-stopped
networks:
- nerd-monitor
# Resource limits (optional, uncomment to enable)
# deploy:
# resources:
# limits:
# cpus: '0.5'
# memory: 512M
# =========================================================================
# Nerd Monitor Agent
# =========================================================================
# Lightweight monitoring agent that reports system stats to the server
#
# Environment Variables:
# SERVER: Server address (default: server:8080 when using docker-compose)
# INTERVAL: Reporting interval (default: 15s)
# AGENT_ID: Optional agent identifier (auto-generated from hostname if empty)
#
# Note: This agent depends on the server being healthy before starting
#
agent:
build:
context: .
dockerfile: Dockerfile.agent
image: nerd-monitor-agent:latest
environment:
# Agent configuration
SERVER: "server:8080" # Connect to the server service
INTERVAL: "15s" # Report stats every 15 seconds
# AGENT_ID: "my-machine" # Optional: set a custom agent ID
depends_on:
server:
condition: service_healthy # Wait for server to be healthy
restart: unless-stopped
networks:
- nerd-monitor
# Resource limits (optional, uncomment to enable)
# deploy:
# resources:
# limits:
# cpus: '0.25'
# memory: 128M
networks:
# Shared network for server and agent communication
nerd-monitor:
driver: bridge