{"id":31769225,"url":"https://github.com/second-state/wasmedge-mysql","last_synced_at":"2026-08-02T22:31:16.330Z","repository":{"id":98615606,"uuid":"415159018","full_name":"second-state/wasmedge-mysql","owner":"second-state","description":"A repository which provides a MySQL persistent storage solution for the WasmEdge runtime","archived":false,"fork":false,"pushed_at":"2021-10-12T00:46:39.000Z","size":115,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-10T02:43:12.233Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/second-state.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-09T00:14:51.000Z","updated_at":"2023-09-09T13:35:55.000Z","dependencies_parsed_at":"2023-07-04T20:45:34.105Z","dependency_job_id":null,"html_url":"https://github.com/second-state/wasmedge-mysql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/second-state/wasmedge-mysql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/second-state%2Fwasmedge-mysql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/second-state%2Fwasmedge-mysql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/second-state%2Fwasmedge-mysql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/second-state%2Fwasmedge-mysql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/second-state","download_url":"https://codeload.github.com/second-state/wasmedge-mysql/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/second-state%2Fwasmedge-mysql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36210049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-08-02T02:00:06.915Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","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":"2025-10-10T02:42:08.608Z","updated_at":"2026-08-02T22:31:16.302Z","avatar_url":"https://github.com/second-state.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Use our ready-made MySQL service\n\nGood news!, if you would like persistent data in your wasmedge application, simply follow the usage examples below.\n\n# Usage\n\nThe wasmedge-mysql API will accept valid secure HTTP requests. Whilst the primary use case is to allow Javascript developers to have persistence in their WasmEdge apps, there is nothing stopping you from storing and loading data (even for testing) using any software which is capable of making secure HTTP requests (i.e. Python, Curl, Ruby, PHP). Below, we only provide explicit code examples of using Curl and Javascript.\n\n## Endpoints\n\n### /api/store\n\nStore raw bytes and receive a UUID to access that data in the future\n\n#### Curl example\n\n```bash\ncurl --location --request POST 'https://rpc.ssvm.secondstate.io:8888/api/store \\\n--header 'Content-Type: application/octet-stream' \\\n--data-binary '@/home/my_user/my_image_file_on_disk'\n```\n\n#### Javascript example\n\n```Javascript\nvar data = \"\u003cfile contents here\u003e\";\n\nvar xhr = new XMLHttpRequest();\nxhr.withCredentials = true;\nxhr.addEventListener(\"readystatechange\", function() {\n  if(this.readyState === 4) {\n    console.log(this.responseText);\n  }\n});\nxhr.open(\"POST\", \"https://rpc.ssvm.secondstate.io:8888/api/store\");\nxhr.setRequestHeader(\"Content-Type\", \"application/octet-stream\");\nxhr.send(data);\n```\n\n###\n\n###\n\n###\n\n\n---\n\nAs mentioned above, this MySQL service is already set up and ready for your requests. If you would like to set up your own service (on your own hardware) please proceed to the next section called \"Runing your own wasmedge-mysql\".\n\n---\n\n# Run your own wasmedge-mysql - optional\n\n## System requirements\n\nUbuntu 20.04 and above\n\n## Update system\n\n```bash\nsudo apt-get update\n```\n\n## Install MySQL\n\nInstall MySQL using package manager\n\n```bash\nsudo apt-get install -y mysql-server\n```\n\n**Just FYI:** In our case we are using an existing MySQL database installation. From here we will be creating a `second_server_data` directory and starting the existing MySQL software using different port and so forth.\n\nCreate new data directory\n\n```bash\nsudo mkdir -p /opt/second_server_data/\n```\n\nChange permissions and ownership\n\n```bash\nsudo chmod --reference /var/lib/mysql /opt/second_server_data/\nsudo chown --reference /var/lib/mysql /opt/second_server_data/\n```\n\nEdit apparmor configuration\n\n```bash\nsudo vi /etc/apparmor.d/usr.sbin.mysqld\n```\n\nAdd the following block anywhere between the two parenthesis\n\n```bash\n# Allow second server\n/opt/second_server_data/ r,\n/opt/second_server_data/** rwk,\n/var/run/mysqld/second_server.pid rw,\n/var/run/mysqld/second_server.sock rw,\n/var/run/mysqld/second_server.sock.lock rw,\n/run/mysqld/second_server.pid rw,\n/run/mysqld/second_server.sock rw,\n/run/mysqld/second_server.sock.lock rw,\n```\n\nRestart apparmor\n\n```bash\nsudo service apparmor restart\n```\n\n# Initialize new MySQL instance\n\n```bash\nsudo mysqld --initialize --user=mysql --datadir=/opt/second_server_data\n```\n\nTo find the new root password simply `tail` or `vi` the `/var/log/mysql/error.log` file \n\n```bash\ntail /var/log/mysql/error.log\n```\n\nYou will notice a line such as the one below (which tells you the new password)\n\n```\nA temporary password is generated for root@localhost: abcdnewpassword\n```\n\n# Secure the MySQL instance\n\n```bash\nsudo mysql_secure_installation --basedir=/opt/second_server_data\n```\n\n# Start new MySQL instance\n\n```bash\nsudo mysqld_safe --no-defaults --datadir=/opt/second_server_data --port=3315 --mysqlx=0 --socket=/var/run/mysqld/second_server.sock \u0026\n```\n\nLogging in, can be done via socket or via TCP\n\n```bash\nmysql --socket=/var/run/mysqld/second_server.sock -u root -p\n```\n\n```bash\nmysql -h 127.0.0.1 -P 3315 -u root -p\n```\n\nCreate new root password\n\n```mysql\nALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here';\nFLUSH PRIVILEGES;\n```\n\n# Create new database\n\n```mysql\nCREATE DATABASE wasmedge_db;\nuse wasmedge_db;\n```\n\n# Create new table\n\n```mysql\nCREATE TABLE wasmedge_data (\n    wasmedge_int INT(6) NOT NULL AUTO_INCREMENT,\n    wasmedge_id BINARY(16) NOT NULL,\n    wasmedge_blob LONGBLOB NOT NULL,\n    PRIMARY KEY (wasmedge_int)\n);\n```\n\n# Create new local user\n\n```mysql\nCREATE USER 'wasmedge_user'@'localhost' IDENTIFIED BY 'your_password_here';\nGRANT ALL PRIVILEGES ON wasmedge_db . * TO 'wasmedge_user'@'localhost';\nFLUSH PRIVILEGES;\nALTER USER 'wasmedge_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here';\nFLUSH PRIVILEGES;\n```\n\n# Fetch\n\n```bash\ngit clone https://github.com/second-state/wasmedge-mysql.git\ncd wasmedge-mysql\n```\n\n# Create config (`.env`) file\n\nOpen a new file called `.env`.\n\n```bash\nvi `.env`\n```\n\nPlace the following configuration in that file and save.\n\n```bash\nserver_name=rpc.ssvm.secondstate.io\nhost=0.0.0.0\nport=8888\n\ndb_host=localhost\ndb_port=3315\ndb_user=wasmedge_user\ndb_password=your_password_here\ndb_name=wasmedge_db\n```\n\nAutomatically install the npm packages that ship with this build's package.json file.\n\n```bash\nnpm install\n```\n\n# Start\n\n```bash\nnode index.js\n```\n\n# Start using forever\n\n```bash\nforever start index.js\n```\n\n---\n\n# Design discussion - number 3 currently in play\n\n## 1) Direct remote access - not recommended!\n\nAccessing the database remotely will always require the caller to have a mysql client. Further, it will require that the caller stores the password. Both of these facts make native remote access not practicable in a shared environment. Instead, we are going to implement a simple API which will accept secure HTTP requests and perform MySQL read/write transactions on behalf of the caller.\n\nYou could create a new external user like this ...\n\n```mysql\nCREATE USER 'wasmedge_remote_user'@'0.0.0.0' IDENTIFIED BY 'your_password_here';\nGRANT ALL PRIVILEGES ON wasmedge_db . * TO 'wasmedge_remote_user'@'0.0.0.0';\nFLUSH PRIVILEGES;\nALTER USER 'wasmedge_remote_user'@'0.0.0.0' IDENTIFIED WITH mysql_native_password BY 'your_password_here';\nFLUSH PRIVILEGES;\n```\nYou could test remote access like this ...\n\nDownload the MySQL client from [dev.mysql.com](https://dev.mysql.com/doc/refman/8.0/en/mysql.html).\n\nRun the following command on a remote machine\n\n```bash\nmysql -P 3315 -u wasmedge_remote_user -h 27.33.80.26 -p\n```\nHowever, the above direct remote access solution means that all users are sharing a common username and password.\n\n## 2) 3rd-party remote access - not ideal\n\nThere are many ways to expose MySQL over HTTP using 3rd-party software like [aceql](https://github.com/kawansoft/aceql-http). However these also require that you share/give passwords out to end users.\n\n## 3) In-house key:value store - working on this\n\nOne way to store data would be to allow the caller to store anything as a byte array i.e. a blob.\n\nThe following convention would need to be followed:\n- a user can make a secure HTTP request to store a blob i.e. anything as a byte array\n- the user is responsible encoding/decoding their data type to byte array and back again (depending on their application)\n- this allows us to store images natively etc (as apposed to only allowing JSON or String)\n- the API will always return a valid UUID when data is stored\n- the user will load their data using the UUID which the database provided\n\nHere are some examples of the internal SQL operations\n\nStoring a blob\n```SQL\nINSERT INTO wasmedge_data(wasmedge_id, wasmedge_blob) VALUES(UUID_TO_BIN(UUID()), the_byte_array);\n```\nReturns\n994d926e-2a3e-11ec-a87d-08719041559b\n\nLoading a blob\n```SQL\nSELECT wasmedge_blob FROM wasmedge_data where BIN_TO_UUID(wasmedge_id) = '994d926e-2a3e-11ec-a87d-08719041559b';\n```\n---\n\n# Shutdown database\n\nPlease use the following command to shutdown this database instance\n\n```bash\nsudo mysqladmin -h 127.0.0.1 -P 3315 -u root -p shutdown\n```\n\n# References\n\n- https://medium.com/@omkarmanjrekar/running-multiple-mysql-instances-on-ubuntu-4af059aad5ae","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecond-state%2Fwasmedge-mysql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecond-state%2Fwasmedge-mysql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecond-state%2Fwasmedge-mysql/lists"}