{"id":15010873,"url":"https://github.com/haskell/play-haskell","last_synced_at":"2025-04-05T05:04:44.576Z","repository":{"id":66651613,"uuid":"593759768","full_name":"haskell/play-haskell","owner":"haskell","description":"Haskell Playground","archived":false,"fork":false,"pushed_at":"2025-03-24T18:21:36.000Z","size":740,"stargazers_count":136,"open_issues_count":23,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T04:05:23.688Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haskell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"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":"2023-01-26T19:24:23.000Z","updated_at":"2025-03-24T18:21:39.000Z","dependencies_parsed_at":"2023-03-01T02:45:14.083Z","dependency_job_id":"fee7ee67-a20d-46e7-a28c-7908bd31a68f","html_url":"https://github.com/haskell/play-haskell","commit_stats":{"total_commits":435,"total_committers":9,"mean_commits":"48.333333333333336","dds":0.2896551724137931,"last_synced_commit":"eb41340b59cb465325a2b7e457fa5390f097acb4"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fplay-haskell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fplay-haskell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fplay-haskell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fplay-haskell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haskell","download_url":"https://codeload.github.com/haskell/play-haskell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289426,"owners_count":20914464,"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":[],"created_at":"2024-09-24T19:36:52.341Z","updated_at":"2025-04-05T05:04:44.557Z","avatar_url":"https://github.com/haskell.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Haskell Playground\n\nThere's lots still to do, see\n[the issue list](https://github.com/haskell/play-haskell/issues) (as well as\n[TODO.txt](https://github.com/haskell/play-haskell/blob/master/TODO.txt) for some further ideas).\nIf you want to contribute, perhaps connect with me (either via an issue or on\n[IRC](https://wiki.haskell.org/IRC_channel)) before writing lots of code.\n\n## GHCup target platform\n\nBecause the GHCup installation from the host machine will be used as-is in the\ncontainers of the workers, and because said containers run Ubuntu, the desired\nGHC versions must be installed as follows with `ghcup`:\n\n    ghcup -p x86_64-deb10-linux install ghc 8.10.7\n\nThis ensures that the GHCs will work in the Ubuntu container. Note that\ncurrently (2022-08), Ubuntu GHCs seem to work fine on Arch Linux, for example.\n\n(This seems to be necessary with certain GHC versions only, and it's probably related to [GHC #22268](https://gitlab.haskell.org/ghc/ghc/-/issues/22268).)\n\n## Installation\n\n### System setup: Ubuntu\n\nNote: the worker needs bubblewrap 0.7.0, which is present in the Ubuntu repos\nonly from Ubuntu 23.04. If you're running an older version of Ubuntu (or\nanother system without version 0.7.0), build\n[bubblewrap](https://github.com/containers/bubblewrap) yourself.\n\n```bash\n# Note: earlyoom is only advised if you're deploying; not necessary on your local machine\nsudo apt update \u0026\u0026 sudo apt install earlyoom bubblewrap make npm jq\n# Change \"-r 60\" to \"-r 3600\" in /etc/default/earlyoom (less spammy logs)\nsudo systemctl restart earlyoom\n\nsudo apt install build-essential curl libffi-dev libffi7 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5 pkg-config\n# Install ghcup: https://www.haskell.org/ghcup/ (skip HLS and stack)\n# Open a new terminal to get ghcup in PATH\n```\n\n### System setup: Arch Linux\n\n```bash\n# Note: earlyoom is only advised if you're deploying; not necessary on your local machine\nsudo pacman -Syu earlyoom bubblewrap make npm jq\nsudo systemctl enable --now earlyoom\n\nsudo pacman -S base-devel\n# Install ghcup: https://www.haskell.org/ghcup/ (skip HLS and stack)\n# Open a new terminal to get ghcup in PATH\n# MAKE SURE TO INSTALL GHC FOR TARGET x86_64-deb10-linux\n# See above in the 'GHCup target platform' section\n```\n\n### Building the applications\n\n```bash\ngit clone https://github.com/haskell/play-haskell --recurse-submodules\ncd play-haskell\n```\n\nTo build the server (that hosts the website but doesn't run any user code):\n```bash\ncd play-haskell-server\nmake\ncabal build\n```\n\nTo build the worker (that the server will connect to, and that runs user code (in a sandbox)):\n```bash\ncd play-haskell-worker\nmake  # Or equivalently:\n      #   make chroot ; make bwrap-files/systemd-run-shim ; make builders\n      # 'make chroot' is interactive, select en_US.UTF-8.\n      # 'make builders' takes a long time because it builds all packages that should\n      #   be available on the playground with all GHCs you have installed with GHCup.\n      #   If you want just a few of those GHCs to work in the playground, manually run:\n      #     bwrap-files/mkbuildscript.sh 9.2.5\n      #     bwrap-files/mkbuildscript.sh 8.10.7\n      #   etc., once for each version you want to be available. Change available\n      # packages in bwrap-files/mkbuildscript.sh .\ncabal build\n```\n\nOptionally, if the machine you're building on does not have enough RAM, do this and use `cabal build -j1`:\n\n```bash\nsudo fallocate -l 4G /swapfile\nsudo chmod go-rw /swapfile\nsudo mkswap /swapfile\nsudo swapon /swapfile\n```\n\nDuring development:\n\n- `make frontend-dependencies` in `play-haskell-server/` whenever [play-haskell-server/static/package.json](https://github.com/haskell/play-haskell/blob/master/play-haskell-server/static/package.json) changes\n- `make frontend` in `play-haskell-server/` whenever some `*.ts` file for the frontend changes\n- `make reload-pages` in `play-haskell-server/` (or re-run `cabal run play-haskell-server`) to reload mustache pages (or send `SIGUSR1`)\n\n### Running the applications\n\nTo run the server: (all in `play-haskell-server/`)\n1. Put a good password in `adminpass.txt` (filename does not matter, but adjust below)\n2. `cabal run gen-secret-key -- secretkey.txt` (filename does not matter, but adjust below)\n    - Remember the public key that it prints, say `$SERVER_PUBKEY`\n3. Optional: put one or more lines of the form `{http://}hostname{:port} $WORKER1_PUBKEY` in `preload-workers.txt`, where the `{}` parts are optional (if not given, uses https on port 443); that `$WORKER1_PUBKEY` is produced by the steps to run a worker, see below\n4. `cabal run play-haskell-server -- --adminpassfile adminpass.txt --secretkey secretkey.txt --preloadworkers preload-workers.txt` (omit the `--preloadworkers` if you didn't do that step)\n5. See `cabal run play-haskell-server -- --help` for more info on options; the server listens with http on port 8123 by default\n\nTo run a worker: (all in `play-haskell-worker/`)\n1. `cabal run gen-secret-key -- secretkey.txt` (filename does not matter, but adjust below)\n    - Remember the public key that it prints, say `$WORKER1_PUBKEY`\n2. Put one or more `$SERVER_PUBKEY` in `trustedkeys.txt` (filename does not matter, but adjust below)\n2. `cabal run play-haskell-worker -- --secretkey secretkey.txt --trustedkeys trustedkeys.txt +RTS -N`\n3. See `cabal run play-haskell-worker -- --help` for more info on options; the worker listens with http on port 8124 by default, use a reverse proxy ssl terminator to get https\n\n### Server admin interface\n\nOn `example.com/admin` the server exposes a simple admin interface through which you can add and remove workers. If you don't want to add workers this way, use the `--preloadworkers` flag described above.\n\n## Storage\n\nPasted snippets are stored in an SQLite database in the file `pastes.db`.\n\n## API\n\nThe playground web client uses a simple API to submit jobs to the server; this API can also be used by others.\nBe aware that the server imposes simple IP-based rate-limiting on job requests; you might get back [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) responses if you submit too many jobs.\n\nThe API is as follows: `POST` to `/submit` on the playground server with the following JSON content:\n```jsonc\n{\n  \"code\": \"main :: IO ()\\nmain = print 42\",\n  \"version\": \"9.2.4\",  // or \"8.10.7\", or \"9.6.0.20230210\", etc.\n  \"opt\": \"O1\",  // \"O0\", \"O1\" or \"O2\"\n  \"output\": \"run\"  // \"run\", \"core\" or \"asm\"\n}\n```\n\nThe response will be a JSON object (with `Content-Type: text/json`) that has one of the following forms:\n```jsonc\n{\"err\": \"... an error message ...\"}\n```\nor\n```jsonc\n{\n  \"ec\": 0,  // exit code; 0 on success\n  \"ghcout\": \"\",  // stderr output from GHC; GHC warnings/errors end up here\n  \"sout\": \"42\\n\",  // stdout from the program, empty if it didn't get to run\n  \"serr\": \"\",  // stderr from the program, empty if it didn't get to run\n  \"timesecs\": 0.595881831  // time taken to run the job on the worker, excludes server queueing time\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaskell%2Fplay-haskell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaskell%2Fplay-haskell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaskell%2Fplay-haskell/lists"}