Fixing your Doltlab instance with db-shell
There's lots of ways to use Dolt, the world's first version controlled SQL database:
- You can run Dolt locally and manage your DB with our Git-like command line interface.
- You can run Dolt as a drop-in replacement for your MySQL server.
- You can use DoltHub, our free and public service for hosting Dolt remotes.
- You can use Hosted Dolt and get your very own version controlled SQL server that we manage for you.
- Or, you can self-host your own remote with DoltLab.
There's no wrong answer. I'm the kind of guy who likes self-hosting, because I like feeling in control of my data. And while it's true that self hosting means a lot more responsibility for any issues that might come up, it also gives me the maximum power to fix those issues.
Most issues can be fixed directly from the DoltLab admin panel. But what if you don't have access to the admin panel? In that case, you may need to connect directly to the underlying database to fix a problem.
Accidental Lock-Out
Last month, I accidentally locked my account on my local DoltLab instance by entering an incorrect password too many times. DoltLab Enterprise has a workflow for resetting passwords by sending a link to the account's registered email address, but that requires an SMTP server to be configured and I am only using the free version of DoltLab, so that was a non-starter. As a backup plan, the DoltLab v2.2.0 blog mentioned that server admins can reset passwords from the admin panel. There was only one problem: the admin was me. The account I had locked out was the admin account.
It was essentially this.
I knew that this was fixable in theory: the server was running locally in a box in my basement, and I had root privileges. So I connected to the machine over SSH and started poking around.
DoltLab isn't a single piece of software: it's actually multiple isolated services running in Docker containers:
- doltlabapi: The core DoltLab API.
- doltlabdb: The database that backs DoltLab, containing user accounts and settings, pull requests, etc.
- doltlabenvoy: The Envoy proxy that web requests connect to.
- doltlabfileserviceapi: The server for managing uploaded files to DoltLab.
- doltlabgraphql: The GraphQL server.
- doltlabremoteapi: The server for handling remote operations on hosted Dolt repos (push, pull, etc).
- doltlabui: The web server for the DoltLab web interface.
Why Docker?
Using Docker this way allows each component to run in isolation from each other and from the host machine, each with their own dependencies. It guarantees that changes to the running environment of the host or of one service has no effect on the other services. Docker also has security benefits: runs each of these processes on a private virtual network, tightly controlling how other processes on the host can interact with these services.
Fortunately, you don't need to think about Docker because Doltlab provides some helper scripts to connect to these services. The helper script that we care about here is called shell-db.sh
, and is found in the doltlabdb
directory of your DoltLab environment. Running this shell script will connect you the SQL database used by DoltLab.
$ ./doltlabdb/shell-db.sh
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 352
Server version: 8.0.33 Dolt
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
In the spirit of "eating our own dogfood", DoltLab stores its data in a Dolt repo, as we can tell from the reported version string.
The account was locked because I had too many incorrect password attempts. So I can restore access by deleting the records of those failed attempts. Failed password attempts are stored in the password_attempts
table:
mysql> show create table password_attempts;
+-------------------+-------------------------------------------------------------------+
| password_attempts | CREATE TABLE `password_attempts` ( |
| | `id` varchar(36) NOT NULL, |
| | `user_id_fk` varchar(36) NOT NULL, |
| | `event_type` int, |
| | `ip_address` varchar(255), |
| | `user_agent` varchar(3096), |
| | `created_at` timestamp(6), |
| | PRIMARY KEY (`id`), |
| | KEY `password_attempts_user_id_fk` (`user_id_fk`,`created_at`), |
| | KEY `user_id_fk` (`user_id_fk`), |
| | CONSTRAINT `password_attempts_ibfk_1` |
| | FOREIGN KEY (`user_id_fk`)REFERENCES `users` (`id`) |
| | ON DELETE CASCADE |
| | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin |
+-------------------+-------------------------------------------------------------------+
We could delete all records in the table, but this would reset the password attempts for everyone. Instead, let's only want clear the login attempts for a single account. Unfortunately, there's no human-readable username field, only user_id_fk
, which is a UUID. So before we can unlock the locked account, we need to figure out the UUID corresponding to the account.
mysql> select id from users where name = "admin";
+--------------------------------------+
| id |
+--------------------------------------+
| 625dfd53-2160-4d36-9fe4-9e1f468d7ddc |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> delete from password_attempts where user_id_fk = '625dfd53-2160-4d36-9fe4-9e1f468d7ddc';
Query OK, 3 rows affected (0.01 sec)
And then we're good to go! With my prior mistake erased from history, I could once again log in, making sure to use the correct password this time. We added a section to the DoltLab documentation for the event that anyone else ends up in this situation.
Conclusion
That's all for today! Ideally, you should never need to touch the database like this. We take user experience very seriously and strive to make DoltLab as user friendly as possible, and that means a polished web interface that lets you do what you want, when you want. If you ever have an issue with DoltLab's web interface, or a feature request, or if you just want to ask us a question, join our Discord and we'll make your Dolt experience the best it can be.