Add Docker support and update README
- Add Dockerfile with multi-stage build for Node.js + React - Add docker-compose.yml for easy local deployment - Add .dockerignore to exclude unnecessary files - Add GitHub Actions workflow for automatic Docker image builds and pushes to GHCR - Add comprehensive DOCKER.md documentation - Update README with Docker installation instructions
This commit is contained in:
1 parent
564aa7c1b8
commit
4e4f2fb324
6 files changed
+382
-17
No files matched your search
@@ -0,0 +1,16 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
.DS_Store
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.log
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
client/node_modules
|
||||||
|
server/node_modules
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
name: Docker Build and Push
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=sha,prefix={{branch}}-
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
# Docker Setup for SkyWatch
|
||||||
|
|
||||||
|
This guide explains how to build and run SkyWatch using Docker.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Docker and Docker Compose installed on your system
|
||||||
|
- A `.env` file configured in the project root (see README.md for configuration details)
|
||||||
|
|
||||||
|
## Building Locally
|
||||||
|
|
||||||
|
### Using Docker Compose (Recommended)
|
||||||
|
|
||||||
|
The easiest way to build and run SkyWatch with Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
1. Build the Docker image
|
||||||
|
2. Create a container named `skywatch-monitor`
|
||||||
|
3. Start the application on port 3001
|
||||||
|
4. Mount a persistent volume for data storage
|
||||||
|
|
||||||
|
### Using Docker Directly
|
||||||
|
|
||||||
|
To build the image manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t skywatch:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name skywatch \
|
||||||
|
-p 3001:3001 \
|
||||||
|
--env-file .env \
|
||||||
|
-v skywatch-data:/app/data \
|
||||||
|
skywatch:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pushing to GitHub Container Registry (GHCR)
|
||||||
|
|
||||||
|
### Automatic Deployment (Recommended)
|
||||||
|
|
||||||
|
The project includes a GitHub Actions workflow (`.github/workflows/docker-publish.yml`) that automatically:
|
||||||
|
- Builds your Docker image when you push to `main` or create a tag
|
||||||
|
- Pushes it to GitHub Container Registry (GHCR)
|
||||||
|
- Tags images as:
|
||||||
|
- `latest` (for main branch)
|
||||||
|
- Branch name (e.g., `main`)
|
||||||
|
- Semantic version (if you push a tag like `v1.0.0`)
|
||||||
|
- Short commit SHA
|
||||||
|
|
||||||
|
**No configuration needed!** The workflow uses GitHub's built-in authentication.
|
||||||
|
|
||||||
|
### Manual Push to GHCR
|
||||||
|
|
||||||
|
If you want to push manually:
|
||||||
|
|
||||||
|
1. Authenticate with GitHub Container Registry:
|
||||||
|
```bash
|
||||||
|
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u USERNAME --password-stdin
|
||||||
|
# Or use a Personal Access Token (PAT) with `read:packages` and `write:packages` scopes
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Build and tag the image:
|
||||||
|
```bash
|
||||||
|
docker build -t ghcr.io/YOUR-USERNAME/monitor:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Push to GHCR:
|
||||||
|
```bash
|
||||||
|
docker push ghcr.io/YOUR-USERNAME/monitor:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Viewing Published Images
|
||||||
|
|
||||||
|
Visit: `https://github.com/nmemmert/monitor/pkgs/container/monitor`
|
||||||
|
|
||||||
|
Or pull the image:
|
||||||
|
```bash
|
||||||
|
docker pull ghcr.io/nmemmert/monitor:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Managing Containers
|
||||||
|
|
||||||
|
### View running containers
|
||||||
|
```bash
|
||||||
|
docker ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### View logs
|
||||||
|
```bash
|
||||||
|
docker logs skywatch-monitor
|
||||||
|
# Follow logs in real-time
|
||||||
|
docker logs -f skywatch-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stop the container
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
# Or
|
||||||
|
docker stop skywatch-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remove containers and volumes
|
||||||
|
```bash
|
||||||
|
docker-compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Make sure your `.env` file is in the project root with required variables:
|
||||||
|
|
||||||
|
```env
|
||||||
|
PORT=3001
|
||||||
|
NODE_ENV=production
|
||||||
|
# Add other environment variables as needed
|
||||||
|
```
|
||||||
|
|
||||||
|
The `.env` file is loaded by Docker Compose from the `env_file` directive.
|
||||||
|
|
||||||
|
## Health Checks
|
||||||
|
|
||||||
|
The Docker container includes a health check that verifies the API is responding:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker inspect skywatch-monitor --format='{{.State.Health.Status}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Container exits immediately
|
||||||
|
Check logs:
|
||||||
|
```bash
|
||||||
|
docker logs skywatch-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port already in use
|
||||||
|
Change the port in `docker-compose.yml`:
|
||||||
|
```yaml
|
||||||
|
ports:
|
||||||
|
- "3002:3001" # Access at localhost:3002
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database issues
|
||||||
|
Clear the volume and rebuild:
|
||||||
|
```bash
|
||||||
|
docker-compose down -v
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Permission issues
|
||||||
|
The container runs as non-root user (nodejs). Ensure `.env` file permissions allow reading.
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
For production environments, consider:
|
||||||
|
|
||||||
|
1. Using a reverse proxy (nginx, traefik)
|
||||||
|
2. Setting up SSL/TLS certificates
|
||||||
|
3. Using environment-specific `.env` files
|
||||||
|
4. Implementing container orchestration (Kubernetes, Docker Swarm)
|
||||||
|
5. Setting resource limits in docker-compose.yml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
skywatch:
|
||||||
|
# ... other config
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 256M
|
||||||
|
```
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
# Build stage for React client
|
||||||
|
FROM node:20-alpine AS client-builder
|
||||||
|
|
||||||
|
WORKDIR /app/client
|
||||||
|
|
||||||
|
# Copy client package files
|
||||||
|
COPY client/package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy client source
|
||||||
|
COPY client/src ./src
|
||||||
|
COPY client/public ./public
|
||||||
|
|
||||||
|
# Build React app
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Final stage - Node.js server
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dumb-init for proper signal handling
|
||||||
|
RUN apk add --no-cache dumb-init
|
||||||
|
|
||||||
|
# Copy server package files
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install production dependencies only
|
||||||
|
RUN npm ci --only=production
|
||||||
|
|
||||||
|
# Copy server code
|
||||||
|
COPY server ./server
|
||||||
|
|
||||||
|
# Copy built React client from builder stage
|
||||||
|
COPY --from=client-builder /app/client/build ./client/build
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN addgroup -g 1001 -S nodejs && \
|
||||||
|
adduser -S nodejs -u 1001
|
||||||
|
|
||||||
|
USER nodejs
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 3001
|
||||||
|
|
||||||
|
# Use dumb-init to handle signals properly
|
||||||
|
ENTRYPOINT ["dumb-init", "--"]
|
||||||
|
|
||||||
|
# Start the server
|
||||||
|
CMD ["node", "server/index.js"]
|
||||||
@@ -27,6 +27,40 @@ The script will:
|
|||||||
- ✅ Set up auto-start on boot
|
- ✅ Set up auto-start on boot
|
||||||
- ✅ Guide you through email/webhook setup
|
- ✅ Guide you through email/webhook setup
|
||||||
|
|
||||||
|
### Docker Installation (Recommended)
|
||||||
|
|
||||||
|
The easiest way to get SkyWatch running with Docker:
|
||||||
|
|
||||||
|
#### Prerequisites
|
||||||
|
- Docker and Docker Compose
|
||||||
|
|
||||||
|
#### Setup
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/nmemmert/monitor.git
|
||||||
|
cd monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create and configure your `.env` file:
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your settings
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Start with Docker Compose:
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
The application will be available at `http://localhost:3001`
|
||||||
|
|
||||||
|
See [DOCKER.md](./DOCKER.md) for detailed Docker documentation including:
|
||||||
|
- Building images locally
|
||||||
|
- Pushing to Docker registries
|
||||||
|
- Running with custom ports
|
||||||
|
- Health checks and monitoring
|
||||||
|
|
||||||
### Manual Installation
|
### Manual Installation
|
||||||
|
|
||||||
#### Prerequisites
|
#### Prerequisites
|
||||||
@@ -150,26 +184,18 @@ nano .env # Configure your settings
|
|||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Option 3: Docker Deployment (Advanced)
|
### Option 3: Docker Deployment (Recommended)
|
||||||
|
|
||||||
Create `Dockerfile` in project root:
|
Docker setup is now fully integrated! See [DOCKER.md](./DOCKER.md) for complete documentation.
|
||||||
```dockerfile
|
|
||||||
FROM node:18
|
|
||||||
WORKDIR /app
|
|
||||||
COPY package*.json ./
|
|
||||||
RUN npm install
|
|
||||||
COPY . .
|
|
||||||
WORKDIR /app/client
|
|
||||||
RUN npm install && npm run build
|
|
||||||
WORKDIR /app
|
|
||||||
EXPOSE 3001
|
|
||||||
CMD ["node", "server/index.js"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Then deploy:
|
Quick start:
|
||||||
```bash
|
```bash
|
||||||
docker build -t resource-monitor .
|
# Local deployment
|
||||||
docker run -d -p 3001:3001 -v ./data:/app/data --name monitor resource-monitor
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Using pre-built image from GitHub Container Registry
|
||||||
|
docker pull ghcr.io/nmemmert/monitor:latest
|
||||||
|
docker run -d -p 3001:3001 --env-file .env ghcr.io/nmemmert/monitor:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deployment Workflow (Critical!)
|
### Deployment Workflow (Critical!)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
skywatch:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: skywatch-monitor
|
||||||
|
ports:
|
||||||
|
- "3001:3001"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3001
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- skywatch-data:/app/data
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3001/api/groups"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
skywatch-data:
|
||||||
|
driver: local
|
||||||
Reference in new issue
Block a user