{"id":15007272,"url":"https://github.com/pojntfx/pojde","last_synced_at":"2025-10-03T14:31:40.521Z","repository":{"id":47708061,"uuid":"340735009","full_name":"pojntfx/pojde","owner":"pojntfx","description":"Develop from any device with a browser.","archived":true,"fork":false,"pushed_at":"2023-02-26T03:37:52.000Z","size":5023,"stargazers_count":65,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-09-29T15:04:04.357Z","etag":null,"topics":["cockpit","code-server","docker-container","jupyter-lab","linux-distribution","novnc","ttyd","vscode","web-application"],"latest_commit_sha":null,"homepage":"https://pojntfx.github.io/pojde/","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pojntfx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2021-02-20T19:21:50.000Z","updated_at":"2024-06-29T12:44:27.000Z","dependencies_parsed_at":"2024-09-24T19:08:04.824Z","dependency_job_id":"269851d6-b81d-40d3-99d0-834c4f04dc34","html_url":"https://github.com/pojntfx/pojde","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fpojde","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fpojde/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fpojde/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fpojde/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pojntfx","download_url":"https://codeload.github.com/pojntfx/pojde/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235146475,"owners_count":18943264,"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","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":["cockpit","code-server","docker-container","jupyter-lab","linux-distribution","novnc","ttyd","vscode","web-application"],"created_at":"2024-09-24T19:07:19.752Z","updated_at":"2025-10-03T14:31:35.101Z","avatar_url":"https://github.com/pojntfx.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pojde\n\n![Demo Video](./assets/demo.gif)\n\nDevelop from any device with a browser.\n\n[![Docker CI](https://github.com/pojntfx/pojde/actions/workflows/docker.yaml/badge.svg)](https://github.com/pojntfx/pojde/actions/workflows/docker.yaml)\n[![Matrix](https://img.shields.io/matrix/pojde:matrix.org)](https://matrix.to/#/#pojde:matrix.org?via=matrix.org)\n[![Docker Pulls](https://img.shields.io/docker/pulls/pojntfx/pojde?label=docker%20pulls)](https://hub.docker.com/r/pojntfx/pojde)\n![Chrome Support](https://img.shields.io/badge/Chrome-Latest%20version-%234285F4?logo=google-chrome)\n![Firefox Support](https://img.shields.io/badge/Firefox-Latest%20version-%23FF7139?logo=firefox-browser)\n![Safari Support](https://img.shields.io/badge/Safari-Latest%20version-%23000000?logo=safari)\n\n## Overview\n\npojde is a distributed multi-tenant development environment with web access to all components.\n\nIt strives to be ...\n\n- **Open**: Free/libre and open source software under the AGPL-3.0 license\n- **Versatile:** Supports multiple isolated instances on one host (for multi-user and/or multi-usecase support)\n- **Fast:** Minimal base image with optional modules for languages and tools\n- **Portable:** Runs on both Intel/AMD and ARM and requires Docker as the only dependency\n- **Lean**: Built on projects like [code-server](https://github.com/cdr/code-server) and [JupyterLab](http://jupyterlab.io/)\n\nWith pojde, you can **develop from any device with a browser!**\n\n## Installation\n\nTo install `pojdectl`, the management tool for pojde, run the following:\n\n```shell\n$ curl https://raw.githubusercontent.com/pojntfx/pojde/main/bin/pojdectl | bash -s -- upgrade-pojdectl\n```\n\nWorks on Linux, macOS and Windows (WSL2). Now, continue to [Usage](#usage) to create your first instance.\n\n## Usage\n\nI've created a brief YouTube video which guides you through the process:\n\n[\u003cimg src=\"https://img.youtube.com/vi/v2QB6Q1rCaQ/0.jpg\" width=\"256\" alt=\"Code from Anywhere with pojde YouTube video\" title=\"Code from Anywhere with pojde\"\u003e](https://www.youtube.com/watch?v=v2QB6Q1rCaQ)\n\nIf you prefer the instructions in written form, continue reading.\n\n### 1. Installing Docker or Podman\n\npojde supports running many isolated instances on a host, where the host can be your local machine, a cloud server or even a Raspberry Pi. Before you continue to the next step, please install either [Docker](https://docs.docker.com/get-docker/) or [Podman](https://podman.io/getting-started/installation) on the host that you wish to run the instance on. Please note:\n\n- If you have CGroups V2 enabled on your system (i.e. if you're using Fedora), please check out the [Docker, Podman and CGroups V2 FAQ](#docker-podman-and-cgroups-v2) first.\n- Host systems using systemd have the best support, but on systems which don't support it (i.e. Docker on macOS or WSL), pojde falls back to using OpenRC instead.\n\n### 2. Creating a first Instance\n\nTo create your first instance, use `pojdectl apply`:\n\n```shell\n$ pojdectl apply my-first-instance 5000 # Append `-n root@your-ip:ssh-port` to create the instance on a remote host instead\n```\n\nNow follow the instructions. `pojdectl apply` will ask you to download the CA certificate to your system, which you should do when creating the first instance; future instances will share this certificate. You can also get the certificate at any later point using `pojdectl get-ca-cert`.\n\n### 3. Trusting the CA Certificate\n\nTo trust the CA certificate, follow the videos we've created for you:\n\n- [Trusting self-signed CA certificates (system-wide on Fedora)](https://www.youtube.com/watch?v=qefr7MU-H-s)\n- [Trusting self-signed SSL certificates (Chrome on Linux)](https://www.youtube.com/watch?v=byFN8vH2SaM)\n- [Trusting self-signed SSL certificates (Chrome on macOS)](https://www.youtube.com/watch?v=_PJc7RcMnw8)\n- [Trusting self signed SSL certificates (Chrome on Windows)](https://www.youtube.com/watch?v=gyQ9IIxE3vc)\n\nNote that you'll have to **select the CA certificate you've downloaded in the step before**, not download the certificate as described in the videos.\n\n### 4. Listing the Instances\n\nOnce you've done so, confirm that everything went well by listing your instances with `pojdectl list`:\n\n```shell\n$ pojdectl list # Append `-n root@your-ip:ssh-port` to list the instances on a remote host instead\nNAME                           STATUS     PORTS\nmy-first-instance              running    5000-5005\n```\n\nAs you can see, our first instance (`my-first-instance`) is running and has exposed ports `5000` through `5005`. This port range has been selected when we ran `pojdectl apply` above.\n\n### 5. Accessing the Services\n\nYou can now access the services you've enabled (replace `localhost` with your remote host's IP or domain if you deployed to a remote host):\n\n| Icon                                                                                                                | Service                                           | Address                 | Description                         |\n| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ----------------------- | ----------------------------------- |\n| \u003cimg src=\"https://avatars.githubusercontent.com/u/5765104?s=200\u0026v=4\" width=\"25\"\u003e                                    | [Cockpit](https://cockpit-project.org/)           | https://localhost:5000/ | General management interface        |\n| \u003cimg src=\"https://raw.githubusercontent.com/cdr/code-server/main/src/browser/media/pwa-icon.png\" width=\"25\"\u003e        | [code-server](https://github.com/cdr/code-server) | https://localhost:5001/ | VSCode in the browser               |\n| \u003cimg src=\"https://raw.githubusercontent.com/tsl0922/ttyd/master/html/src/favicon.png\" width=\"25\"\u003e                   | [ttyd](https://tsl0922.github.io/ttyd/)           | https://localhost:5002/ | Shell access from the browser       |\n| \u003cimg src=\"https://raw.githubusercontent.com/novnc/noVNC/master/app/images/icons/novnc-192x192.png\" width=\"25\"\u003e      | [noVNC](https://novnc.com/info.html)              | https://localhost:5003/ | Graphical access from the browser   |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/jupyter/jupyter-original.svg\" width=\"25\"\u003e | [JupyterLab](http://jupyterlab.io/)               | https://localhost:5004/ | Interactive development environment |\n\nIf you can't access the services from outside `localhost`, make sure to open the ports on your firewall.\n\nAdditionally, there is a SSH server running on port `5005` which you can use to forward ports from the instance with `pojdectl forward`:\n\n```shell\n$ pojdectl forward local my-first-instance 127.0.0.1:4200:127.0.0.1:1234 127.0.0.1:4201:127.0.0.1:1235 # Append `-n root@your-ip:ssh-port` to also forward from the remote host to the local host\n```\n\nThis, for example, forwards remote port `1234` in the instance to local port `4200` and remote port `1235` to local port `4201`.\n\nYou can also forward ports to the instance:\n\n```shell\n$ pojdectl forward remote my-first-instance 127.0.0.1:6969:127.0.0.1:6969 # Append `-n root@your-ip:ssh-port` to also forward from the local host to the remote host\n```\n\n**🚀 That's it!** We hope you enjoy using pojde. Please be sure to also check out the [Updates](#updates) and [FAQ](#faq) sections to keep your pojde setup up to date.\n\n## Modules\n\npojde is based on a minimal base image; additional functionality can be added by enabling any of the following modules when running `pojdectl apply`:\n\n### Language Modules\n\n| Icon                                                                                                                                                                                                                                                | Name           | Description                                                                           |\n| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------- |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/c/c-original.svg\" width=\"25\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/cplusplus/cplusplus-original.svg\" width=\"25\"\u003e                      | **C/C++**      | GCC, GDB, CMake, the C/C++ VSCode extensions and C++ Jupyter kernel                   |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/go/go-original.svg\" width=\"25\"\u003e                                                                                                                                           | **Go**         | Go, TinyGo, the Go/TinyGo VSCode extensions and Go Jupyter kernel                     |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/python/python-original.svg\" width=\"25\"\u003e \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/jupyter/jupyter-original.svg\" width=\"25\"\u003e               | **Python**     | Python, pip, the Python VSCode extensions and Python Jupyter kernel                   |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/rust/rust-plain.svg\" width=\"25\"\u003e                                                                                                                                          | **Rust**       | Rust, Cargo, the Rust VSCode extensions and Rust Jupyter kernel                       |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/javascript/javascript-original.svg\" width=\"25\"\u003e \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/typescript/typescript-original.svg\" width=\"25\"\u003e | **JavaScript** | Node, the JavaScript/TypeScript VSCode extensions and JavaScript Jupyter kernel       |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/ruby/ruby-original.svg\" width=\"25\"\u003e                                                                                                                                       | **Ruby**       | Ruby, the Ruby VSCode extensions and Ruby Jupyter kernel                              |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/csharp/csharp-original.svg\" width=\"25\"\u003e \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/dot-net/dot-net-original.svg\" width=\"25\"\u003e               | **C#**         | Mono, .NET, PowerShell, the C# VSCode extensions and C#/F#/PowerShell Jupyter kernels |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/java/java-original.svg\" width=\"25\"\u003e                                                                                                                                       | **Java**       | Java, Maven, Gradle, the Java VSCode extensions and Java Jupyter kernel               |\n| \u003cimg src=\"https://github.com/JuliaLang/julia-logo-graphics/raw/master/images/julia-logo-color.png\" width=\"25\"\u003e                                                                                                                                      | **Julia**      | Julia, the Julia VSCode extensions and Julia Jupyter kernel                           |\n| \u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/6/6a/Gnu-octave-logo.svg\" width=\"25\"\u003e                                                                                                                                                      | **Octave**     | Octave, the Octave VSCode extensions and Octave Jupyter kernel                        |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/r/r-original.svg\" width=\"25\"\u003e                                                                                                                                             | **R**          | R, the R VSCode extensions and R Jupyter kernel                                       |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/postgresql/postgresql-original.svg\" width=\"25\"\u003e \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/mysql/mysql-original.svg\" width=\"25\"\u003e           | **SQL**        | SQLite, MariaDB, PostgreSQL, the SQL VSCode extensions and SQL Jupyter kernel         |\n| \u003cimg src=\"https://raw.githubusercontent.com/devicons/devicon/master/icons/bash/bash-original.svg\" width=\"25\"\u003e                                                                                                                                       | **Bash**       | Bash, the Bash VSCode extensions and Bash Jupyter kernel                              |\n\n### Tool Modules\n\n- **Vim**: Vim and the VSCodeVim extension\n- **QEMU, Docker and Kubernetes**: `kubectl`, `helm`, `k9s`, `skaffold`, `k3d` and more DevOps tools\n- **Technical Documentation**: `pandoc`, `plantuml`, `gnuplot`, media, Office, PDF and Markdown/LaTeX support for VSCode\n- **Full LaTeX Support**: Full TeX Live installation\n- **Web Development**: Protobuf, GraphQL, OpenAPI, browser debugging and more VSCode extensions\n- **Common VSCode Extensions**: Prettier, GitLens, Git Graph and test explorer VSCode extensions\n- **Common CLIs**: `tmux`, `jq`, `htop` etc.\n- **Networking**: Wireshark, `nmap`, `iperf3` etc.\n- **Browsers and Mail (TUI)**: `lynx`, `links`, `aerc` etc.\n- **Browsers and Mail (GUI)**: Chromium, Firefox, GNOME Web and Thunderbird\n- **Multimedia**: `ffmpeg`, Handbrake, `youtube-dl` etc.\n\n## Reference\n\n```shell\n$ pojdectl --help\npojdectl is the management tool for pojde.\nGlobal Flags:\n[-n]ode \u003cuser@host:port\u003e            Remote host to execute on.\n                                    If not specified, execute locally.\n\nModification Commands:\napply \u003cname\u003e \u003cstartPort\u003e            Create or upgrade an instance.\n    [-f]orce                            Skip confirmation prompts.\n    [-u]pgrade                          Pull latest image.\n    [-r]ecreate                         Re-create the container.\n    [-i]solate                          Block Docker daemon access.\n    [-p]rivileged                       Run in privileged mode.\nremove [name...]                    Remove instances(s).\n    [-f]orce                            Skip confirmation prompts.\n    [-c]ustomization                    Remove customizations.\n    [-p]references                      Remove preferences.\n    [-s]ecurity                         Remove CA.\n    [-u]ser data                        Remove user data.\n    [-t]ransfer                         Remove transfer data.\n    [-d]eb cache                        Remove .deb cache.\n    [-a]ll                              Remove everything.\nlist                                List all instances.\n\nLifecycle Commands:\nstart [name...]                     Start instance(s).\nstop [name...]                      Stop instance(s).\nrestart [name...]                   Restart instance(s).\n\nUtility Commands:\nlogs \u003cname\u003e                                                 Get the logs of an instance.\nenter \u003cname\u003e                                                Get a shell in an instance.\nforward \u003cname\u003e \u003clocal|remote\u003e [lhost:lport:rhost:rport...]  Forward port(s) to or from an instance.\n\nMiscellaneous Commands:\nupgrade-pojdectl                    Upgrade this tool.\nget-ca-cert [-p]rint                Get the CA cert.\nreset-ca [-f]orce                   Reset the CA.\n\nFor more information, please visit https://github.com/pojntfx/pojde#Usage.\n```\n\n## Contributing\n\nTo contribute, please use the [GitHub flow](https://guides.github.com/introduction/flow/) and follow our [Code of Conduct](./CODE_OF_CONDUCT.md).\n\nTo build and start a development version of pojde locally, run the following:\n\n```shell\n$ git clone https://github.com/pojntfx/pojde.git\n$ cd pojde\n$ make build\n$ ./bin/pojdectl apply my-first-instance 5000 -f -r\n```\n\nYou should now have the pojde services running on [http://localhost:5000/](http://localhost:5000/) through [http://localhost:5004/](http://localhost:5004/) (see [Accessing the Services](#5-accessing-the-services)). Whenever you change something in the source code, run `make build` and `./bin/pojdectl apply my-first-instance 5000 -f -r` again, which will recompile and restart the services.\n\nHave any questions or need help? Chat with us [on Matrix](https://matrix.to/#/#pojde:matrix.org?via=matrix.org)!\n\n## FAQ\n\n### Updates\n\n#### Updating `pojdectl`\n\n`pojdectl` includes a self-update tool, which you can invoke by running the following:\n\n```shell\n$ pojdectl upgrade-pojdectl\n```\n\n#### Updating (or Reconfiguring) an Instance\n\nUpdating an instance (to get the latest pojde version) and changing an instance's configuration are both done using the `pojdectl apply` command.\n\nTo for example update the instance created in [Usage](#usage) or to change it's configuration, installed modules etc., run the following and follow the instructions:\n\n```shell\n$ pojdectl apply my-first-instance 5000 -f -r -u # Append `-n root@your-ip:ssh-port` to upgrade the instance on a remote host instead\n```\n\nThere are multiple update and configuration strategies available; see [Reference](#reference) for more options.\n\n### Docker, Podman and CGroups V2\n\nThe following combinations are known to work:\n\n- Podman and CGroups V2\n- Docker and CGroups V1\n\nUsing Docker and CGroups V2 together on a systemd-based host does not work, as running systemd inside the container is not yet supported properly using this configuration. If you are using CGroups V2, i.e. if you're on Fedora, please use Podman. Alternatively, you can also switch to CGroups V1 and use Docker:\n\n```shell\n$ sudo grubby --update-kernel=ALL --args=\"systemd.unified_cgroup_hierarchy=0\"\n$ sudo reboot\n```\n\n### Mounting Docker Volumes from an Instance\n\nThanks to the `pojde-docker-env` script, mounting Docker volumes from within an instance is supported:\n\n```bash\npojntfx@5d084b2bf2ca:~$ pojde-docker-env # Run this in the instance, using i.e. `ttyd` or code-server's terminal\npojntfx@5d084b2bf2ca:/var/lib/docker/volumes/pojde-my-first-instance-home-user/_data/pojntfx$ # You can now use i.e. `docker run -v` in this shell!\n```\n\nYou can also block Docker daemon access completely by specifiying the `-i` flag; see [Reference](#reference) for more information.\n\n### Transfering Files in and out of an Instance\n\nThere are many options available to transfer files; you can for example use `scp`, another \"traditional\" option or use one of the following inbuilt ones.\n\n#### Transfer Folder\n\nA transfer folder is automatically created for even easier exchange of data between the host system and the instance; this folder is mounted into `~/Documents` in the instance and available at `~/Documents/pojde/your-instance-name` on the host system.\n\n#### WebWormhole\n\n[WebWormhole](https://webwormhole.io/) (available as `ww`) is pre-installed in every instance; it allows you to exchange files globally by using WebRTC. Find out more over at the [WebWormhole GitHub repo](https://github.com/saljam/webwormhole).\n\n## Further Resources\n\n- [Enabling IPv6 on Docker](https://gist.github.com/pojntfx/2f6a7b7db484ef5f3ac143edb5fd4618)\n- [Adding own root CA certificates on iOS](\u003chttps://support.apple.com/en-us/HT204477#:~:text=If%20you%20want%20to%20turn,Mobile%20Device%20Management%20(MDM).\u003e)\n\n## License\n\npojde (c) 2021 Felicitas Pojtinger and contributors\n\nSPDX-License-Identifier: AGPL-3.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpojntfx%2Fpojde","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpojntfx%2Fpojde","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpojntfx%2Fpojde/lists"}