- About the Project
- Documentation
- Getting Started
- Usage
- Development
- Roadmap
- Contributing
- FAQ
- License
- Contact
- Acknowledgements
Warning: Use at your own risk. Please acknowledge for what you are copying and what you are using it for.
- Easy to install packages: one command sets up a whole machine.
- Safe to run again and again. Every script detects finished work and skips it, so you can re-run after a failure or after changing the repository.
- Nothing is lost. Existing files are backed up before they are replaced,
or replaced directly with
--no-backup. - Preview first with
--dry-run: it prints every change and makes none. - Secure your dotfiles in the
privatefolder (encrypted withgpg). - Easy to add your specific tools, see Adding a tool.
- Written in TypeScript and run with bun.
| Read this | When you want to |
|---|---|
| docs/getting-started.md | Set up a machine end to end: preview, run, verify, update, undo |
| docs/recipes.md | Copy-paste solutions: add a tool, undo, servers, CI |
| docs/how-it-works.md | Understand the run order, idempotency rules, backups, dry run |
| docs/private-files.md | Keep secrets encrypted: key, archive, new machine, token rotation |
| docs/troubleshooting.md | Fix an error message |
| lib/README.md | Write or change a setup script; reference of every helper |
| gpg/README.md | Use the encrypt/decrypt/export/import scripts |
| CHANGELOG.md | See what changed and why |
<directory>/README.md |
Learn what one directory installs and how to customize it |
- A Debian/Ubuntu based Linux with
apt, and a user that can usesudo(orroot). curlandgit.install.shinstalls them, plusunzip, if they are missing. bun is installed byinstall.shtoo.
-
Run from script:
File
install.shclones this repository to~/dotfiles(or updates it when it is already there), installsbun, and runsbun bootstrap.tswith the arguments you pass:curl -fsSL https://raw.githubusercontent.com/DuckyMomo20012/dotfiles/main/install.sh | bash -s -- [options] -
Run manually:
Clone the project and go to the project directory:
git clone https://github.com/DuckyMomo20012/dotfiles.git ~/dotfiles cd ~/dotfiles
Install
bunif you do not have it (bun.sh), then run the bootstrap script:bun bootstrap.ts [options]
Tip: look at what would happen first with
bun bootstrap.ts --dry-run.
Note: This project is tested on Ubuntu 22.04 and newer LTS releases. Other Debian based distributions should work, but are not tested.
bun bootstrap.ts does the following, in order:
- Runs the setup files in
asdf(the version manager and the tools it installs). - Runs all other setup files (
setup.tsand*.setup.ts, in every directory). Directories run in a fixed order:packages,install_debandbrewfirst (they providecurl,git, build tools...), then the rest alphabetically. Inside a directorysetup.tsgoes first. - Symlinks everything in
dotfilesinto your home directory. - With
--dedot: imports your GPG key, decryptsprivate, symlinksprivate/dotfilesand runs the private setup files.
It stops at the first failing setup file (use --keep-going to run the rest
and get a report at the end).
Usage: bun bootstrap.ts [options]
-h, --help Show help and exit
-d, --dedot Decrypt and set up the private files
-s, --secret <file> GPG secret key file to import (env: GPG_SECRET_FILE)
-e, --email <email> Email of the GPG key (env: GPG_EMAIL)
-p, --passphrase <passphrase> Passphrase of the encrypted archive (env: GPG_PASSPHRASE)
-n, --dry-run Show what would change, change nothing
--no-backup Overwrite existing files directly instead of backing them up
--force Reinstall tools that are already installed
-v, --verbose Print every command that is run
--only <name> Run only setup files whose path contains <name> (repeatable)
--skip <name> Skip setup files whose path contains <name> (repeatable)
--keep-going Do not stop at the first failing setup file
Examples:
bun bootstrap.ts --dry-run # preview everything
bun bootstrap.ts --only devops --skip docker # only DevOps tools, without docker
bun bootstrap.ts --no-backup # replace existing dotfiles directly
bun bootstrap.ts --force --only helm # reinstall helmA typical session:
$ bun bootstrap.ts --dry-run # 1. look
$ bun bootstrap.ts # 2. do it
$ bun bootstrap.ts # 3. again: nothing to do
Symlinks: 0 linked, 270 already up to date, 0 backed up
All done.
$ bun bootstrap.ts --force --only helm # 4. reinstall one thing
Environment variables (all optional):
| Variable | Same as / effect |
|---|---|
DOTFILES_DRY_RUN=1 |
--dry-run |
DOTFILES_NO_BACKUP=1 |
--no-backup |
DOTFILES_FORCE=1 |
--force |
DOTFILES_VERBOSE=1 |
--verbose |
GPG_EMAIL, GPG_SECRET_FILE, GPG_PASSPHRASE |
--email, --secret, --passphrase |
GITHUB_TOKEN |
Avoid the GitHub API rate limit (asdf, helmfile downloads) |
DOTFILES_APT_INTERACTIVE=1 |
Let apt ask questions (default: never ask) |
NO_COLOR=1 |
Plain output |
Prefer GPG_PASSPHRASE over --passphrase: command line arguments are visible
to other users in ps.
Every single setup file understands --dry-run, --no-backup, --force and
--verbose too (bun devops/helm.setup.ts --dry-run). More about the shared
switches and the helper library in lib/README.md.
You can run any script as often as you like and get the same result.
- Tools are installed only when missing (
--forcereinstalls). apt packages are checked one by one, the package lists are refreshed at most once an hour, and repository files are rewritten only when their content differs. - Shell config (
~/.bashrc,~/.zshrc, ...) lines are appended only when they are not there yet, and only for shells you use. - Git clones (zsh theme and plugins) are fast-forwarded, not deleted and cloned again.
- Symlinks that are already correct are left alone. When something else is
in the way, it is moved to
<file>.backup(an older backup is never overwritten: you get<file>.backup.<timestamp>) and the link is created. With--no-backupit is replaced directly. Seelib/README.md. - Private files from the encrypted archive are written only when they differ, and the old version is backed up in the same way.
- Nothing is left behind: temporary files live in private temp directories that are always removed.
asdf: Setup theasdftool version manager and install plugins.brew: Setup Homebrew and install the packages of itsBrewfile.devops: Setup DevOps tools.dotfiles: Dotfiles that are symlinked into the home directory.docs: Guides: getting started, recipes, how it works, private files, troubleshooting.examples: Wrapper script for a fresh machine.gpg: Scripts to encrypt files in theprivatedirectory or export/importgpgkeys.install_deb: Install the.debfiles you put there.lib: Utility library for this project, with its own documentation.lotus: SetuplotusVietnamese input method.misc: Miscellaneous system fixes.packages: Install packages.private: Private dotfiles, will be ignored and encrypted.private/dotfiles-example: Example private dotfiles configuration.
tests: Unit tests of the library.zsh: Setupzshshell.
Directories that run something have a README.md that explains what it does and
how to customize it.
Assume your current directory has this structure (everything except
bootstrap.sh is optional):
.
βββ bootstrap.sh <- copy of examples/bootstrap.sh
βββ secret.asc <- GPG secret key
βββ code_amd64.deb <- any .deb you want installed first
Then run:
./bootstrap.shIt installs the .deb files, runs install.sh (so every bootstrap.ts option
works: ./bootstrap.sh --dry-run, ./bootstrap.sh --no-backup), imports
secret.asc and decrypts the private files. Set GPG_EMAIL and
GPG_PASSPHRASE to avoid the prompts.
Without the wrapper, normal setup is:
curl -fsSL https://raw.githubusercontent.com/DuckyMomo20012/dotfiles/main/install.sh | bash -sOr setup and decrypt the private files in one go:
export GPG_PASSPHRASE="your_passphrase"
curl -fsSL https://raw.githubusercontent.com/DuckyMomo20012/dotfiles/main/install.sh | bash -s -- --dedot --secret "secret.asc" --email "example@gmail.com"Create <directory>/<tool>.setup.ts (or setup.ts for the main file of a
directory). It is picked up automatically. Keep it idempotent: check before
you act, and use the helpers from lib so --dry-run and
--no-backup work. A complete example is in
lib/README.md.
bun install # dev tools (eslint, typescript)
bun run lint # eslint
bun run typecheck # tsc
bun test # unit tests, use throwaway directories
bun run bootstrap:drybun.lock is the only lockfile. CI runs the same checks, plus ShellCheck and a
double dry run.
- Colorize output.
- Idempotent setup scripts.
- Backup or overwrite existing files.
- Dry run.
Contributions are always welcome! Please run bun run lint, bun run typecheck
and bun test before you open a pull request.
-
Is this project still maintained?
- Yes, I will add more dotfiles when I use new tools or have some modifications to my current dotfiles.
-
Is this project support other Linux distributions or MacOS?
- Debian and Ubuntu based systems are supported. On other systems the
aptbased scripts will not work; the rest may. Try it with--dry-runfirst.
- Debian and Ubuntu based systems are supported. On other systems the
-
I ran it twice, did it duplicate anything?
- No. See Idempotency and backups. If you find a script that is not safe to repeat, please open an issue.
-
Where did my old
~/.zshrcgo?- To
~/.zshrc.backup(or~/.zshrc.backup.<timestamp>when that name was taken). Use--no-backupif you do not want backups.
- To
Distributed under MIT license. See LICENSE for more information.
Duong Vinh - @duckymomo20012 - tienvinh.duong4@gmail.com
Project Link: https://github.com/DuckyMomo20012/dotfiles.
Here are useful resources and libraries that I have used in my projects:
-
Awesome Readme Template: A detailed template to bootstrap your README file quickly.
-
rkalis/dotfiles: A good dotfiles project that inspired me with the keep sudo alive approach, extract install command from file name and some other things.
-
holman/dotfiles: Good folder structure and symlink approach.
-
explainshell.com: A website to explain shell commands.
-
ShellCheck: Finds bugs in your shell scripts.
-
DOCOPT: Command-line interface description language.
-
Command Line Interface Guidelines: An open-source guide to help you write better command-line programs, taking traditional UNIX principles and updating them for the modern day.