diff --git a/Dockerfile b/Dockerfile index 41c198f..5668a3d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,26 @@ -FROM ubuntu:20.04 +FROM ghcr.io/siwatinc/siwat-ubuntubaseimage:focal ARG DEBIAN_FRONTEND=noninteractive -ENV TZ=America/New_York +ENV TZ=Asia/Bangkok RUN apt-get update && apt-get install -y \ cmake \ - libjpeg8-dev \ g++ \ wget \ unzip \ + psmisc \ git \ - python2 \ + python3-virtualenv \ virtualenv \ python3-dev \ - python3-virtualenv \ - tzdata - + libffi-dev \ + build-essential \ + tzdata \ + zlib1g-dev \ + libjpeg-dev \ + ffmpeg \ + iputils-ping + EXPOSE 5000 ARG tag=master @@ -36,7 +41,6 @@ RUN git clone --branch $tag https://github.com/foosel/OctoPrint.git /opt/octopri && ./venv/bin/pip install . RUN /opt/octoprint/venv/bin/python -m pip install \ -https://github.com/AlexVerrico/Octoprint-Display-ETA/archive/master.zip \ https://github.com/1r0b1n0/OctoPrint-Tempsgraph/archive/master.zip \ https://github.com/tpmullan/OctoPrint-DetailedProgress/archive/master.zip \ https://github.com/AliceGrey/OctoprintKlipperPlugin/archive/master.zip \ @@ -45,12 +49,21 @@ https://github.com/jneilliii/OctoPrint-BedLevelVisualizer/archive/master.zip \ https://github.com/OctoPrint/OctoPrint-MQTT/archive/master.zip \ https://github.com/birkbjo/OctoPrint-Themeify/archive/master.zip \ https://github.com/jneilliii/OctoPrint-Python3PluginCompatibilityCheck/archive/master.zip \ -https://github.com/OllisGit/OctoPrint-PrintJobHistory/releases/latest/download/master.zip \ https://github.com/marian42/octoprint-preheat/archive/master.zip \ https://github.com/OllisGit/OctoPrint-FilamentManager/releases/latest/download/master.zip \ https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip \ -https://github.com/jneilliii/OctoPrint-UltimakerFormatPackage/archive/master.zip \ -https://github.com/jneilliii/OctoPrint-ConsolidateTempControl/archive/master.zip +https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip \ +https://github.com/jneilliii/OctoPrint-PrusaSlicerThumbnails/archive/master.zip \ +https://gitlab.com/mosaic-mfg/canvas-plugin/-/archive/master/canvas-plugin-master.zip \ +https://github.com/costas-basdekis/MarlinGcodeDocumentation/archive/master.zip \ +https://github.com/crealitycloud/OctoPrint-Crealitycloud/archive/master.zip \ +https://github.com/crysxd/OctoApp-Plugin/archive/refs/heads/release.zip \ +https://github.com/paukstelis/OctoPrint-Cancelobject/archive/master.zip \ +https://github.com/OllisGit/OctoPrint-CostEstimation/releases/latest/download/master.zip \ +https://github.com/eyal0/OctoPrint-MultipleUpload/archive/master.zip \ +https://gitlab.com/mosaic-mfg/canvas-plugin/-/archive/3.0.3/canvas-plugin-3.0.3.zip \ +https://github.com/wgcv/RewriteM600/archive/master.zip \ +https://github.com/TheSpaghettiDetective/OctoPrint-Obico/archive/master.zip VOLUME /home/octoprint/.octoprint @@ -65,15 +78,13 @@ COPY klippy.sudoers /etc/sudoers.d/klippy RUN useradd -ms /bin/bash klippy # This is to allow the install script to run without error +RUN rm -f /bin/systemctl RUN ln -s /bin/true /bin/systemctl USER octoprint WORKDIR /home/octoprint -# Update the install script for Ubuntu 20 -RUN sed -i 's/python-virtualenv //' ./klipper/scripts/install-ubuntu-18.04.sh - RUN git clone https://github.com/KevinOConnor/klipper RUN ./klipper/scripts/install-ubuntu-18.04.sh @@ -85,5 +96,6 @@ RUN rm -f /bin/systemctl COPY start.py / COPY runklipper.py / - -CMD ["/start.py"] +COPY start.sh / +COPY printer.cfg / +CMD bash /start.sh diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..7016749 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,27 @@ +pipeline { + agent any + + stages { + stage('Clone') { + steps { + git branch: 'ender3s1', url: 'https://git.siwatsystem.com/satitchula-printfarm/octoprint-klipper-docker' + } + } + stage('Build Docker Image') { + steps { + script { + image = docker.build("siwatinc/octoprint-klipper:ender3s1","./ --no-cache") + } + } + } + stage('Publish Docker Image') { + steps { + script { + docker.withRegistry("https://ghcr.io/v2") { + image.push() + } + } + } + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index e1ca776..21dd1ef 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,3 @@ # OctoPrint-Klipper -My version of a Docker image for running [OctoPrint] and [Klipper] in a single container. Includes a few plugins I find useful. - -Big thanks to [sillyfrog](https://github.com/sillyfrog) for laying the groundwork for this image. - -This is very much written for my purposes, so you'll likely need to modify it for your setup. I've been using it for a while now and it's going well. I've successfully run it on these platforms: -* Orange Pi Zero 512MB -* AtomicPi -* Raspberry Pi 4B 1GB (current source of `arm` images) - -## Running the container - -Create a directory on your host that will persist config files. I use `/home/docker/octoprint-klipper`. - -Pull the image. Until I figure out multi platform aware images, you need to specify your arch. Both `arm` and `amd64` images are on DockerHub. If using Raspberry Pi or similar use `arm` in place of `[tag]`. - -```shell -docker pull seanauff/octoprint-klipper:[tag] -``` - -Start the container once to populate your config folder: - -``` -docker run -d --name octoprint-klipper -e TZ=America/New_York -v /home/docker/octoprint-klipper:/home/octoprint/.octoprint --device /dev/ttyUSB0:/dev/ttyUSB0 -p 5000:5000 seanauff/octoprint-klipper:[tag] -``` - -Stop the container, and modify your [Klipper] `printer.cfg` and [Octoprint] `config.yaml` in the config directory as needed. - -Restart the container. - -A sample docker-compose file is also provided. - -If you have any questions, feel free to log an issue on this project, and I'll see if I can help. - -## Updates - -The easiest way to update is to pull the latest image and recreate the container. You could also build the image yourself to get the latest updates. I have had success in using the Octoprint built in updater to upgrade plugins, as well as install new ones. Any upgrades conducted in this manner will be lost upon recreation of the container. - -## Build the image yourself - -The DockerHub images may not be as up to date as the repo (`amd64` is autobuilt, but not `arm`), so you can ensure you have the latest by building yourself. - -Clone the repository and build the image: - -```shell -git clone https://github.com/seanauff/OctoPrint-Klipper.git -docker build -t seanauff/octoprint-klipper OctoPrint-Klipper -``` - -If you already have an image built and are trying to upgrade, you may need to force the build not to use cache: -```shell -docker build -t seanauff/octoprint-klipper --no-cache -pull OctoPrint-Klipper -``` - -[Octoprint]: https://github.com/foosel/OctoPrint -[Klipper]: https://github.com/KevinOConnor/klipper +This repository contain the code required to run klipper and octoprint in a docker container, made specifically for Satit Chula's Ender 3 S1 Print Farm \ No newline at end of file diff --git a/octoprint_config/cancel_gcode.gcode b/octoprint_config/cancel_gcode.gcode new file mode 100644 index 0000000..9bac45f --- /dev/null +++ b/octoprint_config/cancel_gcode.gcode @@ -0,0 +1,14 @@ +; move head out of the way +G91 +G0 Z10 +G28 X Y +G0 X0Y230 + +; disable motors +M84 + +;disable all heaters +{% snippet 'disable_hotends' %} +{% snippet 'disable_bed' %} +;disable fan +M106 S0 \ No newline at end of file diff --git a/octoprint_config/config.txt b/octoprint_config/config.txt new file mode 100644 index 0000000..2f60481 --- /dev/null +++ b/octoprint_config/config.txt @@ -0,0 +1,3 @@ +OctoKlipper +config dir: /home/octoprint/.octoprint +log: /home/octoprint/.octoprint/logs/serial.log \ No newline at end of file diff --git a/printer.cfg b/printer.cfg new file mode 100644 index 0000000..93a228e --- /dev/null +++ b/printer.cfg @@ -0,0 +1,216 @@ +# Ender 3 S1 Config, Satit Chula Specific + +[stepper_x] +step_pin: PC2 +dir_pin: PB9 +enable_pin: !PC3 +microsteps: 16 +rotation_distance: 40 +endstop_pin: !PA5 +position_endstop: 0 +position_max: 258 +homing_speed: 50 + +[stepper_y] +step_pin: PB8 +dir_pin: PB7 +enable_pin: !PC3 +microsteps: 16 +rotation_distance: 40 +endstop_pin: !PA6 +position_endstop: 0 +position_max: 230 +homing_speed: 50 + +[stepper_z] +step_pin: PB6 +dir_pin: !PB5 +enable_pin: !PC3 +microsteps: 16 +rotation_distance: 8 +endstop_pin: probe:z_virtual_endstop +position_max: 270 +position_min: -1 + +[extruder] +max_extrude_only_distance: 100.0 +step_pin: PB4 +dir_pin: PB3 +enable_pin: !PC3 +microsteps: 16 +rotation_distance: 7.6190 +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: PA1 +sensor_type: EPCOS 100K B57560G104F +sensor_pin: PC5 +control: pid +pid_Kp: 22.865 +pid_Ki: 1.292 +pid_Kd: 101.178 +min_temp: 0 +max_temp: 265 +pressure_advance = 0.045 + +[input_shaper] +shaper_freq_x: 40 +shaper_freq_y: 40 + +[filament_switch_sensor RunoutSensor] +pause_on_runout: False +runout_gcode: PAUSE +insert_gcode: RESUME +switch_pin: !PC15 + +[heater_bed] +heater_pin: PA7 +sensor_type: EPCOS 100K B57560G104F +sensor_pin: PC4 +control: pid +pid_Kp: 69.139 +pid_Ki: 1.273 +pid_Kd: 938.565 +min_temp: 0 +max_temp: 130 + +[respond] +default_type: echo + +[endstop_phase stepper_x] + +[endstop_phase stepper_y] + +[gcode_arcs] +resolution: 1.0 + +[heater_fan hotend_fan] +pin: PC0 +heater: extruder +heater_temp: 50.0 + +[fan] +pin: PA0 + +[mcu] +serial: /dev/ttyEnder +restart_method: command + +[printer] +kinematics: cartesian +max_velocity: 500 +max_accel: 3000 +max_accel_to_decel: 3000 +max_z_velocity: 5 +square_corner_velocity: 5.0 +max_z_accel: 100 + +[bltouch] +sensor_pin: ^PC14 +control_pin: PC13 +x_offset: -32 +y_offset: -41 +z_offset: 0 +speed:10 +samples:1 +samples_result:average +probe_with_touch_mode: true +stow_on_each_sample: false + +[safe_z_home] +home_xy_position: 154,154 +speed: 100 +z_hop: 10 +z_hop_speed: 5 + +[bed_mesh] +speed: 100 +mesh_min: 10, 10 +mesh_max: 225, 189 +algorithm: bicubic +probe_count: 5,5 + +[palette2] +serial: /dev/ttyPalette +baud: 115200 +feedrate_splice: 0.5 +feedrate_normal: 1.0 +auto_load_speed: 2 +auto_cancel_variation: 0.1 + +[virtual_sdcard] +path: /home/octoprint/.octoprint/uploads + +[display_status] + +[pause_resume] + +[gcode_macro G29] +description: Mesh Bed Leveling +gcode: + G28 + BED_MESH_CALIBRATE + G0 X0Y0Z5 + +[gcode_macro PAUSE] +description: Pause the actual running print +rename_existing: PAUSE_BASE +# change this if you need more or less extrusion +variable_extrude: 1.0 +gcode: + ##### read E from pause macro ##### + {% set E = printer["gcode_macro PAUSE"].extrude|float %} + ##### set park positon for x and y ##### + # default is your max posion from your printer.cfg + {% set x_park = printer.toolhead.axis_maximum.x|float - 5.0 %} + {% set y_park = printer.toolhead.axis_maximum.y|float - 5.0 %} + ##### calculate save lift position ##### + {% set max_z = printer.toolhead.axis_maximum.z|float %} + {% set act_z = printer.toolhead.position.z|float %} + {% if act_z < (max_z - 2.0) %} + {% set z_safe = 2.0 %} + {% else %} + {% set z_safe = max_z - act_z %} + {% endif %} + ##### end of definitions ##### + PAUSE_BASE + G91 + {% if printer.extruder.can_extrude|lower == 'true' %} + G1 E-{E} F2100 + {% else %} + {action_respond_info("Extruder not hot enough")} + {% endif %} + {% if "xyz" in printer.toolhead.homed_axes %} + G1 Z{z_safe} F900 + G90 + G1 X{x_park} Y{y_park} F6000 + {% else %} + {action_respond_info("Printer not homed")} + {% endif %} + +[gcode_macro RESUME] +description: Resume the actual running print +rename_existing: RESUME_BASE +gcode: + ##### read E from pause macro ##### + {% set E = printer["gcode_macro PAUSE"].extrude|float %} + #### get VELOCITY parameter if specified #### + {% if 'VELOCITY' in params|upper %} + {% set get_params = ('VELOCITY=' + params.VELOCITY) %} + {%else %} + {% set get_params = "" %} + {% endif %} + ##### end of definitions ##### + {% if printer.extruder.can_extrude|lower == 'true' %} + G91 + G1 E{E} F2100 + {% else %} + {action_respond_info("Extruder not hot enough")} + {% endif %} + RESUME_BASE {get_params} + +[gcode_macro CANCEL_PRINT] +description: Cancel the actual running print +rename_existing: CANCEL_PRINT_BASE +gcode: + TURN_OFF_HEATERS + CANCEL_PRINT_BASE \ No newline at end of file diff --git a/start.py b/start.py index a5ce600..05da961 100755 --- a/start.py +++ b/start.py @@ -5,37 +5,11 @@ import time import os import pwd -MJPG = [ - "/usr/local/bin/mjpg_streamer", - "-i", - "%(input)s", - "-o", - "output_http.so -p %(port)s -w /usr/local/share/mjpg-streamer/www/", -] -MJPG_INPUT_DEFAULT = "input_uvc.so -r HD" - -OCTOPRINT = ["/opt/octoprint/venv/bin/octoprint", "serve"] +OCTOPRINT = ["/opt/octoprint/venv/bin/octoprint", "serve","--port","80"] def main(): - mjpg_processes = [] - mjpg_ports = [5000] # Reserve the OctoPrint port - for k, v in os.environ.iteritems(): - if k.startswith("MJPG") and not k.startswith("MJPG_"): - v = v.strip() - port_env = "MJPG_PORT" + k[4:] - port = int(os.environ.get(port_env, 8080)) - if port in mjpg_ports: - raise ValueError("Port %s from key %s already in use" % (port, port_env)) - if not v: - v = MJPG_INPUT_DEFAULT - subs = {'input': v, 'port': port} - cmd = [] - for part in MJPG: - cmd.append(part % subs) - print("Starting: %s" % (cmd,)) - mjpg_processes.append(subprocess.Popen(cmd)) # Start klipper klipper = subprocess.Popen(['sudo', '-u', 'octoprint', '/runklipper.py']) diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..529bcf6 --- /dev/null +++ b/start.sh @@ -0,0 +1,6 @@ +#Copy over Initial Printer Config +cp -n /printer.cfg /home/octoprint/.octoprint/printer.cfg +chmod 777 -v /home/octoprint/.octoprint/printer.cfg + +#Start OctoPrint and Klipper +python3 /start.py \ No newline at end of file diff --git a/unitconfig.json b/unitconfig.json new file mode 100644 index 0000000..59829c3 --- /dev/null +++ b/unitconfig.json @@ -0,0 +1,18 @@ +{ + "listeners": { + "*:80": { + "pass": "routes" + } + }, + "routes": [ + { + "match": { + "uri": "*" + }, + + "action": { + "proxy": "http://127.0.0.1:5000" + } + } + ] +} \ No newline at end of file