{"id":14235781,"url":"https://github.com/karlicoss/cloudmacs","last_synced_at":"2025-04-05T09:06:53.756Z","repository":{"id":49688228,"uuid":"207112933","full_name":"karlicoss/cloudmacs","owner":"karlicoss","description":"Selfhost your Emacs and access it in browser","archived":false,"fork":false,"pushed_at":"2023-04-14T23:35:03.000Z","size":36,"stargazers_count":541,"open_issues_count":4,"forks_count":30,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-03-29T08:06:31.086Z","etag":null,"topics":["docker","docker-emacs","emacs","gotty","gotty-docker","selfhosted","spacemacs"],"latest_commit_sha":null,"homepage":"https://beepb00p.xyz/cloudmacs.html","language":"Shell","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/karlicoss.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2019-09-08T12:58:40.000Z","updated_at":"2025-03-28T07:39:23.000Z","dependencies_parsed_at":"2024-11-18T01:20:05.900Z","dependency_job_id":null,"html_url":"https://github.com/karlicoss/cloudmacs","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/karlicoss%2Fcloudmacs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlicoss%2Fcloudmacs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlicoss%2Fcloudmacs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlicoss%2Fcloudmacs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karlicoss","download_url":"https://codeload.github.com/karlicoss/cloudmacs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312077,"owners_count":20918344,"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":["docker","docker-emacs","emacs","gotty","gotty-docker","selfhosted","spacemacs"],"created_at":"2024-08-20T21:02:20.989Z","updated_at":"2025-04-05T09:06:53.712Z","avatar_url":"https://github.com/karlicoss.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/karlicoss/cloudmacs)\n\n[Docker hub](https://hub.docker.com/r/karlicoss/cloudmacs)\n\nFor ages I've been seeking a decent browser frontend for my org-mode notes and todo lists. Until I realized that nothing prevents me from having emacs itself in my browser.\n\nSelfhost your Emacs with your favorite configuration.\n\n![Demo screenshot](https://user-images.githubusercontent.com/291333/64866462-26e25c80-d644-11e9-9ad5-ad9d9808b0cb.png)\n\n# Motivation\nSince I've became hooked on emacs, I've been looking for ways to have same experience in my browser.\nSometimes you have to use non-personal computers where it's not possible/undesirable to install desktop Emacs and Dropbox/Syncthing to access your personal data. \nSo I've been looking for some cloud solution since I've got a VPS.\n\nThe closest tool to what I wanted was [Filestash](https://github.com/mickael-kerjean/filestash): it supports vim/emacs bindings and some [org-mode goodies](https://www.filestash.app/2018/05/31/release-note-v0.1). However, it wasn't anywhere as convenient as emacs.\n\nDropbox is not capable of previewing arbitrary text files let alone edit; and even if it could you obviously wouldn't get anything close to your usual emacs workflow.\n\nAnd you could imagine that while elisp/vim style editing is fairly application [agnostic](https://github.com/brookhong/Surfingkeys#vim-editor-and-emacs-editor), it's a thankless job to rewrite/port all the amazing emacs packages and features I'm used to like neotree, helm, refile, swoop, agenda, projectile, org-drill etc.\n\nSo I figured the only thing that would keep me happy is to run emacs itself over the web! Thankfully, due to its TUI interface that works surprisingly well.\n\nIt works **really** well with spacemacs style `SPC`/`,` bindings because they for the most part don't overlap with OS/browser hotkeys.\n\n# How does it work?\n[Dockerfile](Dockerfile) has got some comments and should be straightforward to follow, but in essence:\n\n1. [Gotty](https://github.com/yudai/gotty) is a tool that allows accessing any TTY app as a web page (also allows forwarding input)\n2. We use Gotty to run `emacsclient --tty -a ''` command, that connects to the existing Emacs instance or starts a new one. That makes the session persist tab closes, connection problems etc.\n3. Your Emacs configs and files you want to expose to Cloudmacs are mapped in `docker-compose.yml` file.\n\n\n# Try it out locally \n1. `cp docker-compose.example.yml docker-compose.yml`\n2. Edit necessary variables in `docker-compose.yml`, presumably your want to\n   * map the files you want to make accessible to container\n   * map the path to your config files/directories (e.g. `.emacs.d` or `.spacemacs`/`.spacemacs.d`). Also check the 'Setting up Spacemacs' section!\n   * change port (see 'selfhost' section)\n3. Run the container: `./compose up -d`.\n4. Check it out in browser: 'http://localhost:8080'.\n\n# Setting up Spacemacs\nSpacemacs doesn't use `init.el`, instead you have `~/.spacemacs.d` directory, and `~/.emacs.d` serves as Spacemacs distribution.\nI **don't** recommend you to reuse `~/.emacs.d` your OS emacs distribution will generally be different from containers, \nand who knows what else could it break. Instead just clone spacemacs in a separate dir and map it.\n\nOn your Host OS:\n\n```\ngit clone https://github.com/syl20bnr/spacemacs.git -b develop ~/.cloudmacs.d\ncd ~/.cloudmacs.d \u0026\u0026 git revert --no-edit 5d4b80 # get around https://github.com/syl20bnr/spacemacs/issues/11585\n```\n\nIn your `docker-compose.yml`, add:\n```\n    volumes:\n      - ${HOME}/.cloudmacs.d:/home/emacs/.emacs.d\n```\n\n# Customize\nSome packages need extra binaries in the container (e.g. `magit` needs `git`). There are to ways you can deal with it\n\n1. Extend cloudmacs dockerfile and mix in the packages you need: see [my example](Dockerfile.customized), where I'm extending the container with git and ripgrep.\n   Then you can build it, e.g.:\n   ```\n   docker build -f Dockerfile.customized -t customized-cloudmacs --build-arg RIPGREP_VERSION=\"11.0.2\" .\n   ```\n   Don't forget to update `docker-compose.yml` with the name of your new container.\n\n2. Install packages directly on running container. The downside is that it's easy to lose changes if you delete the container. \n   Unfortunately docker-compose file [doesn't support](https://github.com/docker/compose/issues/1809) post-start scripts\n   so if you want to automate this perhaps easiest would be to write a wrapper script like this:\n   ```\n   #!/bin/bash -eux\n   docker-compose up -d\n   docker exec cloudmacs sh -c \"apk add --no-cache git\"\n   ```\n \n# Selfhost\n* I use basic auth to access my container.\n* Set up reverse proxy to access Gotty. Steps may vary depending on your web server, but for my nginx it looks like that:\n  ```\n  location / {\n      proxy_set_header X-Real-IP $remote_addr;\n      proxy_set_header X-Forwarded-For $remote_addr;\n      proxy_set_header Host $host;\n      proxy_http_version 1.1;\n      proxy_pass http://localhost:8888;\n      proxy_set_header Upgrade $http_upgrade;\n      proxy_set_header Connection \"upgrade\";\n  }\n  ```\n\n\n# Potential improvements\n* split rg/locales/gotty in separate docker containers? maybe locales could be somehow moved to original emacs container?\n  * also, after splitting it would be easy to make setup more generic and let people run vim/neovim, since the setup is pretty editor agnostic\n\n# Limitations\n* Mobile phones -- you'd struggle to use default emacs/spacemacs on touchscreens. Perhaps there is some special phone friendly config out there?\n  Anyway, I tend to use [orgzly](https://github.com/orgzly/orgzly-android) on my Android phone.\n\n# Credits\n* [dit4c/dockerfile-gotty](https://github.com/dit4c/dockerfile-gotty)\n* [JAremko/docker-emacs](https://github.com/JAremko/docker-emacs)\n* [JAremko/browsermax](https://github.com/JAremko/browsermax). It's pretty similar but Dockerfile is quite complicated, looks like they are trying to use X11 for some reason, whereas I'd be perfectly happy with `emacsclient --tty`.\n* [raincoats/nginx.gotty.proxy](https://github.com/raincoats/nginx.gotty.proxy)\n\n# License\nGPL due to the fact that I looked at other GPL licensed dockerfiles as reference.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarlicoss%2Fcloudmacs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarlicoss%2Fcloudmacs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarlicoss%2Fcloudmacs/lists"}