{"id":18115990,"url":"https://github.com/mkuf/prind","last_synced_at":"2025-11-30T04:03:10.743Z","repository":{"id":37028218,"uuid":"417930556","full_name":"mkuf/prind","owner":"mkuf","description":"print in docker - Deploy a containerized Klipper Stack for your 3D Printer","archived":false,"fork":false,"pushed_at":"2025-11-23T17:27:01.000Z","size":647,"stargazers_count":459,"open_issues_count":4,"forks_count":98,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-11-23T17:30:10.624Z","etag":null,"topics":["3d-printing","docker","docker-compose","fluidd","klipper","klipperscreen","mainsail","mobileraker","mobileraker-companion","moonraker","moonraker-obico","moonraker-telegram-bot","obico","octoprint","simulavr"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkuf.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-16T19:45:04.000Z","updated_at":"2025-11-23T16:43:21.000Z","dependencies_parsed_at":"2023-02-19T08:16:09.971Z","dependency_job_id":"3075e4f9-d332-4dba-ae61-64c20796b26c","html_url":"https://github.com/mkuf/prind","commit_stats":null,"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"purl":"pkg:github/mkuf/prind","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkuf%2Fprind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkuf%2Fprind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkuf%2Fprind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkuf%2Fprind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkuf","download_url":"https://codeload.github.com/mkuf/prind/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkuf%2Fprind/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27376104,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-30T02:00:05.582Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-printing","docker","docker-compose","fluidd","klipper","klipperscreen","mainsail","mobileraker","mobileraker-companion","moonraker","moonraker-obico","moonraker-telegram-bot","obico","octoprint","simulavr"],"created_at":"2024-11-01T04:00:55.676Z","updated_at":"2025-11-30T04:03:10.736Z","avatar_url":"https://github.com/mkuf.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=center\u003e\u003cimg src=img/prind-logo.png height=400px\u003e\u003c/p\u003e\n\n# prind\n[![Build and Publish Images](https://github.com/mkuf/prind/actions/workflows/image-build-and-publish-schedule.yaml/badge.svg)](https://github.com/mkuf/prind/actions/workflows/image-build-and-publish-schedule.yaml)\n\nprind allows you to run the software for your 3D printer in Docker containers, eliminating any dependencies on the operating system.  \nThis means you can use end-of-life or cutting-edge operating systems, and anything in between.\n\nWith a single command, you can start up Klipper and its accompanying applications.\n\n## Supported Applications\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n|   |Name|Image source|Docs|\n|:---:|------|--------------|---|\n|\u003cimg src=\"https://raw.githubusercontent.com/Klipper3d/klipper/master/docs/img/klipper-logo.png\" width=30px\u003e|[Klipper](https://github.com/Klipper3d/klipper)|prind @ [docker/klipper](docker/klipper)|[Getting Started](#getting-started)|\n|\u003cimg src=\"https://avatars.githubusercontent.com/u/9563098?v=4\" width=30px\u003e|[Moonraker](https://github.com/Arksine/moonraker)|prind @ [docker/moonraker](docker/moonraker)|[Getting Started](#getting-started)|\n|\u003cimg src=\"https://raw.githubusercontent.com/mainsail-crew/docs/master/assets/img/logo.png\" width=30px\u003e|[Mainsail](https://github.com/mainsail-crew/mainsail)|`upstream`|[Starting the Stack](#starting-the-stack)|\n|\u003cimg src=\"https://raw.githubusercontent.com/fluidd-core/fluidd/develop/docs/assets/images/logo.svg\" width=30px\u003e|[Fluidd](https://github.com/fluidd-core/fluidd)|`upstream`|[Starting the Stack](#starting-the-stack)|\n|\u003cimg src=\"https://github.com/OctoPrint/OctoPrint/blob/main/docs/images/octoprint-logo.png?raw=true\" width=30px\u003e|[Octoprint](https://github.com/OctoPrint/OctoPrint)|`upstream`|[Starting the Stack](#starting-the-stack)|\n|\u003cimg src=\"https://avatars.githubusercontent.com/u/91093001?s=200\u0026v=4\" width=30px\u003e|[KlipperScreen](https://github.com/KlipperScreen/KlipperScreen)|prind @ [docker/klipperscreen](docker/klipperscreen)|[Additional Profiles](#klipperscreen)|\n|\u003cimg src=\"https://avatars.githubusercontent.com/u/52351624?s=48\u0026v=4\" width=30px\u003e|[moonraker-telegram-bot](https://github.com/nlef/moonraker-telegram-bot)|`upstream`|[Additional Profiles](#moonraker-telegram-bot)|\n|\u003cimg src=\"https://github.com/Clon1998/mobileraker/blob/master/assets/icon/ic_launcher_foreground.png?raw=true\" width=30px\u003e|[mobileraker_companion](https://github.com/Clon1998/mobileraker_companion)|`upstream`|[Additional Profiles](#mobileraker_companion)|\n|\u003cimg src=\"https://avatars.githubusercontent.com/u/46323662?s=200\u0026v=4\" width=30px\u003e|[moonraker-obico](https://github.com/TheSpaghettiDetective/moonraker-obico)|`upstream`|[Additional Profiles](#moonraker-obico)|\n|\u003cimg src=\"https://raw.githubusercontent.com/Donkie/Spoolman/master/client/icons/spoolman.svg\" width=30px\u003e|[Spoolman](https://github.com/Donkie/Spoolman)|`upstream`|[Additional Profiles](#spoolman)|\n|\u003cimg src=\"https://avatars.githubusercontent.com/u/41749659?s=200\u0026v=4\" width=30px\u003e|[µStreamer](https://github.com/pikvm/ustreamer)|prind @ [docker/ustreamer](docker/ustreamer)|[Add your Configuration](#add-your-configuration-to-docker-composeoverrideyaml)\u003cbr\u003e[Multiple Webcams](https://github.com/mkuf/prind?tab=readme-ov-file#multiple-webcams)|\n|\u003cimg src=\"https://octoeverywhere.com/img/logo/logo_maskable.svg\" width=30px\u003e|[OctoEverywhere](https://octoeverywhere.com)|`upstream`|[Additional Profiles](#octoeverywhere)|\n|\u003cimg src=\"https://raw.githubusercontent.com/ssendev/LaserWeb4/refs/heads/v4.1/src/favicon.ico\" width=30px\u003e|[LaserWeb4](https://laserweb.yurl.ch/)|prind @ [docker/laserweb](docker/laserweb)|[Additional Profiles](#laserweb)|\n\n\u003c/details\u003e\n\n## Getting started\nThis guide requires _Docker_ and _Docker Compose v2_ on your machine.  \nFollow the official guides to install and set them up:\n\n* [Install Docker on Ubuntu](https://docs.docker.com/engine/install/ubuntu/)\n* [Install Docker Compose v2](https://docs.docker.com/compose/cli-command/#installing-compose-v2)\n\nClone this repository onto your Docker host using Git:\n```bash\ngit clone https://github.com/mkuf/prind\n```\n\nInstall the `prind-tools` helper script.\n```bash\ncd prind\n\ncat \u003c\u003cEOF | sudo install /dev/stdin /usr/local/bin/prind-tools\n#!/bin/sh\ndocker compose -f $(pwd)/docker-compose.extra.tools.yaml run --rm tools \"\\$@\"\nEOF\n```\n\nUnless otherwise specified, all commands mentioned in the documentation should be run from the root of the repository.\n\n### Build the MCU Code\nBefore using Klipper, you'll have to build and flash the microcontroller-code for your printers mainboard.  \nThis can be done in a container by calling the build commands via `prind-tools`.  \nFollow the Instructions on finding your printer, building and flashing the microcontroller found in the [Klipper Docs](https://www.klipper3d.org/Installation.html#building-and-flashing-the-micro-controller).  \n\nAdapted from the official Docs, a generic Build would look like this.\n```bash\nprind-tools \"make menuconfig\"\nprind-tools \"make\"\nprind-tools \"make flash FLASH_DEVICE=/dev/serial/by-id/\u003cmy printer\u003e\"\n```\n\nIf your Board can be flashed via SD-Card, you can also use the `flash-sdcard.sh` script provided by klipper\n\n```bash\nprind-tools \"scripts/flash-sdcard.sh \u003cdevice\u003e \u003cboard\u003e\"\n```\n\nIf no official flash method is available, you can retrieve the `klipper.bin` from the `out` directory that is created by `make` and Follow your boards instructions on how to proceed with flashing.\n\n### Add your Configuration to docker-compose.override.yaml\nLocate the `webcam` Service within `docker-compose.override.yaml` and update the `device` Section with the Device Name of your Webcam.  \nIn this example, the Webcam is using device `/dev/video0`. Do not edit any other lines.\n```yaml\n  webcam:\n    \u003c\u003c: *ustreamer-svc\n    devices:\n      - /dev/video0:/dev/webcam\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.services.webcam.loadbalancer.server.port=8080\"\n      - \"traefik.http.routers.webcam.rule=PathPrefix(`/webcam`)\"\n      - \"traefik.http.routers.webcam.entrypoints=web\"\n      - \"traefik.http.middlewares.webcam.stripprefix.prefixes=/webcam\"\n      - \"traefik.http.routers.webcam.middlewares=webcam\"\n```\n\n### Configuring Klipper/Moonraker\nAll Runtime Configs are stored within `config` of this Repo.  \n* Update `config/printer.cfg` with your Klipper config, set the serial device and make sure to not remove the existing Macros as they are required by fluidd/mainsail. See [Klipper3d Docs](https://www.klipper3d.org/Config_Reference.html) for Reference\n* Make sure to update `cors_domains` and `trusted_clients` within `moonraker.cfg` to secure your moonraker api from unwanted access. See [Moonraker Docs](https://moonraker.readthedocs.io/en/latest/configuration/) for Reference\n\n### Starting the stack\nThere are currently 3 frontend Profiles to choose from, depending on the Web Frontend you'd like to use.\n* fluidd\n* mainsail\n* octoprint (w/o moonraker)\n\nStarting the stack comes down to:\n```\ndocker compose --profile \u003cprofile\u003e up -d\n```\ne.g.\n```\ndocker compose --profile fluidd up -d\n```\n\nSwitching between profiles requires the whole stack to be torn down before starting another Frontend.  \nRunning two Frontends at the same time is currently not supported behind a proxy.\nSwitching from fluidd to mainsail would look like this: \n```\ndocker compose --profile fluidd down\ndocker compose --profile mainsail up -d\n```\n\n### Additional Profiles\nDocker compose allows for multiple profiles to be started at once.  \nYou may combine any of the above frontend profiles with any number of the following additional profiles.  \n\nBe sure to always use the same set of profiles when updating the stack, otherwise services may be orphaned or the stack is behaving in an unpredictable way. \n\n#### hostmcu\nThe `hostmcu` profile enables you to use your host as secondary mcu for klipper.  \nSee the [Klipper Docs](https://www.klipper3d.org/RPi_microcontroller.html) for more information on this Topic.\n\nUncomment the following lines in `printer.cfg`\n```\n[mcu host]\nserial: /opt/printer_data/run/klipper_host_mcu.tty\n```\nthen start the stack with\n\n```\ndocker compose --profile mainsail --profile hostmcu up -d\n```\n\nAfter the hostmcu container is started, you may check for available gpio chips with\n\n```\ndocker compose exec -it hostmcu gpiodetect\n```\n\nand check the pin number and pin availability with\n\n```\ndocker compose exec -it hostmcu gpioinfo\n```\n\n#### KlipperScreen\n[KlipperScreen by jordanruthe](https://github.com/jordanruthe/KlipperScreen) can be enabled via the `klipperscreen` Profile.  \n\nIt requires a X11 Server on your machine that the Container can connect to.  \nLocate the setup Script for X11 within `scripts/` and run it from the root directory of this repository as user root.\nIt creates a User, installs and configures X11 and creates a Systemd Service for xinit.\n```\ncd prind/\n./scripts/setup-X11.sh\n```\n\nThe Prind Logo should now be displayed on your screen.  \nIf this is not the case, check the scripts output for errors.  \nOtherwise, proceed to start/update the Stack.\n\n```\ndocker compose --profile fluidd --profile klipperscreen up -d\n```\n\n#### Moonraker-Telegram-Bot\n[moonraker-telegram-bot by nlef](https://github.com/nlef/moonraker-telegram-bot) can be enabled via the `moonraker-telegram-bot` Profile  \n\nAdd your `bot_token` and `chat_id` to `config/telegram.conf`.  \nSee the [configuration reference](https://github.com/nlef/moonraker-telegram-bot/wiki/Sample-config) for further configuration Options.\n\n```\ndocker compose --profile mainsail --profile moonraker-telegram-bot up -d\n```\n\n#### mobileraker_companion\n[mobileraker_companion by Clon1998](https://github.com/Clon1998/mobileraker_companion) can be enabled via the `mobileraker_companion` Profile.\n\nThe default configuration provided with this repository contains everything needed to start the service and receive notifications via the [Mobileraker App](https://github.com/Clon1998/mobileraker). See the [configuration reference](https://github.com/Clon1998/mobileraker_companion#companion---config) for further configuration Options.\n\n```\ndocker compose --profile mainsail --profile mobileraker_companion up -d\n```\n\n#### moonraker-obico\n\u003e This profile is incompatible with OctoPrint, choose Fluidd or Mainsail instead.\n\n[moonraker-obico by TheSpaghettiDetective](https://github.com/TheSpaghettiDetective/moonraker-obico) can be enabled via the `moonraker-obico` Profile.  \n\nThe default configuration provided with this repository contains everything needed to access the webcam and use the tunnel with obico Cloud. This requires an account at https://obico.io.  \nIf you use a self hosted instance of [obico-server](https://github.com/TheSpaghettiDetective/obico-server), you'll have to change the `[server].url` at `config/moonraker-obico.cfg`.  \n\nFor further configuration options, see the [Official Documentation](https://www.obico.io/docs/user-guides/moonraker-obico/config/).\n\nFollow these steps to link your printer and start the profile:\n\n1. Add a new `Klipper`-Type Printer via the Webinterface\n2. Klick `Next` when prompted to *Install Obico for Klipper*, not executing the shown Commands\n3. Change to the root of the prind repository and start the linking process\n```bash\ndocker compose -f docker-compose.extra.link-obico.yaml run --rm link-obico\n```\n4. Enter the *6-digit verification code*\n5. Check if `[server].auth_token` is set in `config/mooonraker-obico.cfg`\n6. Start the stack\n```bash\ndocker compose --profile mainsail --profile moonraker-obico up -d\n```\n\n#### Spoolman\n[Spoolman by Donkie](https://github.com/Donkie/Spoolman) can be enabled via the `spoolman` Profile.  \n\nUncomment the spoolman section in `moonraker.conf` and add your printers Hostname or IP to the server URL.  \nThe stack can then be started by specifying the `spoolman` profile. \n```bash\ndocker compose --profile fluidd --profile spoolman up -d\n```\n\nNavigate to `http://\u003cyourprinter\u003e/spoolman` to access the spool manager webinterface.\n\n#### octoeverywhere\n[OctoEverywhere](https://octoeverywhere.com) can be enabled via the `octoeverywhere` Profile.\n\nAdd your Printers IP address to `docker-compose.override.yaml` like so, then start the stack.\n```yaml\nservices:\n  octoeverywhere:\n    environment:\n      PRINTER_IP: 10.0.0.11\n```\n```\ndocker compose --profile mainsail --profile octoeverywhere up -d\n```\n\nAfter the stack has started, get the logs of the octoeverywhere service to retrieve the code to link your printer.\n\n```\ndocker compose logs octoeverywhere\n```\n\n#### laserweb\n\n[LaserWeb4](https://laserweb.yurl.ch/) can be enabled via the `laserweb` Profile. The image is based on [a fork](https://github.com/ssendev/LaserWeb4) which includes support for connecting to Moonraker.\n\n```\ndocker compose --profile fluidd --profile laserweb up -d\n```\n\nAfter the stack has started, navigate to `http://\u003cyourprinter\u003e/laserweb/`.  \nIn the `Comms` tab, select `SERVER: Moonraker`, add your Printers IP Address as `SERVER IP` and click `Connect`\n\n## Updating\nImages are built daily and tagged with `latest` and the [git description](https://git-scm.com/docs/git-describe#_examples) of the remote repo. \nExample: \n\n* `mkuf/klipper:latest`\n* `mkuf/klipper:v0.12.0-114-ga77d0790`\n\nThe `latest` Tag will point to a new Image within 24h.  \nThe descriptive Tag `v0.12.0-114-ga77d0790` will remain and refers to [Klipper3d/klipper:v0.12.0-114-ga77d0790](https://github.com/Klipper3d/klipper/commit/a77d07907fdfcd76f7175231caee170db205ff04)\n\nUpdating can be handled via docker-compose.  \ndocker-compose.yaml uses latest tags for all Images contained in this Repository.  \nCompose will download all current Images and replace them when starting the stack again.  \nMake sure to include _all_ profiles that you specified at stack startup when pulling images.  \n```\ndocker compose --profile \u003cprofile\u003e pull\ndocker compose --profile \u003cprofile\u003e up -d\n``` \n\n## Advanced Topics\n### Device permissions\nAdjusting permissions for devices connected to your host may become necessary, especially if you're using a non-Debian-based distribution with varying numerical group IDs.  \n\nYou can accomplish this by crafting a udev rule tailored to your specific device on your host system. Refer to your operating system's manual for instructions on configuring udev rules.  \n\nTypically, this involves creating a `*.rules` file within `/etc/udev/rules.d` and appending a single line to it.  \nConsult the table below for the appropriate rule corresponding to your device type. Ensure to include your device's specific `idVendor` and `idProduct`, which can be identified using the `lsusb` command.\n\n| Device Type | Group Name | GID  | Udev Rule                                                                                            |\n|-------------|------------|------|------------------------------------------------------------------------------------------------------|\n| Serial Port | `dialout`  | `20` | `ACTION==\"add\",SUBSYSTEM==\"tty\",ATTRS{idVendor}==\"0000\",ATTRS{idProduct}==\"0000\",GROUP=\"20\"`         |\n| Webcam      | `video`    | `44` | `ACTION==\"add\",SUBSYSTEM==\"video4linux\",ATTRS{idVendor}==\"0000\",ATTRS{idProduct}==\"0000\",GROUP=\"44\"` |\n\n### Input Shaper Calibration\nUsing input shaper requires an accelerometer.  \nIf you choose to connect this to your hosts GPIO pins, make sure to enable the `hostmcu` profile described in the `Additional Profiles` section above.\n\nFollow the Docs on [Measuring Resonances](https://www.klipper3d.org/Measuring_Resonances.html), to set up your Printer.  \n\nAfter running `TEST_RESONANCES` or `SHAPER_CALIBRATE`, Klipper generates csv output in /tmp. To further analyze this data, it has to be extracted from the running klipper container.\n```\nmkdir ./resonances\n\ndocker compose exec klipper ls /tmp\n  resonances_x_20220708_124515.csv  resonances_y_20220708_125150.csv\n\ndocker compose cp klipper:/tmp/resonances_x_20220708_124515.csv ./resonances/\ndocker compose cp klipper:/tmp/resonances_y_20220708_125150.csv ./resonances/\n```\n\nTo analyze the generated files, call `calibrate_shaper.py` via `prind-tools`\n```\nprind-tools \"scripts/calibrate_shaper.py resonances/resonances_x_20220708_124515.csv -o resonances/cal_x.png\"\n  [...]\n  Recommended shaper is ei @ 90.2 Hz\n\nprind-tools \"scripts/calibrate_shaper.py resonances/resonances_y_20220708_125150.csv -o resonances/cal_y.png\"\n  [...]\n  Recommended shaper is mzv @ 48.2 Hz\n```\n\n### Use CANBUS\nCAN Devices are network devices in the Hosts network namespace. Granting access for containers requires running them in host network mode.  \nAdd the following snippet to your `docker-compose.override.yaml` and restart the stack.  \nAny further configuration has to be done in klipper, see the [official Klipper Docs](https://www.klipper3d.org/CANBUS.html)\n```yaml\nservices:\n  klipper:\n    network_mode: host\n```\n\n\n### Change Execution Options\nThe Entrypoint for all Docker Images within this Repo are the actual Applications, which are run at container execution time.  \nThis makes it possible to set command line Arguments for the Apps as Docker Command.  \nWithin docker-compose.yaml commands are already set, you may override them within `docker-compose.override.yaml` to fit your needs. \nExample from service Klipper:\n```yaml\n  command:\n    - \"-I\"\n    - \"run/klipper.tty\"\n    - \"-a\"\n    - \"run/klipper.sock\"\n    - \"cfg/printer.cfg\"\n```\n\n### Multiple Webcams\nThe Ustreamer Service is already templated to be easily reused for multi-webcam Setups.  \nTo add a new Ustreamer Service, simply add the following snippet to `docker-compose.override.yaml`.  \nNotice, that all service names, container names and traefik labels need to be unique while the right side of the passed Device (`:/dev/webcam`) always stays the same.\nHence replace webcam2 with webcam3 and so on for every webcam you add and update the physical device that gets passed to the container.\n```yaml\n  webcam2:\n    \u003c\u003c: *ustreamer-svc\n    devices:\n      - /dev/video1:/dev/webcam\n    labels:\n      org.prind.service: webcam2\n      traefik.enable: true\n      traefik.http.services.webcam2.loadbalancer.server.port: 8080\n      traefik.http.routers.webcam2.rule: PathPrefix(`/webcam2`)\n      traefik.http.routers.webcam2.entrypoints: web\n      traefik.http.middlewares.webcam2.stripprefix.prefixes: /webcam2\n      traefik.http.routers.webcam2.middlewares: webcam2\n```\n\n### Building Docker images locally\nIf you'd like to customize the provided Docker Images, you may edit the Dockerfiles within the `docker/\u003cservice\u003e` Directory.  \nImages are build in multiple stages, the final stage is called `run`. Based on this, you can update Service definitions within `docker-compose.override.yaml` to build Images locally.\n\nExample: Build Moonraker  \nUpdate the `image:` name and add a `build` config:\n```yaml\n  moonraker:\n    image: moonraker:latest\n    build:\n      context: docker/moonraker\n      target: run\n```\n\n### Healthchecks\nThe Klipper, Moonraker, and Ustreamer images include scripts to monitor the overall health of the application. By default, health checks are **disabled** to avoid high CPU usage, which can cause unwanted behavior on low-powered machines.\n\nIn tests, container CPU usage **doubled** when health checks were performed every 30 seconds and increased **sixfold** when performed every 5 seconds.\n\nTo enable health checks, you can add them to your docker-compose.override.yaml file. Refer to the [Compose file documentation]((https://docs.docker.com/reference/compose-file/services/#healthcheck)) for guidance on customizing these checks.\n\n```yaml\nservices:\n  klipper:\n    healthcheck:\n      test: [\"python3\", \"/opt/health.py\"]\n      interval: 30s\n  moonraker:\n    healthcheck:\n      test: [\"bash\", \"/opt/health.sh\"]\n      interval: 30s\n  webcam:\n    healthcheck:\n      test: [\"bash\", \"/opt/health.sh\"]\n      interval: 30s\n```\n\n### Enable Mainsail remoteMode\nIn case Moonraker is not situated on the same Host as Mainsail, you'll have to enable remoteMode in Mainsail to set up a remote Printer. This mirrors the behaviour of https://my.mainsail.xyz.\n\n1. Create `config/mainsail.json` with the following Contents\n```json\n{\n    \"remoteMode\":true\n}\n```\n2. Add the newly created File as a Volume to the mainsail Service\n```yaml\n  mainsail:\n    volumes:\n      - ./config/mainsail.json:/usr/share/nginx/html/config.json\n```\n\n### Debugging the Stack\nDebugging the Stack without printer hardware is challenging, as klipper requires a mcu to operate.  \nFor this purpose, you can build a service that emulates a mcu with simulavr, as suggested by the [Klipper Docs](https://github.com/Klipper3d/klipper/blob/master/docs/Debugging.md).  \n\nThe simulavr Image is part of the Dockerfile for Klipper but is not pushed to any registry, so it needs to be built when needed.  \n\nLocate the `docker-compose.extra.simulavr.yaml` in the repository and set the `VERSION` Build-Arg to any Git Reference from [Klipper3d/klipper](https://github.com/Klipper3d) that you would like the mcu code to be compatible with. \n\nThis example builds the mcu code from [Klipper3d/klipper:d75154d](https://github.com/Klipper3d/klipper/commit/d75154d695efb1338cbfff061d226c4f384d127b)\n```yaml\n    build:\n      context: docker/klipper\n      target: build-simulavr\n      args: \n        VERSION: d75154d695efb1338cbfff061d226c4f384d127b\n```\n\nThen start the Stack\n```\ndocker compose \\\n  --profile mainsail \\\n  -f docker-compose.yaml \\\n  -f docker-compose.extra.simulavr.yaml \\\n  up -d\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkuf%2Fprind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkuf%2Fprind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkuf%2Fprind/lists"}