{"id":13990505,"url":"https://github.com/mikadosoftware/workstation","last_synced_at":"2025-07-22T12:32:57.015Z","repository":{"id":144988967,"uuid":"138070951","full_name":"mikadosoftware/workstation","owner":"mikadosoftware","description":"Docker based portable Workstation","archived":false,"fork":false,"pushed_at":"2024-12-25T12:43:50.000Z","size":2525,"stargazers_count":492,"open_issues_count":15,"forks_count":21,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-12-25T13:35:44.175Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikadosoftware.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.rst","authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-20T18:28:07.000Z","updated_at":"2024-12-25T12:43:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"7a861726-eea3-4479-8d54-5f5e87878ef2","html_url":"https://github.com/mikadosoftware/workstation","commit_stats":{"total_commits":54,"total_committers":1,"mean_commits":54.0,"dds":0.0,"last_synced_commit":"9c8b19bc5d6c596843da30f58f1dad6a60c7e989"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mikadosoftware/workstation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikadosoftware%2Fworkstation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikadosoftware%2Fworkstation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikadosoftware%2Fworkstation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikadosoftware%2Fworkstation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikadosoftware","download_url":"https://codeload.github.com/mikadosoftware/workstation/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikadosoftware%2Fworkstation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266496336,"owners_count":23938710,"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-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":[],"created_at":"2024-08-09T13:02:50.323Z","updated_at":"2025-07-22T12:32:56.676Z","avatar_url":"https://github.com/mikadosoftware.png","language":"Python","readme":"============================\nDocker Immutable Workstation \n============================\n\nThe concept of an *immutable server* for production deployment is now\nfully mainstream, but the same concepts underpinning servers is less\napplied to the workstations on which the developers work.\n\nWe have a tendency to start with a nice clean laptop, a Mac if we are\nlucky, and slowly but surely *stuff* creeps on, dependencies we did\nnot know about appear and we stop trusting the platform we stand on.\n\nSo I have used Docker to make my own *immutable workstation*.  It\nmeans that I get *exactly* the same stack running on my\nbanged-about-on-commute laptop, my wife's nice big screen iMac and\neven on my client's Windows box, that I had to use for client's policy\nreasons.  So wherever I was, I was using the same config of emacs -\nusing it on a windows machine or a mac or a Linux host, it was the\nsame emacs, and the same nice set of tools like grep.  And it was\nrunning XWindows in those places too.\n\nSecondly, I get the ratchet effect of continuously improving security\n- I can always improve something on the install, and just rerun\n`docker build` and I have permanently remembered to fix that security\nhole wherever I build my workstation.\n\nI have 'improved' the approach (this is many years old now), so that\nI run a complete desktop on docker, and VNC into it, from my local machine.\nTHis simplifies things like looking at pdfs or html files built on the machine\nplus simplifies things like keeping my local machine updated - I can live without \nalmost any 'new stuff' on the local laptop.\n\n\nSo, *anything* that changes I keep in\nsource control (here in this repo) and my secrets are all stored on a\nUSB key that I carry with me and plugin to the host - so my GitHub ssh\nkey is on a USB stick, that when I plug it in, .\n    \n\nDocumentation can be found at https://workstation.readthedocs.io/en/latest/\n\n::\n\n    `immutableworkstation` can create docker images from config, and\n    launch those images so that as a developer you can work inside the\n    container, but using X-applications on the host laptop.\n\n    So you can define your workstation in code, but take it with you\n    from laptop to home to work.\n\n\nUsing X Windows\n===============\n\nThe *essential* parts of this approach are hard to dig out from Google\nsearches, but I hope this makes them clearer - the below code will\nproduce a working local docker instance, ssh into it and display an\napp *from* docker but *on* the host desktop.\n\nWe build a X11 capable docker image ::\n\n    FROM ubuntu:18.04\n    \n    RUN apt-get update \u0026\u0026 \\\n        apt-get install -y openssh-server \\\n                           x11-apps                       \n\n    RUN mkdir -p /var/run/sshd                     \n    RUN echo 'root:root' | chpasswd \n    RUN sed -ri 's/^#PermitRootLogin\\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config\n    RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config\n    RUN sed -ri 's/^#AllowTcpForwarding\\s+.*/AllowTcpForwarding yes/g' /etc/ssh/sshd_config\n    RUN sed -ri 's/^#X11Forwarding\\s+.*/X11Forwarding yes/g' /etc/ssh/sshd_config\n    RUN sed -ri 's/^#X11UseLocalhost\\s+.*/X11UseLocalhost no/g' /etc/ssh/sshd_config\n\n    EXPOSE 22\n    CMD [\"/usr/sbin/sshd\", \"-D\"]\n\nWe then build the above image::\n\n    # sudo docker build -t devbox:latest .\n\nNow run it, listening on the localhost port of 2222, which is then\nmapped to 22 on the container::\n\n    # docker run -d  --name devbox-live -v /data/projects:/projects -p 2222:22 devbox:latest\n    \nwe should now have a running container listening on port 2222\n\nSo we can ssh tunnel into the container using::\n\n    # ssh -X root@localhost -p 2222\n\nThere may be some faffing with .XAuthority files. Ignore that for now.\nBut we should then be able to run ::\n\n   # xeyes \n\non the container, and it will appear on the laptop we are running on.\n\n#TODO: screenshot \n\nUsing Sound\n===========\n\nThere is a developer who (I think) works for Docker and has a list of\nYouTube videos showing how to do things like run Skype on Docker.  She\ndeveloped a `snd` device parameter for `docker run`, which seems to\nwork fine. I don't do much with it but should expand on it.\n\nUsing Secrets\n=============\n\n\n/etc/fstab on host machine::\n\n\n    # /etc/fstab: static file system information.\n    ....\n    UUID=ed74f120-1736-4f59-8752-06098a635c16 /home/pbrian/secrets/usb   ext4  user,rw,auto,nofail  0   0\t\n    ...\n\n    I used `sudo blkid` to get the UUID for that specific USB key.\n    \n    It is then automounted to my home dir, where docker will make it\n    visible in the docker instance, and I get to use the ssh keys on\n    the USB stick to authenticate to, for example, github.\n\nUsing Dropbox\n=============\n\nI have some files I keep on private GitHub repos, but for most\ndocuments (things like Bank statements) it seems easier to just store\nthem on Dropbox.  I merely have my Dropbox folder on my home dir, and\nmount it into Docker.  It seems to work with no horrible clashes so I\nwill keep it. At some point it seems sensible to migrate to having the\nDropbox client actually running on the docker instance.\n\nIts not terribly secure, but it seems good enough.\n\nWhy is this good?\n-----------------\n\nQuite simply, I can easily control the dev environment, rebuild it at\nwill, and run programs \"on my laptop\" when they are not installed or\nconfigured on the laptop.\n\nIn fact I think the best part of this is configuration for my *whole*\ndev machine is stored on GitHub, and can be re-created anywhere\neasily.\n\nWith the volume mounted, I can then use emacs / console running inside\na container, and adjust files that are stored on my local laptop.\n\nI then have a consistent dev environment \n\nAlso, I can easily rebuild it\n\nAlso I can spin up a microservice on laptop that also points at the\nsame volume, and it will thus be using the code I just developed\n\nThis works even if I change underlying OS - which is good for\nwandering contractors like me.\n\nTODO::\n\n  #TODO:: allow two workstations on same host, so I can play / verify changes\n  #TODO:: get dropbox installed on docker instance\n\n\nBuilding on Mac OS\n------------------\n\nYou will need a XServer running on the Mac.  I recommend using XQuartz\n- this will need to be installed and running before starting the ssh\n-X process so the ssh session can connect to something\n\nRoadmap\nSee `Roadmap \u003cdocs/roadmap.rst\u003e`_\n\n","funding_links":[],"categories":["Python","Virtualization"],"sub_categories":["Containers"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikadosoftware%2Fworkstation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikadosoftware%2Fworkstation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikadosoftware%2Fworkstation/lists"}