{"id":25895247,"url":"https://github.com/dpbm/qserver","last_synced_at":"2026-04-12T19:26:38.552Z","repository":{"id":279144563,"uuid":"915723751","full_name":"Dpbm/qserver","owner":"Dpbm","description":"A server to run your quantum jobs locally","archived":false,"fork":false,"pushed_at":"2025-04-11T14:12:49.000Z","size":1596,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T15:27:33.244Z","etag":null,"topics":["docker","docker-compose","golang","pennylane","python","qiskit","qserver","quantum","quantum-algorithms","quantum-circuits","quantum-computing","quantum-server","rabbitmq","server"],"latest_commit_sha":null,"homepage":"","language":"Go","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/Dpbm.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2025-01-12T16:30:58.000Z","updated_at":"2025-04-11T14:12:52.000Z","dependencies_parsed_at":"2025-02-24T03:24:53.076Z","dependency_job_id":"75adaec3-2e83-45db-a313-6a2c52408fc7","html_url":"https://github.com/Dpbm/qserver","commit_stats":null,"previous_names":["dpbm/qserver"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Dpbm/qserver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dpbm","download_url":"https://codeload.github.com/Dpbm/qserver/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqserver/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265297030,"owners_count":23742585,"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-compose","golang","pennylane","python","qiskit","qserver","quantum","quantum-algorithms","quantum-circuits","quantum-computing","quantum-server","rabbitmq","server"],"created_at":"2025-03-02T22:30:11.412Z","updated_at":"2026-04-12T19:26:38.532Z","avatar_url":"https://github.com/Dpbm.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QServer\n\n![Test parts](https://github.com/Dpbm/qserver/actions/workflows/tests.yml/badge.svg)\n![(Test) Publish workflows](https://github.com/Dpbm/qserver/actions/workflows/test-publish.yml/badge.svg)\n![Release](https://github.com/Dpbm/qserver/actions/workflows/release.yml/badge.svg)\n\nAn entire setup to run your quantum circuits in a separated machine.\n\n## Why?\n\nThe main reason for this project was a problem I had during my first scientific research.\n\nAt that time, I had to run many different experiments, and most part of them were time-cost. Due to that, always when I needed to run some experiment, it was sure that I was unable to do anything else on my computer.\n\nYou may think, \"why Didn't You upload your jobs to IBM QPUs or something similar\". Well, there're some reasons:\n\n1. errors\n\nEven though my projects took to long to run, they had up to 30 qubits, so running these small experiments on QPUs with 100+ qubits were prone to errors caused by the idle ones. Probably, there were some techniques to reduce them, but I had no time to deep dive on that at that moment.\n\n2. free QPUs\n\nEven though IBM has many different quantum systems available, only a tiny portion of them are free available. I'm not saying this approach is unfair, once these machines are very expensive and complicated to maintain. However, as an undergrad student, I had not access to the systems I needed for my research.\n\n3. long queues\n\nWhen submitting a job to IBM's infrastructure, it's not always you get you job running right away, most part of the time you need to wait for days to get your results.\n\n---\n\n\nI'm not saying that using these cloud providers are bad, but there's always some trade-offs you'll face.\n\nAlso, for experiments aiming to test hardware and quantum algorithms in real scenarios, submitting to a real hardware is always the best idea.\n\n## QServer is for who?\n\nSaying the reasons I've built qserver, here's a list of who can be  beneficiated by using this:\n\n- Curious people who wants to run circuits while learning\n- People with limited hardware but have access to better machines \n- Homelab lovers\n- Quantum computing enthusiasts \n\n\n## How does it work?\n\nThis project is developed as multiple services orchestrated via docker compose.\n\nIts structure follows the diagram bellow:\n\n![architecture](./assets/arch.jpg)\n\nAfter developing your circuit, all data related to it is send to the server via GRPC/Protobuf and a job is added to a rabbitmq queue waiting to be executed by a worker. When a job is finished, all data is saved on a postgres database and it can be retrieved using the http API.\n\n![services](./assets/services.jpg)\n\nInternally, there're are two main pieces: A GRPC server and a HTTP server. To make it easier to connect, a NGINX reverse proxy is put before those services, letting access different services using the same IP/host and also configuring TLS.\n\nBy default, the NGINX proxy listen on ports 8080(http/GRPC) and 443(https/GRPC+TLS) and a static IP is set, being: `172.18.0.30`.\n\n---\n\nTo actually run a job, you must have had pre installed a quantum plugin. You can find the available ones [here](https://github.com/quantum-plugins/plugins-list).\n\nIf you want to some plugin that doesn't exist yet, you can create your own using [this template](https://github.com/quantum-plugins/quantum-server-plugin-template) and them opening an issue on [quantum-plugins/plugins-list](https://github.com/quantum-plugins/plugins-list). Your plugin will be added as a fork into our organization and listed on the main repo.\n\nThe admission for plugins works as the following:\n\n![plugin admission](./assets/plugin-admission.jpg)\n\nIt's not required to publish your plugin to PYPI, but you're free to do that.\n\n---\n\nOnce a plugin is requested by a worker, it will be downloaded, if it exists, and the process will continue.\n\n![workflow](./assets/plugin-flow.jpg)\n\n---\n\nWith the backend in hands, the circuit is ready to run.\n\nYou can request the server to extract multiple types of results. The options you have are: `expval`, `counts` and `quasi_dist`.\nThe job is run iteratively till all result types are gotten.\n\nDoing that, the data is saved on a Postgres DB.\n\nYou can see the Structure below:\n\n![database diagram](./assets/database.jpg)\n\n## How to use?\n\nTo run all that, you must install docker along with docker compose. Then get the compose file you want:\n\n```bash\n\n# http version\nwget https://raw.githubusercontent.com/Dpbm/qserver/refs/heads/main/compose.yml\n# https version\nwget https://raw.githubusercontent.com/Dpbm/qserver/refs/heads/main/compose-https.yml\n\n# or\n\n# http version\nwget  https://raw.githubusercontent.com/Dpbm/qserver/refs/heads/main/ghcr-prod-compose.yml\n# https version\nwget  https://raw.githubusercontent.com/Dpbm/qserver/refs/heads/main/ghcr-prod-compose-https.yml\n```\n\nThen, you must set some env variables to configure the services access:\n\n```bash\nexport DB_USERNAME=\"your user for db\"\nexport DB_PASSWORD=\"you db user password\"\nexport DB_ROOT_USER=\"root username\"\nexport DB_ROOT_PASSWORD=\"root db user password\"\nexport RABBITMQ_USER=\"rabbitmq username\"\nexport RABBITMQ_PASSWORD=\"rabbitmq password\"\nexport DOMAIN=\"your domain\" # it can be arbitrary if not using HTTPS or running in local environments\n```\n\n`Note: Remember to not use hard set env variables in production. Use your cloud provider secure alternative`\n\n\nUsing HTTPS is not mandatory, but we recommend you doing that. In case you're going to setup HTTPS, there's a script to setup your certs using `certbot`. Doing that is, sometimes, very trick, so I'm letting here the setup I did in my environment, but remember to check [let's encrypt documentation](https://letsencrypt.org/docs/) and [certbot's](https://certbot.eff.org/) as well.\n\nIn my case, I bought a real domain that can be reach outside on the internet and them used certbot to generate the certificates. \n\n```bash\n# install certbot (check: https://certbot.eff.org/instructions?ws=nginx\u0026os=pip)\nsudo apt update \u0026\u0026 sudo apt install python3 python3-venv libaugeas0\nsudo pip install certbot \n\n# get and run the script\ncd /tmp\nwget https://raw.githubusercontent.com/Dpbm/qserver/refs/heads/main/certs/generate-certs.sh\nchmod +x ./generate-certs.sh \u0026\u0026 ./generate-certs.sh your-domain\n```\n\nDoing that, certbot will request you to add some information and then adding a acme challenge via DNS. Check your provider's documentation to see how to add that.\nBy the end of this process, certbot will generate the `.pem` files and will store that at `/etc/letsencrypt/archive/{your-domain}/`. This location is going to be mounted inside docker when running, so you don't need to do anything else.\n\nOnce we are running on a local network, it's not possible to access the domain right away. So to run:\n\n```bash\nsudo echo \"172.18.0.30 your-domain\" | sudo tee -a /etc/hosts\n```\n\nIt's not required for cloud providers, by for local running it's a good option.\n\nIf you have this server running in the same network, but on a different machine, make the mapping using the other computer's IP.\n\nSetting this up, we can run the docker compose file as:\n\n```bash\n# for dockerhub images\ndocker compose -f ./compose-https.yml up -d \n\n# for ghcr images\ndocker compose -f ./ghcr-prod-compose-https.yml up -d\n```\n\nAfter some minutes, the server is ready to be used. You can check its API endpoints at: `http://your-domain:8080/swagger/index.html`, `https://your-domain/swagger/index.html` or even `http://172.18.0.30:8080/swagger/index.html` (remember this IP may change depending on where you're running it).\n\n![swagger](./assets/swagger.png)\n\nBeside these routes, the GRPC service run at the root path `/`. So, to add jobs this path must be used.\n\n---\n\nA more easy way to interact with your server is using the python client library we built. You can find the details about it [here](https://github.com/Dpbm/qserver-connect).\n\nWith it, you can submit and retrieve jobs in your current python project, without handling http/grpc requests by hand.\n\n## Dev Usage\n\nFor devs, there's a bunch of different tools you may have installed to run each part isolated here are some of the main tools you need:\n\n* make\n* python \u003e= 3.12\n* go\n* curl\n* grpcurl\n* mamba/conda-lock/conda\n* pip/pip3\n* bash/sh\n* docker/docker compose\n* openssl\n\nIf you're using Ubuntu based distros, there's a script to install some dependencies easily.\n\n```bash\nchmod +x install-system-dev-dependencies.sh\n./install-system-dev-dependencies.sh\n```\n\nIt doesn't install docker and python, go, conda and docker, so make sure to install it yourself.\n\n---\n\nWhen you need to run something with the dev-compose config, the env values are set using majorly .env files. In the repo there're some examples you can use.\n\nIn case you need something different, update the .env files or the dev-compose as you need.\n\n### Janitor as Dev\n\nJanitor is a small script to delete logs and qasm files after some predetermined time using cron jobs.\n\nTo run the tests first create a python environment:\n\n```bash\ncd ./janitor\n\n# example with mamba\nmamba env create -f environment.yml\nmamba activate janitor\n\n# conda-lock example\nconda-lock install -n janitor conda-lock.yml\nmamba activate janitor\n\n# pip installation\npip install -r dev-requirements.txt\n```\n\nThen run: \n```bash\ntox\n```\n\n\n### Proxy as DEV\n\nTo test the proxy instance, you first need to run the proxy itself. You can use the dev-compose file to set it up, but first, remember to set up your domain certs.\n\n```bash\ncd ./certs\n\nexport DOMAIN=\"your domain\"\nchmod +x generate-certs.sh\n./generate-certs.sh \"$DOMAIN\"\n```\n\nthen:\n\n```bash\ncd ..\n# remember that the DOMAIN env variable must be set\ndocker compose -f ./dev-compose.yml up -d --build proxy\n```\n\nAfter some instants running, you'll be able to run the proxy tests with:\n\n```bash\ncd ./proxy\nchmod +x test.sh\n# remember that the DOMAIN env variable must be set\n./test.sh\n```\n\nYou can also change it to run the http version, just update the `dev-compose.yml` file.\n\n### GRPC server as DEV\n\nFirst of all, install the go dependencies:\n\n```bash\ncd ./server/jobsServer\nmake install\n```\n\nThen, to test your GRPC server, first you need to make it run. You can do that using it locally on your machine, or inside docker.\n\nThe former can be done running:\n\n```bash\ndocker compose -f ./dev-compose.yml up -d --build queue-handler db\ncd ./server/jobsServer/\nmake run\n```\n\nand the latter:\n\n```bash\ndocker compose -f ./dev-compose.yml up -d --build jobs-server\n```\n\nFinally, you can run the script to execute the tests\n\n```bash\ncd ./server/jobsServer/\n\n# for local running instance\nmake test-local \n\n# for docker running instance\nmake test-docker\n```\n\n---\n\nIf you need to update the protobuf definition, also run:\n\n```bash\nmake proto\n```\n\nto generate the new grpc go definition files.\n\n---\n\nRemember to lint the code as well:\n\n```bash\nmake lint\n```\n\n### API as DEV\n\nThe rest api has the same logic as the GRPC server:\n\n\n```bash\n# install dependencies\ncd ./server/restAPI\nmake install\n\n--------------------------------------------------\n\n# run locally\ndocker compose -f ./dev-compose.yml up -d --build db\ncd ./server/restAPI/\nmake run\n\n# run with docker\ndocker compose -f ./dev-compose.yml up -d --build api\n\n--------------------------------------------------\n\n\n# tests for local instance\nmake test-local\n\n# test for docker instance\nmake test-docker\n\n--------------------------------------------------\n\n# linting\nmake lint\n```\n\nhowever, in the case you updated some routes, you'll likely want to update swagger definitions. For that, run:\n\n```bash\nmake swagger\n```\n\n\n### Worker as DEV\n\nThe Worker, is a python script, so to run that the dependencies:\n\n\n```bash\ncd ./server/worker\n\n# example with mamba\nmamba env create -f environment.yml\nmamba activate worker\n\n# conda-lock example\nconda-lock install -n janitor conda-lock.yml\nmamba activate worker\n\n# pip installation\npip install -r dev-requirements.txt\n```\n\nStart the worker instance:\n\n```bash\n# locally\ndocker compose -f ./dev-compose.yml up -d --build queue-handler db\ncd ./server/worker\nmake run\n\n# with docker\ndocker compose -f ./dev-compose.yml up -d --build workers\n# notice that you can change the amount of workers running by changing the\n# number of replicas in the compose file\n```\n\n---\n\nTo test your worker, you don't necessarily needs it running. You just need your python environment and then run:\n\n```bash\ncd ./server/worker\ntox\n```\n\n\n\n### Other stuff\n\nThere're some other things you can check and may help me improve, like the database setup which can be found [here](./server/database/) and the shared library used for both http and grpc servers, being found [here](./server/shared/).\n\n\n## Contribute\n\nFeel free to open an Issue or even open a pull request to help this project evolve.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpbm%2Fqserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdpbm%2Fqserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpbm%2Fqserver/lists"}