diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..a29c2d3 --- /dev/null +++ b/.env.template @@ -0,0 +1,5 @@ +PRINTER_URLS=["127.0.0.1"] +FILAMENT_DIAMETER=1.75 +SPOOLMAN_URL=http://127.0.0.1:7912 +SPOOLMAN_MODE=direct + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c54f60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +data/ +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7766826 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +FROM python:3.12-slim AS builder + +# Set working directory +WORKDIR /app + +COPY . . + +# Install dependencies to a specific folder +RUN pip install --no-cache-dir --prefix=/install -r requirements.txt + +FROM python:3.12-slim + +# Install packages +RUN apt-get update && apt-get install -y sshpass && rm -rf /var/lib/apt/lists/* + +# Set environment variables +ENV APP_DIR=/opt/filament-management \ + PYTHONPATH=/opt/filament-management \ + UI_PORT=8005 + +WORKDIR $APP_DIR + +# Copy Python libs and app code +COPY --from=builder /install /usr/local +COPY --from=builder /app $APP_DIR + +# Setup Entrypoint +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# Expose the UI port +EXPOSE $UI_PORT + +ENTRYPOINT ["/entrypoint.sh"] + +# Start the application +CMD uvicorn main:app --host 0.0.0.0 --port $UI_PORT + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bd73be1 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +up: + docker-compose up -d +down: + docker-compose down +restart: + docker-compose down && docker-compose up -d +logs: + docker-compose logs -f +pull: + docker-compose pull +build: + docker-compose build diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..565eefb --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +services: + cfsync: + build: . + container_name: cfsync + restart: unless-stopped + ports: + - "8005:8005" + # Create .env file here and override the settings below (See .env.template for example) + environment: + - UI_PORT=8005 + - TZ=${TZ:-Asia/Jerusalem} + - PRINTER_URLS=${PRINTER_URLS:-["127.0.0.1"]} + - FILAMENT_DIAMETER=${FILAMENT_DIAMETER:-1.75} + - SPOOLMAN_URL=${SPOOLMAN_URL:-http://127.0.0.1:7912} + - SPOOLMAN_MODE=${SPOOLMAN_MODE:-direct} # direct or moonraker + volumes: + # This ensures your filament data survives container updates + - ./data:/opt/filament-management/data + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8005/api/health"] + interval: 30s + timeout: 10s + retries: 3 diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..571734d --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e + +CONFIG_PATH="$APP_DIR/data/config.json" + +# Only generate the file if it does not exist +if [ ! -f "$CONFIG_PATH" ]; then + echo "Config not found. Generating from environment variables..." + + # Ensure the directory exists (important for mounts) + mkdir -p "$(dirname "$CONFIG_PATH")" + + python3 -c " +import os, json + +config = { + \"printer_urls\": json.loads(os.getenv('PRINTER_URLS', '[]')), + \"filament_diameter_mm\": float(os.getenv('FILAMENT_DIAMETER', '1.75')), + \"spoolman_url\": os.getenv('SPOOLMAN_URL', ''), + \"spoolman_mode\": os.getenv('SPOOLMAN_MODE', 'remote') +} + +with open('$CONFIG_PATH', 'w') as f: + json.dump(config, f, indent=4) +" +else + echo "Config file already exists in volume, skipping generation." +fi + +# Hand off to the CMD (uvicorn) +exec "$@" +