├── .gitbook └── assets │ ├── image.png │ ├── screen-shot-2018-12-30-at-5.01.51-pm.png │ ├── screen-shot-2018-12-30-at-5.02.48-pm.png │ ├── screen-shot-2019-01-23-at-3.40.49-pm.png │ ├── screen-shot-2019-01-23-at-3.44.35-pm.png │ ├── screen-shot-2019-03-11-at-4.19.50-pm (1).png │ ├── screen-shot-2019-03-11-at-4.19.50-pm.png │ ├── screen-shot-2019-03-11-at-4.25.22-pm.png │ ├── screen-shot-2021-08-13-at-7.43.54-pm.png │ └── screenshot-2018-09-30-23.00.30.png ├── .gitignore ├── LICENSE ├── README.md ├── SUMMARY.md ├── apps-and-tools ├── README.md ├── docker │ ├── README.md │ └── volumes-1 │ │ ├── README.md │ │ └── volumes.md ├── fish │ ├── README.md │ └── plugins.md ├── google-chrome │ ├── README.md │ ├── extensions.md │ └── theme.md ├── hyper │ ├── README.md │ └── theme.md ├── raycast │ ├── README.md │ └── extensions.md ├── visual-studio-code │ ├── README.md │ ├── extensions.md │ └── theme.md └── web-bundlers │ ├── README.md │ └── webpack.md ├── arabic ├── README.md ├── advice │ ├── README.md │ ├── idarh-almtwryn-nbthh.md │ └── nsaeh-tshyh-matqdat-khateh-amnyat-llmbrmjyn-aljdd.md └── learning │ ├── README.md │ └── msadr-ltalm-albrmjh-w-alwm-alhasb.md ├── awesome-products.md ├── awesome-products └── README.md ├── biology ├── README.md └── species │ ├── README.md │ └── ants.md ├── design ├── README.md └── icons │ ├── README.md │ └── icon-sets.md ├── devops ├── README.md ├── databases │ ├── README.md │ └── estimating-connections.md └── kubernetes │ ├── README.md │ ├── application-health-checks.md │ ├── best-practices.md │ ├── kubectl-cheatsheet.md │ ├── ruby-on-rails.md │ ├── terminology.md │ ├── troubleshooting.md │ └── upgrades.md ├── documentation.md ├── education ├── README.md ├── design │ ├── README.md │ └── courses-and-books.md ├── frontend-development.md └── programming-and-computer-science │ ├── README.md │ └── courses.md ├── engineering-management ├── README.md └── overview.md ├── http ├── README.md └── status-codes.md ├── machine-learning ├── README.md ├── overfitting.md ├── regression.md └── terminology.md ├── my-stack.md ├── programming-languages ├── README.md ├── constructs.md ├── go │ ├── README.md │ └── syntax.md └── ruby │ ├── README.md │ ├── debugging │ ├── README.md │ └── byebug │ │ ├── README.md │ │ └── cheatsheet.md │ ├── lazy-enumerators.md │ ├── libraries.md │ ├── ruby-on-rails │ ├── README.md │ ├── gotchas.md │ ├── helpers.md │ ├── libraries.md │ ├── relations.md │ ├── routing.md │ ├── setup.md │ └── status-code-symbols.md │ └── snippets.md ├── sharing.md ├── software-architecture ├── README.md ├── centralized-authentication.md ├── event-sourcing.md ├── microservices.md └── serverless.md ├── talks ├── README.md └── software-architecture │ ├── README.md │ ├── an-insiders-look-at-the-technology-that-powers-shopify.md │ └── building-extensible-platforms.md ├── version-control ├── README.md └── git │ ├── README.md │ └── conventions │ ├── README.md │ ├── conventional-commits.md │ └── gitmoji.md └── work ├── README.md ├── hiring-process.md └── what-i-want-in-a-workplace.md /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/image.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2018-12-30-at-5.01.51-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2018-12-30-at-5.01.51-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2018-12-30-at-5.02.48-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2018-12-30-at-5.02.48-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2019-01-23-at-3.40.49-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2019-01-23-at-3.40.49-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2019-01-23-at-3.44.35-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2019-01-23-at-3.44.35-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2019-03-11-at-4.19.50-pm (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2019-03-11-at-4.19.50-pm (1).png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2019-03-11-at-4.19.50-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2019-03-11-at-4.19.50-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2019-03-11-at-4.25.22-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2019-03-11-at-4.25.22-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screen-shot-2021-08-13-at-7.43.54-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screen-shot-2021-08-13-at-7.43.54-pm.png -------------------------------------------------------------------------------- /.gitbook/assets/screenshot-2018-09-30-23.00.30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obahareth/knowledge/68417b9de04566dca5524466248ad3df63598a3b/.gitbook/assets/screenshot-2018-09-30-23.00.30.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Omar Bahareth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [My knowledge wiki](https://wiki.omar.engineer). You can also find [a repository](https://github.com/obahareth/knowledge) mirroring this wiki with Markdown files on GitHub. 4 | 5 | This is the beginning of a Gitbook containing everything I know, and it's heavily inspired from [https://github.com/nikitavoloboev/knowledge](https://github.com/nikitavoloboev/knowledge). 6 | 7 | You can search using the top right corner or you can simply explore the tree view to the left. 8 | 9 | You can [ask me anything](https://github.com/obahareth/ama) you want at anytime. 10 | 11 | ## Other things I wrote and shared 12 | 13 | I also share my knowledge by writing articles [on Medium](https://medium.com/@obahareth), on [dev.to](https://dev.to/obahareth), and my [personal website](https://omar.engineer). 14 | 15 | I also love writing code that solves various problems I have and I share it all [on GitHub](https://github.com/obahareth). 16 | 17 | I share a number of pages, boards, and lists on my [public Notion page](https://www.notion.so/obahareth/Public-04ad2eb582a448b1ae834249d5ada9b9). 18 | 19 | ## Make your own wiki 20 | 21 | You can view other similar to this, continuously updated wikis, [here](https://github.com/RichardLitt/meta-knowledge#readme). 22 | 23 | Don't be afraid to create one of your own and share what you know with the world. 24 | 25 | If you found a mistake anywhere in this wiki, I would appreciate your help. You can quickly find any entry you wish to edit by [searching for the topic](https://github.com/obahareth/knowledge/find/master) and then making the changes. 26 | 27 | I also appreciate any [ideas you have](https://github.com/obahareth/knowledge/issues/new) on how I can improve this wiki. 28 | 29 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Introduction](README.md) 4 | * [My Stack](my-stack.md) 5 | * [Sharing](sharing.md) 6 | * [Work](work/README.md) 7 | * [How I Want to Work](work/what-i-want-in-a-workplace.md) 8 | * [Hiring Process](work/hiring-process.md) 9 | * [Apps & Tools](apps-and-tools/README.md) 10 | * [Raycast](apps-and-tools/raycast/README.md) 11 | * [Extensions](apps-and-tools/raycast/extensions.md) 12 | * [Visual Studio Code](apps-and-tools/visual-studio-code/README.md) 13 | * [Theme](apps-and-tools/visual-studio-code/theme.md) 14 | * [Extensions](apps-and-tools/visual-studio-code/extensions.md) 15 | * [Google Chrome](apps-and-tools/google-chrome/README.md) 16 | * [Theme](apps-and-tools/google-chrome/theme.md) 17 | * [Extensions](apps-and-tools/google-chrome/extensions.md) 18 | * [iTerm 2](apps-and-tools/hyper/README.md) 19 | * [Theme](apps-and-tools/hyper/theme.md) 20 | * [Fish](apps-and-tools/fish/README.md) 21 | * [Plugins](apps-and-tools/fish/plugins.md) 22 | * [Docker](apps-and-tools/docker/README.md) 23 | * [Volumes](apps-and-tools/docker/volumes-1/README.md) 24 | * [Mounting](apps-and-tools/docker/volumes-1/volumes.md) 25 | * [Web Bundlers](apps-and-tools/web-bundlers/README.md) 26 | * [Webpack](apps-and-tools/web-bundlers/webpack.md) 27 | * [DevOps](devops/README.md) 28 | * [Databases](devops/databases/README.md) 29 | * [Estimating Connections](devops/databases/estimating-connections.md) 30 | * [Kubernetes](devops/kubernetes/README.md) 31 | * [Terminology](devops/kubernetes/terminology.md) 32 | * [kubectl Cheatsheet](devops/kubernetes/kubectl-cheatsheet.md) 33 | * [Best Practices](devops/kubernetes/best-practices.md) 34 | * [Application Health Checks](devops/kubernetes/application-health-checks.md) 35 | * [Upgrades](devops/kubernetes/upgrades.md) 36 | * [Troubleshooting](devops/kubernetes/troubleshooting.md) 37 | * [Ruby on Rails](devops/kubernetes/ruby-on-rails.md) 38 | * [Awesome Products](awesome-products.md) 39 | * [Engineering Management](engineering-management/README.md) 40 | * [Overview](engineering-management/overview.md) 41 | * [Software Architecture](software-architecture/README.md) 42 | * [Microservices](software-architecture/microservices.md) 43 | * [Event sourcing](software-architecture/event-sourcing.md) 44 | * [Serverless](software-architecture/serverless.md) 45 | * [Centralized Authentication](software-architecture/centralized-authentication.md) 46 | * [Talks](talks/README.md) 47 | * [Software Architecture](talks/software-architecture/README.md) 48 | * [An Insider's Look at the Technology That Powers Shopify](talks/software-architecture/an-insiders-look-at-the-technology-that-powers-shopify.md) 49 | * [Building Extensible Platforms](talks/software-architecture/building-extensible-platforms.md) 50 | * [Documentation](documentation.md) 51 | * [Machine Learning](machine-learning/README.md) 52 | * [Terminology](machine-learning/terminology.md) 53 | * [Regression](machine-learning/regression.md) 54 | * [Overfitting](machine-learning/overfitting.md) 55 | * [Programming Languages](programming-languages/README.md) 56 | * [Constructs](programming-languages/constructs.md) 57 | * [Go](programming-languages/go/README.md) 58 | * [Syntax](programming-languages/go/syntax.md) 59 | * [Ruby](programming-languages/ruby/README.md) 60 | * [Ruby on Rails](programming-languages/ruby/ruby-on-rails/README.md) 61 | * [Setup](programming-languages/ruby/ruby-on-rails/setup.md) 62 | * [Gotchas](programming-languages/ruby/ruby-on-rails/gotchas.md) 63 | * [Helpers](programming-languages/ruby/ruby-on-rails/helpers.md) 64 | * [Libraries](programming-languages/ruby/ruby-on-rails/libraries.md) 65 | * [Routing](programming-languages/ruby/ruby-on-rails/routing.md) 66 | * [Status Code Symbols](programming-languages/ruby/ruby-on-rails/status-code-symbols.md) 67 | * [Debugging](programming-languages/ruby/debugging/README.md) 68 | * [Byebug](programming-languages/ruby/debugging/byebug/README.md) 69 | * [Cheatsheet](programming-languages/ruby/debugging/byebug/cheatsheet.md) 70 | * [Libraries](programming-languages/ruby/libraries.md) 71 | * [Lazy Enumerators](programming-languages/ruby/lazy-enumerators.md) 72 | * [Snippets](programming-languages/ruby/snippets.md) 73 | * [Version Control](version-control/README.md) 74 | * [Git](version-control/git/README.md) 75 | * [Conventions](version-control/git/conventions/README.md) 76 | * [Conventional Commits](version-control/git/conventions/conventional-commits.md) 77 | * [gitmoji](version-control/git/conventions/gitmoji.md) 78 | * [Education](education/README.md) 79 | * [Programming & Computer Science](education/programming-and-computer-science/README.md) 80 | * [Courses](education/programming-and-computer-science/courses.md) 81 | * [Design](education/design/README.md) 82 | * [Courses and Books](education/design/courses-and-books.md) 83 | * [Frontend Development](education/frontend-development.md) 84 | * [HTTP](http/README.md) 85 | * [Status Codes](http/status-codes.md) 86 | * [Design](design/README.md) 87 | * [Icons](design/icons/README.md) 88 | * [Icon Sets](design/icons/icon-sets.md) 89 | * [Arabic Content | محتوى عربي](arabic/README.md) 90 | * [Learning](arabic/learning/README.md) 91 | * [مصادر لتعلم البرمجة و علوم الحاسب](arabic/learning/msadr-ltalm-albrmjh-w-alwm-alhasb.md) 92 | * [Advice](arabic/advice/README.md) 93 | * [إدارة المطورين: نبذة](arabic/advice/idarh-almtwryn-nbthh.md) 94 | * [نصائح تصحيح معتقدات خاطئة أمنيات للمبرمجين الجدد](arabic/advice/nsaeh-tshyh-matqdat-khateh-amnyat-llmbrmjyn-aljdd.md) 95 | * [Biology](biology/README.md) 96 | * [Species](biology/species/README.md) 97 | * [Ants](biology/species/ants.md) 98 | -------------------------------------------------------------------------------- /apps-and-tools/README.md: -------------------------------------------------------------------------------- 1 | # Apps & Tools 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/docker/README.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/docker/volumes-1/README.md: -------------------------------------------------------------------------------- 1 | # Volumes 2 | 3 | ### Table of Contents 4 | 5 | * [Mounting](volumes.md). 6 | 7 | -------------------------------------------------------------------------------- /apps-and-tools/docker/volumes-1/volumes.md: -------------------------------------------------------------------------------- 1 | # Mounting 2 | 3 | ### Mounting 4 | 5 | Mounting Docker volumes via Docker for Mac can result in performance bottlenecks as seen in [this issue](https://github.com/docker/for-mac/issues/77). This also heavily impacts the performance of my [Elixir base16 builder](https://github.com/obahareth/base16-builder-elixir/issues/2). 6 | 7 | On macOS, you can [configure mount consistency](https://docs.docker.com/storage/bind-mounts/#configure-mount-consistency-for-macos) to get better performance on your use case. These are the three available consistencies: 8 | 9 | * `consistent` \(the default\) - This is the slowest setting and it aims for full consistency between the container and host 10 | * `delegated` - This setting treats the container view as the source of truth, changes in the container can take a while to appear on the host. This setting is better used when the container is making the majority of the changes \(especially if they're a lot\). In my Elixir base16 builder, this is the setting I chose because A LOT of files are written in the container that should then be reflected back to the host, and I don't really care about the host's version of the files. 11 | * `cached` - This setting treats the host as the source of truth, changes in the host may take a while to appear in the container. This setting is better used for development where you always want the latest changes on your host to show up on the container, and you aren't really going to make changes inside of the container only. 12 | 13 | -------------------------------------------------------------------------------- /apps-and-tools/fish/README.md: -------------------------------------------------------------------------------- 1 | # Fish 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/fish/plugins.md: -------------------------------------------------------------------------------- 1 | # Plugins 2 | 3 | I don't have a lot of plugins because Fish is awesome and comes with great defaults. 4 | 5 | I use [Fisher](https://github.com/jorgebucaran/fisher) to manage [my plugins](https://github.com/obahareth/dotfiles). 6 | 7 | ### Utility 8 | 9 | * ​[autojump](https://github.com/wting/autojump) - A cd command that learns - easily navigate directories from the command line. 10 | * [asdf](https://github.com/asdf-vm/asdf) - One version manager for all my programming languages \(no need to have rvm/nvm/etc.\). 11 | * [bass](https://github.com/edc/bass) - Make Bash utilities usable in Fish shell. 12 | 13 | ### Prompt 14 | 15 | * [Starship](https://github.com/starship/starship) - Pretty, minimal and fast cross-shell prompt. 16 | 17 | -------------------------------------------------------------------------------- /apps-and-tools/google-chrome/README.md: -------------------------------------------------------------------------------- 1 | # Google Chrome 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/google-chrome/extensions.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | These are the Google Chrome extensions I use \(RIP my RAM\). 4 | 5 | ### General 6 | 7 | * [1Password X - Password Manager](https://chrome.google.com/webstore/detail/1password-x-%E2%80%93-password-ma/aeblfdkhhhdcdjpifhhbdiojplfjncoa). 8 | * [Buffer](https://chrome.google.com/webstore/detail/buffer/noojglkidnpfjbincgijbaiedldjfbhh). 9 | * [Midnight Lizard](https://chrome.google.com/webstore/detail/midnight-lizard/pbnndmlekkboofhnbonilimejonapojg) with [Nord Scheme](https://midnight-lizard.org/schemes/index/full/641417e1-5773-4e95-b707-75358ed5286c) to make all websites use the Nord theme. 10 | * [Enhanced Steam](https://chrome.google.com/webstore/detail/enhanced-steam/okadibdjfemgnhjiembecghcbfknbfhg). 11 | * [GhostText](https://chrome.google.com/webstore/detail/ghosttext/godiecgffnchndlihlpaajjcplehddca). 12 | * [Hunter](https://chrome.google.com/webstore/detail/hunter/hgmhmanijnjhaffoampdlllchpolkdnj). 13 | * [Markdown Here](https://chrome.google.com/webstore/detail/markdown-here/elifhakcjgalahccnjkneoccemfahfoa). 14 | * [Notion Web Clipper](https://chrome.google.com/webstore/detail/notion-web-clipper/knheggckgoiihginacbkhaalnibhilkk?hl=en). 15 | * [OneTab](https://chrome.google.com/webstore/detail/onetab/chphlpgkkbolifaimnlloiipkdnihall). 16 | * [Refined Twitter](https://chrome.google.com/webstore/detail/refined-twitter/nlfgmdembofgodcemomfeimamihoknip). 17 | * [Save to Pocket](https://chrome.google.com/webstore/detail/save-to-pocket/niloccemoadcdkdjlinkgdfekeahmflj). 18 | * [Reddit Enhancement Suite](https://chrome.google.com/webstore/detail/reddit-enhancement-suite/kbmfpngjjgdllneeigpgjifpgocmfgmb). 19 | * [Shodan](https://chrome.google.com/webstore/detail/shodan/jjalcfnidlmpjhdfepjhjbhnhkbgleap). 20 | * [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo). 21 | * [The Great Suspender](https://chrome.google.com/webstore/detail/the-great-suspender/klbibkeccnjlkjkiokjodocebajanakg). 22 | * [Todoist](https://chrome.google.com/webstore/detail/todoist-to-do-list-and-ta/jldhpllghnbhlbpcmnajkpdmadaolakh). 23 | * [uBlock Origin](https://lh3.googleusercontent.com/gE-W0qCedE7UhXvN_VvyUn1axwmEV5fc2XybuKY3OGyvB54Ci6IMBGLAemQUkejaB2bDxVrmWQ=w440-h280-e365). 24 | * [Vimium](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb). 25 | * [Wappalyzer](https://chrome.google.com/webstore/detail/wappalyzer/gppongmhjkpfnbhagpmjfkannfbllamg). 26 | * [WhatRuns](https://chrome.google.com/webstore/detail/whatruns/cmkdbmfndkfgebldhnkbfhlneefdaaip). 27 | * [Wikiwand](https://chrome.google.com/webstore/detail/wikiwand-wikipedia-modern/emffkefkbkpkgpdeeooapgaicgmcbolj). 28 | 29 | ### Github Enhancements 30 | 31 | * [Awesome Autocomplete for GitHub](https://chrome.google.com/webstore/detail/awesome-autocomplete-for/djkfdjpoelphhdclfjhnffmnlnoknfnd). 32 | * [Isometric Contributions](https://chrome.google.com/webstore/detail/isometric-contributions/mjoedlfflcchnleknnceiplgaeoegien). 33 | * [OctoLinker](https://chrome.google.com/webstore/detail/octolinker/jlmafbaeoofdegohdhinkhilhclaklkp). 34 | * [Refined GitHub](https://chrome.google.com/webstore/detail/refined-github/hlepfoohegkhhmjieoechaddaejaokhf). 35 | * [Notifier for GitHub](https://github.com/sindresorhus/notifier-for-github). 36 | 37 | ### Development 38 | 39 | * [EditThisCookie](https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg?utm_source=inline-install-disabled). 40 | * [RailsPanel](https://chrome.google.com/webstore/detail/railspanel/gjpfobpafnhjhbajcjgccbbdofdckggg). 41 | * [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi). 42 | * [Redux DevTools](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd). 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /apps-and-tools/google-chrome/theme.md: -------------------------------------------------------------------------------- 1 | # Theme 2 | 3 | ### [Material Nord](https://chrome.google.com/webstore/detail/material-nord/cnfjnjfppmpabbbdeijhimfijipmmanj?hl=en) 4 | 5 | ![The dark background for the webpage is from the Dark Reader extension](../../.gitbook/assets/screen-shot-2019-01-23-at-3.44.35-pm.png) 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps-and-tools/hyper/README.md: -------------------------------------------------------------------------------- 1 | # iTerm 2 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/hyper/theme.md: -------------------------------------------------------------------------------- 1 | # Theme 2 | 3 | I use [Nord](https://github.com/arcticicestudio/nord-iterm2) as my Hyper theme, along with the [starship prompt](https://github.com/starship/starship). 4 | 5 | ![](../../.gitbook/assets/screen-shot-2021-08-13-at-7.43.54-pm.png) 6 | 7 | -------------------------------------------------------------------------------- /apps-and-tools/raycast/README.md: -------------------------------------------------------------------------------- 1 | # Raycast 2 | 3 | Raycast is an awesome launcher with many extensions that make it go so much more beyond that. Extensions can present a variety of interfaces, it has an extension store, and it's so easy to develop extensions for. 4 | -------------------------------------------------------------------------------- /apps-and-tools/raycast/extensions.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Raycast extensions that I frequently use 3 | --- 4 | 5 | # Extensions 6 | 7 | ## Bundled with Raycast 8 | 9 | * Clipboard History 10 | * Define Word 11 | * File Search 12 | * Search Emoji 13 | 14 | ## Available on Store 15 | 16 | * [Change Case](https://www.raycast.com/es183923/change-case) 17 | * [Linear](https://www.raycast.com/raycast/linear) 18 | * [Ruby Evaluate](https://www.raycast.com/obahareth/ruby-evaluate) 19 | -------------------------------------------------------------------------------- /apps-and-tools/visual-studio-code/README.md: -------------------------------------------------------------------------------- 1 | # Visual Studio Code 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/visual-studio-code/extensions.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | ### Editing 4 | 5 | > 6 | 7 | #### Syntax Highlighters / Programming Languages 8 | 9 | * [Apache Conf](https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-apache) - Syntax highlighter for Apache configuration files. 10 | * [C\#](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp) - C\# for Visual Studio Code \(powered by OmniSharp\). 11 | * [Crystal](https://marketplace.visualstudio.com/items?itemName=g3ortega.crystal) - Provides Crystal language support for Visual Studio Code. 12 | * [DotENV](https://marketplace.visualstudio.com/items?itemName=mikestead.dotenv) - Support for dotenv file syntax. 13 | * [Go](https://marketplace.visualstudio.com/items?itemName=ms-vscode.go) - Rich Go language support for Visual Studio Code. 14 | * [Handlebars](https://marketplace.visualstudio.com/items?itemName=andrejunges.handlebars) - Handlebars Visual Studio Code. 15 | * [Mustache](https://marketplace.visualstudio.com/items?itemName=dawhite.mustache) - Syntax highlighting for Mustache. 16 | * [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) - Linting, Debugging \(multi-threaded, remote\), Intellisense, code formatting, refactoring, unit tests, snippets, and more. 17 | * [Ruby](https://marketplace.visualstudio.com/items?itemName=rebornix.ruby) - Provides Ruby language and debugging support for Visual Studio Code. 18 | * [Rust](https://marketplace.visualstudio.com/items?itemName=kalitaalexey.vscode-rust) - Rust language integration for VSCode. 19 | * [vscode-elixir](https://marketplace.visualstudio.com/items?itemName=mjmcloug.vscode-elixir) - Elixir support for VSCode. 20 | * [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) - Great YAML support, including Kubernetes syntax, and lets you find out where you exactly are in the YAML if you have [breadcrumbs](https://code.visualstudio.com/updates/v1_26#_breadcrumbs) enabled. 21 | 22 | #### General Editing 23 | 24 | * [Babel ES6/ES7](https://marketplace.visualstudio.com/items?itemName=dzannotti.vscode-babel-coloring) - Adds JS Babel es6/es7 syntax coloring. 25 | * [Beautify](https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify) - Beautify code in place for VS Code. 26 | * [Better Align](https://marketplace.visualstudio.com/items?itemName=wwm.better-align) - Align code without selecting them first. 27 | * [Bracket Pair Colorizer 2](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2) - A customizable extension for colorizing matching brackets. 28 | * [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) - Spelling checker for source code. 29 | * [indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow) - Makes indentation easier to read. 30 | * [Vim](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) - Vim emulation for Visual Studio Code. 31 | 32 | ### Collaboration 33 | 34 | * [VS Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare) - Real-time collaborative development from the comfort of your favorite tools. 35 | * [GitHub Pull Requests](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github) - Review and manage GitHub pull requests in Visual Studio Code. 36 | 37 | ### Git 38 | 39 | * [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory) - View git log, file history, compare branches or commits. 40 | * [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) - Supercharge the Git capabilities built into Visual Studio Code. 41 | 42 | ### Devops 43 | 44 | * [Docker](https://marketplace.visualstudio.com/items?itemName=peterjausovec.vscode-docker) - Adds syntax highlighting, commands, hover tips, and linting for Dockerfile and docker-compose files. 45 | 46 | ### Debugging 47 | 48 | * [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) - Debug your JavaScript code in the Chrome browser, or any other target that supports the Chrome Debugger protocol. 49 | * [Debugger for Unity](https://marketplace.visualstudio.com/items?itemName=unity.unity-debug) - Unity debugger extension. 50 | * [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) - Debug support for PHP with XDebug. 51 | 52 | ### Snippets 53 | 54 | * [Ruby on Rails](https://marketplace.visualstudio.com/items?itemName=hridoy.rails-snippets). 55 | * [ES7 React/Redux/GraphQL/React-Native snippets](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets). 56 | 57 | ### Utility 58 | 59 | * [Browser Preview](https://github.com/auchenberg/vscode-browser-preview) - A real browser preview inside your editor that you can debug. 60 | * [advanced-new-file](https://marketplace.visualstudio.com/items?itemName=patbenatar.advanced-new-file) - adds the ability to create files anywhere in your workspace. 61 | * [Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) - Run code in VS Code. 62 | * [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=editorconfig.editorconfig) - EditorConfig Support for Visual Studio Code. 63 | * [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - Integrates ESLint JavaScript into VS Code. 64 | * [GhostText](https://marketplace.visualstudio.com/items?itemName=tokoph.ghosttext) - Use VS Code to write in your browser. 65 | * [hexdump for VSCode](https://marketplace.visualstudio.com/items?itemName=slevesque.vscode-hexdump) - Display a specified file in hexadecimal. 66 | * [Insert Numbers](https://marketplace.visualstudio.com/items?itemName=asuka.insertnumbers) - Insert increasing numbers. 67 | * [IntelliSense for CSS class names](https://marketplace.visualstudio.com/items?itemName=Zignd.html-css-class-completion) - CSS class name completion for the HTML class attribute based on the definitions found in your workspace. 68 | * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.liveserver) - Launch a development local Server with live reload feature for static & dynamic pages. 69 | * [Path Intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense) - Filename autocompletion. 70 | * [phpcs](https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs) - PHP CodeSniffer for Visual Studio Code. 71 | * [Quit Control for VSCode](https://marketplace.visualstudio.com/items?itemName=artdiniz.quitcontrol-vscode) - Stop mistyping keyboard shortctus that close/quit VSCode unintentionally. 72 | * [React Native Tools](https://marketplace.visualstudio.com/items?itemName=vsmobile.vscode-react-native) - Code-hinting, debugging and integrated commands for React Native. 73 | * [Ruby Solargraph](https://marketplace.visualstudio.com/items?itemName=castwide.solargraph) - Code completion and inline documentation for Ruby. 74 | * [Settings Sync](https://marketplace.visualstudio.com/items?itemName=shan.code-settings-sync) - Synchronize Settings, Snippets, Themes, File Icons, Launch, Keybindings, Workspaces and Extensions Across Multiple Machines Using GitHub Gist. 75 | * [Sort lines](https://marketplace.visualstudio.com/items?itemName=tyriar.sort-lines) - Sort lines of text. 76 | * [TODO Highlight](https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight) - Highlight TODOs, FIXMEs, and any keywords, annotations. 77 | * [WakaTime](https://marketplace.visualstudio.com/items?itemName=wakatime.vscode-wakatime) - Metrics, insights, and time tracking automatically generated from your programming activity. 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /apps-and-tools/visual-studio-code/theme.md: -------------------------------------------------------------------------------- 1 | # Theme 2 | 3 | Color Theme: 4 | 5 | * [Polar](https://marketplace.visualstudio.com/items?itemName=merithayan.polar) (day, via Workbench: Preferred Light Color Theme). 6 | * [Nord](https://marketplace.visualstudio.com/items?itemName=arcticicestudio.nord-visual-studio-code) (night, via Workbench: Preferred Dark Color Theme). 7 | * I use Window: Auto Detect Color Scheme to auto switch themes based on time of day. 8 | 9 | Icon Theme: [Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme). 10 | 11 | Font: [Pragmata Pro](https://www.fsd.it/shop/fonts/pragmatapro/). 12 | 13 | ![](../../.gitbook/assets/screen-shot-2019-03-11-at-4.25.22-pm.png) 14 | 15 | -------------------------------------------------------------------------------- /apps-and-tools/web-bundlers/README.md: -------------------------------------------------------------------------------- 1 | # Web Bundlers 2 | 3 | -------------------------------------------------------------------------------- /apps-and-tools/web-bundlers/webpack.md: -------------------------------------------------------------------------------- 1 | # Webpack 2 | 3 | ### Tips 4 | 5 | #### Be very careful with importing large libraries 6 | 7 | Trying to compile large libraries (like react-plotly or PDF libraries) can take your Webpack compile from seconds to 10 minutes+. If a package is slowing down your compile, consider using a CDN version. We simply used script tags, but there are Webpack plugins that can help with that too: 8 | 9 | * [webpack-cdn-plugin](https://www.npmjs.com/package/webpack-cdn-plugin). 10 | * [dynamic-cdn-webpack-plugin](https://www.npmjs.com/package/dynamic-cdn-webpack-plugin). 11 | 12 | #### Try to find a webpack plugin for your dependencies 13 | 14 | Just importing packages like [moment.js](https://momentjs.com/) or [lodash](https://lodash.com/) bring in a lot of bloat that you probably don’t need. Try to import what you need only, or better yet find a webpack plugin that removes the unused things from your bundle, because [selective imports don’t always work](https://github.com/react-bootstrap/react-bootstrap/issues/2683). As one example, there’s [a webpack plugin](https://github.com/iamakulov/moment-locales-webpack-plugin) that removes a lot of the unnecessary bloat added by Moment.js. 15 | 16 | Google actually has a [nice repository](https://github.com/GoogleChromeLabs/webpack-libs-optimizations) listing some common problematic dependencies. 17 | 18 | #### Inspect your bundle with Webpack bundle analyzer 19 | 20 | ![](https://cdn-images-1.medium.com/max/800/0\*TewqripGyXujWGJs.png) 21 | 22 | [Webpack Bundle Analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) is extremely helpful to see what exactly is going into your bundle. In the screenshot above, you’ll notice that moment.js has lots of localization files that your app probably doesn’t need. Webpack Bundle Analyzer can help you easily spot these issues. 23 | 24 | #### Add es-check to your CI pipeline early on 25 | 26 | [es-check](https://github.com/dollarshaveclub/es-check) will help you find out which ES version your bundle is using, it’s super useful to find out if you’re somehow suddenly not producing ES5 anymore. Even if you’re using Babel and browserslist, you might be importing a node module that’s not even meant to be used in browsers, or even a package that’s not being distributed as ES5. Add es-check to your continuous integration pipeline early on and it should help you find out if your bundle ever stops working with ES5, and that’ll help you find which package is the culprit so you can then transpile it. 27 | 28 | #### Transpiling a node\_module 29 | 30 | We had imported a very simple package called [hex-rgb](https://github.com/sindresorhus/hex-rgb) that’s not even meant for browsers and this tiny package made our bundle not ES5-compatible anymore. Such packages should go through Babel and be transpiled. 31 | 32 | In your webpack config, your babel loader’s exclude field probably looks like this: `/node_modules/` . We need to make a regex that excludes node\_modules except the specific ones that should be transpiled: 33 | 34 | ``` 35 | // Exclude all node modules except hex-rgb and another-package 36 | /node_modules\/(?![hex\-rgb|another\-package])/ 37 | ``` 38 | 39 | And once again, this might not be a good solution for large packages as it can drastically slow your build time and you might want to switch to a CDN version instead. 40 | 41 | Follow [this issue](https://github.com/babel/babel-loader/issues/171) from the babel-loader repo to stay up to date on how to handle cases like this. 42 | 43 | #### Use Browserslist to specify your target browsers 44 | 45 | [Browserslist](https://github.com/browserslist/browserslist) lets you specify which browsers to transpile for. 46 | 47 | ``` 48 | > 1% 49 | ie >= 8 50 | ``` 51 | 52 | This simple configuration targets browsers with usage more than 1% global usage, and IE versions 8 and above. 53 | 54 | #### Use babel.config.js over .babelrc (for Babel ≥ 7.0) 55 | 56 | Favor using `babel.config.js` to [configure Babel](https://babeljs.io/docs/en/configuration) over `.babelrc` . If you want to transpile `node_modules` (which is now becoming a very common case with webapps), then you should use `babel.config.js` . 57 | 58 | `.babelrc` can be overridden by another `.babelrc` belonging to a node\_module that you’re transpiling and that can lead to all sorts of weird issues. 59 | 60 | #### Make your webpack-dev-server logging output friendlier 61 | 62 | 1. Change your [webpack-dev-server config](https://webpack.js.org/configuration/dev-server/) to this 63 | 64 | ``` 65 | devServer: { 66 | noInfo: true, 67 | stats: 'minimal' 68 | } 69 | ``` 70 | 71 | 2\. Add [WebpackBar](https://github.com/nuxt/webpackbar) to get much less-verbose, friendlier, and more concise output. 72 | 73 | ![](https://cdn-images-1.medium.com/max/800/1\*3CqzwcXgMpT-42e22OMu7Q.png) 74 | 75 | Note: The first configuration is meant to be combined with Webpack Bundle Analyzer, as it suppresses console output for things related to your bundle that Webpack Bundle Analyzer already shows. If you’re not using Webpack Bundle Analyzer, don’t apply the first step. 76 | 77 | #### 78 | -------------------------------------------------------------------------------- /arabic/README.md: -------------------------------------------------------------------------------- 1 | # Arabic Content \| محتوى عربي 2 | 3 | -------------------------------------------------------------------------------- /arabic/advice/README.md: -------------------------------------------------------------------------------- 1 | # Advice 2 | 3 | -------------------------------------------------------------------------------- /arabic/advice/idarh-almtwryn-nbthh.md: -------------------------------------------------------------------------------- 1 | # إدارة المطورين: نبذة 2 | 3 | **تحت الترجمة من** [**هذه المقالة**](https://dev.to/obahareth/engineering-management-an-overview-1814)**.** 4 | 5 | ## **التوقّعات** 6 | 7 | ### **لازم تكتب كثير** 8 | 9 | ### **أغلب وقتك بيروح في محادثات و إجتماعات** 10 | 11 | ### **أتعلم تحسب نجاحك بأداء فريقك، مش بأدائك الشخصي** 12 | 13 | ### **حتواجه صراعات كثيرة** 14 | 15 | ### **قرارت صعبة** 16 | 17 | ### **حتضطر تاخذ قرارات صعبة** **** 18 | 19 | ## **اسعى انك تعمل الحاجات هذه** 20 | 21 | ### **الاجتماعات الانفرادية** 22 | 23 | ### **الإرشاد** 24 | 25 | ### **الجدولة** 26 | 27 | ### **الصقل المستمر لمهاراتك كـ"صانع"** 28 | 29 | ### **كتابة و تحديث قائمة بجميع المهام** 30 | 31 | ### **التوظيف** 32 | 33 | #### **توظيف ال juniors** 34 | 35 | ### **اسمح لفريقك ينمو \ تفويض المهام** 36 | 37 | ### **شجّع مشاركة المعرفة و العلم** 38 | 39 | ### **كون دائماً منفتح للملاحظات و التغيير** 40 | 41 | ### **خلي فريقك يقدر يشتغل بدونك** 42 | 43 | ## **مصادر رهيبة** 44 | 45 | ### **كتب** 46 | 47 | * [**Leading Snowflakes**](https://leadingsnowflakes.com/)  **- مليء بنصائح عملية على المهام اليومية لمدير مطورين.** 48 | * [**The Manager’s Path**](https://www.amazon.com/dp/B06XP3GJ7F/ref=dp-kindle-redirect?\_encoding=UTF8\&btkr=1)  **- دليل لمراحل مختلفة من المسؤولية و التعقيد في إدارة المبرمجين و إدارة مدراء المبرمجين.** 49 | * [**High Output Management**](https://www.amazon.com/dp/B015VACHOK/ref=dp-kindle-redirect?\_encoding=UTF8\&btkr=1)  **- كتاب رهيب عن تشغيل و "تضخيم؟" الشركات التقنية.** 50 | 51 | ### **مواقع** 52 | 53 | * [**Manager Readme**](https://managerreadme.com/)  **- مجتمع لمشاركة "دليلك للإدارة" مع مدراء آخرين** 54 | * [**The Watercooler**](https://thewatercooler.io/) **- مجتمع لمدراء يسعوا انهم يسيروا أفضل.** 55 | 56 | ### **مقالات** 57 | 58 | * [**Rethinking how we interview in Microsoft’s Developer Division**](https://blog.usejournal.com/rethinking-how-we-interview-in-microsofts-developer-division-8f404cfd075a) **- مقالة عظيمة عن إجراءات مايكروسوف الجديدة للتوظيف.** 59 | * [**Undervalued Software Engineering Skills: Writing Well**](https://blog.pragmaticengineer.com/on-writing-well/) **- مقالة عن أهمية الكتابة الجيدة في مجال التطوير.** 60 | 61 | ### **نشرات بريدية (إيميل)** 62 | 63 | * [**Software Lead Weekly**](http://softwareleadweekly.com/) **- ايميل أسبوعي للمهتمين في ما يخص الناس, الثقافة, و الإدارة؟** 64 | -------------------------------------------------------------------------------- /arabic/advice/nsaeh-tshyh-matqdat-khateh-amnyat-llmbrmjyn-aljdd.md: -------------------------------------------------------------------------------- 1 | # نصائح تصحيح معتقدات خاطئة أمنيات للمبرمجين الجدد 2 | 3 | _المحتوى الأصلي من_ [_هذه التغريدة_](https://mobile.twitter.com/o\_bahareth/status/1115699605197348864)_, شكر كثير_ [_لإحسان_](https://e7san.gitbook.io/wiki/) _للمساعدة القيّمة في إعداد المحتوى._ 4 | 5 | ## _المعتقدات الخاطئة_ 6 | 7 | ### أغلب وقتك تكتب كود 8 | 9 | أنا دائما أقول ان المبرمج يقرأ أكثر مما يكتب، بتقرأ كود زملائك و بترجع في ال commit history عشان تفهم الكود (نية الكاتب)، عشان تفهم ايش سبب مشكلة معينة, او عشان تعرف كيف تضيف عليه. 10 | 11 | ### نبدأ بكتابة الكود مباشرةً 12 | 13 | لأ, كتابة الكود بدون خطة من أكثر أسباب المشاكل، لازم تكون فهمت المشكلة اللي تبغى تحلها مضبوط و عملت خوارزم مبدأي لحلها قبل الكتابة. مرات التجربة و اللعب بالكود يساعد في ابتكار الخوارزم، لكن يفضّل مراجعته او إعادة كتابته بعدها. ما في احسن من انك تبدأ بورقة و قلم و تحط لك أمثلة عن المدخلات و تجرّب أساليب مختلفة لحلها, و ارجع جربها على الكود بعد الكتابة. 14 | 15 | ### المبرمج انطوائي أو يعمل وحده 16 | 17 | من أكثر المعتقدات الخاطئة شيوعًا. الصحيح إن المبرمج يحتاج مهارات تواصل كتابية و منطوقة قوية، لإيصال أفكاره لبقية المبرمجين والعمل معهم (pair-programming)، و لكتابة توثيق و ملاحظات واضحة على الكود، و لطرح الأسئلة بشكل سليم على فريق المشروع/المنتج. 18 | 19 | ### لغة برمجة س أفضل من ص 20 | 21 | هذا أسلوب تفكير غير جيد للمبرمج، عادي يكون عندك لغات مفضلة، لكن لا تقفّل عقلك عن باقي اللغات، اللغات هي فقط أدوات في عُدّة ادواتك. لازم تعرف مضبوط نوع المشاكل اللي لغة س أو ص مصممة لحلها. 22 | 23 | ### تقدر تستخدم أي لغة برمجة 24 | 25 | هذا ليس معتقد خاطئ, لكن البعض يستخدم لغة مش مخصصة للنطاق اللي يبرمج فيه و ياخذ وقت كثير و مجهود كبير (عادي اذا يريحك). __ ممكن ابرمج حاجات data science بلغة Crystal لكن لأن مالها مكتبات قوية في هذا المجال, أسهل لي استخدم Python او R عشان اوفّر وقتي. 26 | 27 | ### التعقيد 28 | 29 | البعض يعتقد إن الكود المعقد او الكثير شيء جيد، لكن الأهم في البرمجة هو سهولة قراءة و فهم الكود و بالتالي سهولة قابلية التعديل عليه. 30 | 31 | ركز على اختصار وقت و مجهود فهم الكود عشان تفيد زملاؤك اللي بيقروا الكود بعد كم شهر او سنة. البساطة بتزيد إنتاجيتك انت و كل من يعمل معك. 32 | 33 | ### المبرمج لازم يحفظ كثير 34 | 35 | المبرمج لازم يكون عنده فهم قوي جدا للأساسيات, ما يحتاج يحفظ قد كدا. دائما بيكون معه مرجع (كتاب, توثيق, مقالة, محرك بحث, الخ) و أدوات في محرر النصوص تساعده يوصل للشيء اللي يحتاجه, الإعتماد على الحفظ قليل. 36 | 37 | ## حاجات انصح بتعلمها لدخول سوق العمل للمبرمجين و بعض النصائح الاخرى 38 | 39 | ### اللغة الانجليزية 40 | 41 | ممكن تكتب كود حتى إذا ما تعرف انجليزي، لكن اذا هدفك تعمل كمبرمج او تكون ضمن فريق او تستخدم أو تساهم في مكتبات مفتوحة المصدر، لازم تصقل لغتك الانجليزية باستمرار. 42 | 43 | 44 | 45 | ### كيفية استخدام محركات البحث 46 | 47 | المبرمج يحتاج يعرف كيف يبحث مضبوط, لازم يعرف المصطلحات التقنية بشكل جيد و يعرف امكانيات محركات البحث اللي يستخدمها. 48 | 49 | {% embed url="https://moz.com/learn/seo/search-operators" %} 50 | 51 | أول ما نزل فلم Django Unchained, ساروا الكثير من مبرمجين Django يتعبوا بسبب طغيان نتائج بحث الفلم على إطار العمل, كنت أبحث بهذه الطريقة عشان احصل على نتائج خاصة بإطار العمل `django -unchained ~programming` 52 | 53 | ### Source Control 54 | 55 | من اهم الحاجات اللي اغلب الجامعات ما تغطّيها. باختصار، بيساعدكم تحافظوا على تاريخ التغييرات على الكود و على العمل جماعياً على الكود، و هو أساس المشاركة في المكتبات مفتوحة المصدر. أشهر تقنية هي Git و اشهر استضافة هي GitHub. 56 | 57 | ### فهم كيف الكود يتفاعل مع مكونات الأجهزة 58 | 59 | كيف الكود يتفاعل مع الذاكرة و المعالج, كيف تشغل الكود حقك على اكثر من نواة (core) في المعالج, كيف تحدد متى تزيد أو تقلل استخدام أي واحد من المكونات هذي. كيف تلاقي و تحل مشاكل اداء في مكون معين. 60 | 61 | ### فهم في مجالك الدقيق 62 | 63 | اذا انت frontend developer لازم تسعى انك تفهم كيف ال web browser يشغل كودك و كامل امكانياته و حدوده. اذا انت mobile developer لازم تفهم كيف تكتب كود يحافظ على البطارية وما يعلّق الجوال. فكّر في مستخدمينك و انت تبرمج. 64 | 65 | ### تعلّم مهارات حل المشاكل 66 | 67 | الكود في النهاية أداة تستخدمها لحلّ مشكلة، إيجاد هذا الحل يحتاج لمهارات تفكير وتحليل واستنتاج قبل مهارات كتابة الكود، إذا ما تقدر تحل المشكلة بدون كتابة كود حتتعب في محاولة كتابة كود لأوامر انت أصلاً ما تعرفها. 68 | 69 | #### بعض المواقع الجيدة اللي ممكن تتدرب فيها على حل المشاكل 70 | 71 | {% embed url="https://www.codewars.com" %} 72 | 73 | {% embed url="https://leetcode.com/" %} 74 | 75 | {% embed url="https://www.hackerrank.com/" %} 76 | 77 | ## حاجات أتمنى المبرمجين الجدد يتعلموها\يعملوها 78 | 79 | ### المشاركة 80 | 81 | في اجابة الناس و المقالات و في المساهمة في المكتبات مفتوحة المصدر. احنا نستهلك مقالات و مكتبات و StackOverflow بشكل خرافي لكن ما نساهم فيهم كفاية. شاركوا حلولكم و الحاجات اللي اتعلمتوها بأي طريقة, انفعوا مثل ما انتفعتوا. 82 | 83 | ### إختبار الكود 84 | 85 | اختبار الكود عن طريق كود. شيء ضروري انك تقدر تعرف اتوماتيكياً اذا تغيير على الكود سار يطلّع نتائج غير مرغوبة و انه عندك طريقة سهلة تختبره مع مدخلات مرغوبة و غير مرغوبة. 86 | 87 | ### المراقبة 88 | 89 | لازم يكون عندكم ادوات تراقب ايش بيحصل مع تطبيقاتكم (سواء هي لعبة, ويب, او جوال). لازم تعرفوا ايش بيسير مع المستخدمين بدون ما يحتاجوا يكلموكم. أمثلة لبعض الأدوات (للمراقبة من ناحية تقنية): 90 | 91 | {% embed url="https://sentry.io" %} 92 | 93 | {% embed url="https://newrelic.com" %} 94 | 95 | ### قراءة الكتب 96 | 97 | البعض يستهين بأهمية الكتب ويعتقد إنها مجرد حشو زائد ويكتفي بالمقالات والفيديوهات، أو يخاف منها خصوصًا الكتب الانجليزية، الكتب تقدّم لك معلومات تفصيلية بشكل أحيانًا ما تلاقيه في المقالات القصيرة أو حتى الكورسات الّي غالبًا موجهة للمبتدئين. 98 | 99 | -------------------------------------------------------------------------------- /arabic/learning/README.md: -------------------------------------------------------------------------------- 1 | # Learning 2 | 3 | -------------------------------------------------------------------------------- /arabic/learning/msadr-ltalm-albrmjh-w-alwm-alhasb.md: -------------------------------------------------------------------------------- 1 | # مصادر لتعلم البرمجة و علوم الحاسب 2 | 3 | ## مواقع 4 | 5 | {% embed url="https://academy.hsoub.com/" %} 6 | 7 | {% embed url="https://www.rwaq.org/" %} 8 | 9 | {% embed url="https://harmash.com" %} 10 | 11 | {% embed url="http://www.coursat.org/" %} 12 | 13 | {% embed url="https://www.doroob.sa/ar/" %} 14 | 15 | {% embed url="https://edlal.org/" %} 16 | 17 | {% embed url="https://www.edraak.org/ar/" %} 18 | 19 | 20 | 21 | ## المصادر 22 | 23 | {% embed url="https://twitter.com/Twi_Hajar/status/1165156126868086784" %} 24 | 25 | -------------------------------------------------------------------------------- /awesome-products.md: -------------------------------------------------------------------------------- 1 | # Awesome Products 2 | 3 | ### Writing 4 | 5 | * [Notion](https://notion.so) - All-in-one workspace for writing, project management, and more. 6 | * [Typora](https://www.typora.io/) - Awesome WYSIWYG Markdown editor. 7 | * [GitBook](https://www.gitbook.com/) - Document Everything! For you, your users and your team \(Offers bidirectional GitHub sync\). 8 | 9 | ### Task Management 10 | 11 | * [TickTick](https://ticktick.com) - The to do worklist to organize work & life. 12 | 13 | ### Blogging 14 | 15 | * [Ghost](https://ghost.org) - Fiercely independent, professional publishing. 16 | 17 | ### Project Management 18 | 19 | * [Trello](https://trello.com/) - Trello lets you work more collaboratively and get more done. 20 | * [Linear](https://linear.app/) - The issue tracking tool you'll enjoy using 21 | * [JIRA](https://www.atlassian.com/software/jira) - Issue & project tracking software. 22 | * [Basecamp](https://basecamp.com/) - Project management and team communication software. 23 | * [Unito](https://unito.io/) - Integrate and sync project management tools \(Trello, JIRA, Asana, and more\). 24 | 25 | ### Design 26 | 27 | * [Figma](https://www.figma.com/) - Where teams design together. 28 | * [Whimsical](https://whimsical.com/) - The Visual Workspace, communicate visually at the speed of thought. 29 | 30 | ### Sketching 31 | 32 | * [Excalidraw](https://excalidraw.com/) - Hand-drawn look & feel 33 | 34 | ### Whiteboarding 35 | 36 | * [Miro](https://miro.com/) - The online collaborative whiteboard platform to bring teams together, anytime, anywhere. 37 | 38 | ### Automation 39 | 40 | * [Zapier](https://zapier.com/) - Connect Your Apps and Automate Workflows. 41 | * [IFTTT](https://ifttt.com) - Every thing works better together. 42 | 43 | ### Authentication 44 | 45 | * [Auth0](https://auth0.com/) - Never Compromise on Identity. 46 | 47 | ### Collecting Feedback 48 | 49 | * [Canny](https://canny.io) - Track feedback to build better products. 50 | 51 | ### Internal Tools 52 | 53 | * [Retool](https://retool.com/) - Build internal tools, remarkably fast 54 | 55 | ### Scheduling 56 | 57 | * [Calendly](https://calendly.com) - Calendly helps you schedule meetings without the back-and-forth emails. 58 | * [FreeBusy](http://freebusy.io/) The complete solution to automate meeting scheduling. 59 | * [There](https://there.team/) - The base for collaborating clearly & smoothly in remote teams. 60 | 61 | ### Calls / Confrencing 62 | 63 | * [Zoom](https://zoom.us) - Cloud video conferencing and simple online meetings. 64 | * [Google Meet](https://apps.google.com/meet/?hl=en) - Premium video meetings for everyone. 65 | * [Discord](https://discordapp.com) - All-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone. 66 | 67 | ### Forms 68 | 69 | * [Typeform](https://www.typeform.com) - The future of forms is here. 70 | * [Google Forms](https://www.google.com/forms/about/) - Create effortless forms. 71 | 72 | ### Search 73 | 74 | * [Algolia](https://www.algolia.com) - Fast, reliable and modern search and discovery. 75 | 76 | ### PaaS \(Platform as a Service\) 77 | 78 | * [Heroku](https://heroku.com). 79 | * [Render](https://render.com). 80 | * [Google App Engine](https://cloud.google.com/appengine/). 81 | 82 | ### Communication APIs 83 | 84 | * [Twilio](https://twilio.com) - Communication APIs for SMS, voice, video, and authentication. 85 | 86 | ### Email Clients 87 | 88 | * [Spark](https://sparkmailapp.com/) - Love your email again. 89 | 90 | ### Password Managers 91 | 92 | * [1Password](https://1password.com) - Go ahead. Forget your passwords. 93 | 94 | ### Email Services 95 | 96 | * [Mailgun](https://www.mailgun.com/) - The Email Service for Developers. 97 | * [SendGrid](https://sendgrid.com) - Partner with the email service trusted by developers and marketers for time-savings, scalability, and delivery expertise.. 98 | 99 | ### Payment Gateways 100 | 101 | * [Stripe](https://stripe.com) - The new standard in online payments. 102 | 103 | ### Continuous Integration 104 | 105 | * [CircleCI](https://circleci.com/) - Automate your development process quickly, safely, and at scale.. 106 | * [GitHub Actions](https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/) - Fast CI/CD for any OS, any language, and any cloud. 107 | * [GitLab CI](https://about.gitlab.com/product/continuous-integration/) - GitLab CI/CD pipelines build, test, deploy, and monitor your code as part of a single, integrated workflow. 108 | 109 | ### JAMstack 110 | 111 | _See:_ [_https://jamstack.org_](https://jamstack.org) 112 | 113 | #### Hosting 114 | 115 | * [Netlify](https://netlify.com) - All-in-one platform for automating modern web projects. 116 | 117 | #### Management / Building 118 | 119 | * [Stackbit](https://www.stackbit.com/) - Build Modern JAMstack Websites in Minutes. Combine any Theme, Site Generator and CMS without complicated integrations. 120 | 121 | #### CMS 122 | 123 | * [NetlifyCMS](https://www.netlifycms.org/). 124 | * [TinaCMS](https://tinacms.org/). 125 | * [Contentful](https://www.contentful.com/). 126 | 127 | -------------------------------------------------------------------------------- /awesome-products/README.md: -------------------------------------------------------------------------------- 1 | # Awesome Products 2 | 3 | 4 | 5 | ## Writing 6 | 7 | - [Notion](https://notion.so) - All-in-one workspace for writing, project management, and more. 8 | - [Typora](https://www.typora.io/) - Awesome WYSIWYG Markdown editor. 9 | - [GitBook](https://www.gitbook.com/) - Document Everything! For you, your users and your team (Offers bidirectional GitHub sync). 10 | 11 | ## Task Management 12 | 13 | - [Todoist](https://todoist.com/) - The to do worklist to organize work & life. 14 | 15 | ## Blogging 16 | 17 | - [Ghost](https://ghost.org) - Fiercely independent, professional publishing. 18 | 19 | ## Project Management 20 | 21 | - [Trello](https://trello.com/) - Trello lets you work more collaboratively and get more done. 22 | - [JIRA](https://www.atlassian.com/software/jira) - Issue & project tracking software. 23 | - [Basecamp](https://basecamp.com/) - Project management and team communication software. 24 | - [Unito](https://unito.io/) - Integrate and sync project management tools (Trello, JIRA, Asana, and more). 25 | 26 | ## Design 27 | 28 | - [Figma](https://www.figma.com/) - Where teams design together. 29 | - [Whimsical](https://whimsical.com/) - The Visual Workspace, communicate visually at the speed of thought. 30 | 31 | ## Automation 32 | 33 | - [Zapier](https://zapier.com/) - Connect Your Apps and Automate Workflows. 34 | - [IFTTT](https://ifttt.com) - Every thing works better together. 35 | 36 | ## Authentication 37 | 38 | - [Auth0](https://auth0.com/) - Never Compromise on Identity. 39 | 40 | ## Collecting Feedback 41 | 42 | - [Canny](https://canny.io) - Track feedback to build better products. 43 | 44 | ## Scheduling 45 | 46 | - [Calendly](https://calendly.com) - Calendly helps you schedule meetings without the back-and-forth emails. 47 | - [FreeBusy](http://freebusy.io/) The complete solution to automate meeting scheduling. 48 | - [There](https://there.team/) - The base for collaborating clearly & smoothly in remote teams. 49 | 50 | ## Calls / Confrencing 51 | 52 | - [Zoom](https://zoom.us) - Cloud video conferencing and simple online meetings. 53 | - [Discord](https://discordapp.com) - All-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone. 54 | 55 | ## Forms 56 | 57 | - [Typeform](https://www.typeform.com) - The future of forms is here. 58 | - [Google Forms](https://www.google.com/forms/about/) - Create effortless forms. 59 | 60 | ## Search 61 | 62 | - [Algolia](https://www.algolia.com) - Fast, reliable and modern search and discovery. 63 | 64 | ## PaaS (Platform as a Service) 65 | 66 | - [Heroku](https://heroku.com). 67 | - [Render](https://render.com). 68 | - [Google App Engine](https://cloud.google.com/appengine/). 69 | 70 | ## Communication APIs 71 | 72 | - [Twilio](https://twilio.com) - Communication APIs for SMS, voice, video, and authentication. 73 | 74 | ## Email Clients 75 | 76 | - [Spark](https://sparkmailapp.com/) - Love your email again. 77 | 78 | ## Password Managers 79 | 80 | - [1Password](https://1password.com) - Go ahead. Forget your passwords. 81 | 82 | ## Email Services 83 | 84 | - [Mailgun](https://www.mailgun.com/) - The Email Service for Developers. 85 | - [SendGrid](https://sendgrid.com) - Partner with the email service trusted by developers and marketers for time-savings, scalability, and delivery expertise.. 86 | 87 | ## Payment Gateways 88 | 89 | - [Stripe](https://stripe.com) - The new standard in online payments. 90 | 91 | ## Continuous Integration 92 | 93 | - [CircleCI](https://circleci.com/) - Automate your development process quickly, safely, and at scale.. 94 | - [GitHub Actions](https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/) - Fast CI/CD for any OS, any language, and any cloud. 95 | - [GitLab CI](https://about.gitlab.com/product/continuous-integration/) - GitLab CI/CD pipelines build, test, deploy, and monitor your code as part of a single, integrated workflow. 96 | 97 | ## JAMstack 98 | 99 | *See: https://jamstack.org* 100 | 101 | ### Hosting 102 | 103 | - [Netlify](https://netlify.com) - All-in-one platform for automating modern web projects. 104 | 105 | ### Management / Building 106 | 107 | - [Stackbit](https://www.stackbit.com/) - Build Modern JAMstack Websites in Minutes. Combine any Theme, Site Generator and CMS without complicated integrations. 108 | 109 | ### CMS 110 | 111 | - [NetlifyCMS](https://www.netlifycms.org/). 112 | - [TinaCMS](https://tinacms.org/). 113 | - [Contentful](https://www.contentful.com/). -------------------------------------------------------------------------------- /biology/README.md: -------------------------------------------------------------------------------- 1 | # Biology 2 | 3 | -------------------------------------------------------------------------------- /biology/species/README.md: -------------------------------------------------------------------------------- 1 | # Species 2 | 3 | -------------------------------------------------------------------------------- /biology/species/ants.md: -------------------------------------------------------------------------------- 1 | # Ants 2 | 3 | ### Links 4 | 5 | * [Here's Why Ants Are Practically Immune to Traffic Jams, Even on Crowded Roads](https://www.sciencealert.com/ant-roads-are-practically-immune-to-traffic-jams-even-when-it-gets-crowded). 6 | 7 | -------------------------------------------------------------------------------- /design/README.md: -------------------------------------------------------------------------------- 1 | # Design 2 | 3 | -------------------------------------------------------------------------------- /design/icons/README.md: -------------------------------------------------------------------------------- 1 | # Icons 2 | 3 | -------------------------------------------------------------------------------- /design/icons/icon-sets.md: -------------------------------------------------------------------------------- 1 | # Icon Sets 2 | 3 | * [Font Awesome](https://fontawesome.com/). 4 | * [Line Awesome](https://icons8.com/line-awesome). 5 | 6 | -------------------------------------------------------------------------------- /devops/README.md: -------------------------------------------------------------------------------- 1 | # DevOps 2 | 3 | -------------------------------------------------------------------------------- /devops/databases/README.md: -------------------------------------------------------------------------------- 1 | # Databases 2 | 3 | -------------------------------------------------------------------------------- /devops/databases/estimating-connections.md: -------------------------------------------------------------------------------- 1 | # Estimating Connections 2 | 3 | ## Links 4 | 5 | * [Heroku PostgreSQL Connection Calculator](https://railsautoscale.com/heroku-postgresql-connection-calculator/) 6 | 7 | -------------------------------------------------------------------------------- /devops/kubernetes/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes 2 | 3 | _See_ [_Terminology_](https://github.com/obahareth/knowledge/tree/333c0901236edb40cfc5774172c5b200f5f2fe58/devops/kubernetes/terminology.md) _for a reference_ 4 | 5 | Kubernetes \(K8s\) is an open-source orchestration system for automating deployment, scaling, and management of containerized applications. 6 | 7 | \[TOC\] 8 | 9 | ## Architecture 10 | 11 | ![](https://www.aquasec.com/wiki/download/attachments/2855092/kubertes.png?version=1&modificationDate=1520363380138&api=v2) 12 | 13 | ​ \(Image taken from [https://x-team.com/blog/introduction-kubernetes-architecture/](https://x-team.com/blog/introduction-kubernetes-architecture/)\) 14 | 15 | * Everything must be in a namespace, a **default** namespace is created when you create a cluster. 16 | 17 | ## Default objects 18 | 19 | ### Master Node \(one is always present in a cluster\) 20 | 21 | * **API Server** - Allows interaction with kubernetes API, it's the frontend for the control plane. 22 | * **kube-scheduler** - Assigns **pods** to **nodes** at runtime, and checks resources, quality of service, policies, and specifications before scheduling 23 | * **Controller Manager** - Runs **controllers** \(background threads that run tasks in a cluster\). It's compiled into a single binary and has a number of roles: 24 | * **Node Controller** - Responsible for worker states. 25 | * **Replication Controller** - Responsible for maintining correct number of **pods** for replicated controllers. 26 | * **Endpoint Controller** - Responsible for joining **services** and **pods** togethers 27 | * **Service Account Contoller and Token Controller** - Responisble for handling access management to **API Server**. 28 | 29 | ### etcd 30 | 31 | Database used by Kubernetes to store all cluster data \(job scheduling info, pod details, stage information, etc.\). 32 | 33 | ### kubectl 34 | 35 | Commandline interface used to interact with the **master node**. It can be prunounced as Kube Cuttle. Kubectl has a config file which has server information and authentication information to access the API server. 36 | 37 | ## Nodes 38 | 39 | A Node requires the following to be running: 40 | 41 | * **Supervisord** - Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems 42 | * **Container tooling** \(e.g. Docker\) 43 | 44 | ### kubelet 45 | 46 | The main service on a node, regularly taking in new or modified pod specifications \(primarily through the kube-apiserver\) and ensuring that pods and their containers are healthy and running in the desired state. This component also reports to the master on the health of the host where it is running. It executed pod containers via the container engine and mounts pod volume and secrets. **Kubelet must be running on all nodes**, and if it isn't working correctly, you're going to have issues. 47 | 48 | It takes a set of **Podspec**s \(Yaml files provided by API Server\) that describe a pod. 49 | 50 | Kubelet only manages containers that were created by the API server, not any container running on the node. 51 | 52 | ### kube-proxy 53 | 54 | A proxy service that runs on each worker node to deal with individual host subnetting and expose services to the external world. It performs request forwarding to the correct pods/containers across the various isolated networks in a cluster. **kube-proxy must be running in each node**. 55 | 56 | * It can do simple network stream or round-robin forwarding across a set of backends. 57 | * Services definged against the API server: kube-proxy watches the API server for the addition and removal of services. 58 | * For each new service, kube-proxy opens a **randomly chosen port** on the local node. 59 | * Connections made to the chosen port are proxied to one of the corresponding back-end pods. 60 | 61 | Modes of kube-proxy: 62 | 63 | * User space mode \(most common\). 64 | * Iptables mode. 65 | * Ipvs mode. 66 | 67 | ## Pods 68 | 69 | A pod is one or more containers that should be controlled as a single application. It encapsulates application containers, storage resources, a unique network ID and other configuration on how to run the containers. 70 | 71 | Pods are ephemeral/disposable, they never self-heal and are not restarted by the scheduler, never create them by themselves in production. Instead use higher level constructs like **controllers**. 72 | 73 | **States** 74 | 75 | * **Pending** - Accepted by Kubernetes system but a container hasn't been created yet. 76 | * **Running** - A pod has been scheduled on a node, all containers have been created, and at least one container is in the **running** state. 77 | * **Succeeded** - All containers in the pod have exited with a status of 0 \(successful execution and will not be restarted\) 78 | * **Failed** - All containers have exited and at least one has failed \(returned non-zero exit status\) 79 | * **CrashLoopBackOff** - A container fails to start and Kubernetes keeps trying to restart it 80 | 81 | ## Controllers 82 | 83 | In Kubernetes, controllers are control loops that watch the state of your **cluster**, then make or request changes where needed. Each **controller** tries to move the current **cluster state** closer to the desired state. They help with application reliability, scaling, and load balancing. 84 | 85 | ### Controller Types 86 | 87 | #### ReplicaSet 88 | 89 | Ensures that the specified number of **replicas** for a **pod** are **running at all times**. 90 | 91 | #### Deployment 92 | 93 | Most applications are packaged as Deployments. Deployments provide declarative updates for **pods** and **ReplicaSets**. Used to describe desired state in a YAML file and the Deployment controller will align the actual state to match. Can be used to create new **ReplicaSets** or replace them with new ones. A **Deployment** manages the **ReplicaSet**, and the **ReplicaSet** manages the **Pod**. This architecture allows deployments to support a rollback mechanism. 94 | 95 | A new **ReplicaSet** is created each time a new Deployment config is deployed but the old ReplicaSet is still kept to allow for easier rollbacks. 96 | 97 | **Use-cases** 98 | 99 | * **Pod management** - Running a ReplicaSet allows us to deploy a number of pods and check their status as a single unit. 100 | * Scaling a ReplicaSet scales out the pods and allows for a deployment to handle more traffic. 101 | * **Pause and Resume** \(traffic will still get passed to existing replica set\) 102 | * Used with larger changesets. 103 | * Pause, make changes, and resume deployment. 104 | 105 | #### DaemonSet 106 | 107 | Ensures all nodes run a copy of a specific pod. As nodes are added or removed from the cluster, a DaemonSet will add or remove the required pods. 108 | 109 | **Use-cases** 110 | 111 | * Run a single log aggregator. 112 | * Monitoring agent. 113 | 114 | #### Job 115 | 116 | Supervisor process for pods carrying out batch jobs. Used to run individual processes that need to run once and complete successfully. 117 | 118 | **Use-cases** 119 | 120 | * Cron job to run nightly report or database backup. 121 | 122 | #### Service 123 | 124 | Allows the comunication between one set of deployments with another. When a service is created it is assigned a unique IP address that never changes throughout the lifetime of the service. Pods are then configured to talk to the service and can rely on the service IP on any requests that might be sent to the pod. Services are an important concept because they allow one set of pods to communicate with another set of pods in an easy way. 125 | 126 | **Example** 127 | 128 | Frontend deployment needs to talk to backend deployment \(which consists of multiple pods\), a backend service can provide a single IP for the frontend pod to talk with. 129 | 130 | **Kinds of Services** 131 | 132 | * **Internal** - IP is only reachable within the cluster 133 | * **External** - Endpoint available through node IP \(known as **NodePort**\) 134 | * **Load balancer** - Exposes application to the internet with a load balancer \(available with a cloud provider\) 135 | 136 | ## Labels and Selectors 137 | 138 | Covered in the [terminology page](https://github.com/obahareth/knowledge/tree/333c0901236edb40cfc5774172c5b200f5f2fe58/devops/kubernetes/terminology.md). 139 | 140 | ## Namespaces 141 | 142 | * Allows teams to access resources, with accountability. 143 | * Great way to divide cluster resources between users. 144 | * Names for resources **must be unique within a namespace**. 145 | * A **default** namespace is created when kubernetes is launched. 146 | * Newer applications install their resources in a different namespace so they don't interfere with an existing cluster. 147 | 148 | ## Maintenance 149 | 150 | * Features are backward-compatible and APIs are versioned. 151 | * Host can be turned off/on during maintenance. 152 | 153 | ## Logging and Monitoring 154 | 155 | **Application Monitoring** 156 | 157 | * Built-in TCP/HTTP/container-execution health checks. 158 | 159 | **Node health check** 160 | 161 | * Failures are monitored by node controller. 162 | 163 | **Kubernetes status** 164 | 165 | * Can be monitored through addons like [metrics-server](https://github.com/kubernetes-sigs/metrics-server) or the [Prometheus Operator](https://github.com/coreos/prometheus-operator). 166 | 167 | ## Limitations 168 | 169 | _As of 1.16, see_ [_official Limitations page_](https://kubernetes.io/docs/setup/best-practices/cluster-large/)_._ 170 | 171 | * No more than 5000 nodes 172 | * No more than 150000 total pods 173 | * No more than 300000 total containers 174 | * No more than 100 pods per node 175 | 176 | ## References 177 | 178 | * [Kubernetes Architecture 101](https://www.aquasec.com/wiki/display/containers/Kubernetes+Architecture+101) 179 | * [Learning Kubernetes](https://www.linkedin.com/learning/learning-kubernetes) 180 | 181 | -------------------------------------------------------------------------------- /devops/kubernetes/application-health-checks.md: -------------------------------------------------------------------------------- 1 | # Application Health Checks 2 | 3 | ## Readiness Probe 4 | 5 | Used to know when a **container is ready to accept traffic**. It can be configured to wait for a number of seconds after pod startup before applying health checking, and with a number of seconds to time out. 6 | 7 | Types of readiness probes: 8 | 9 | * HTTP probe. 10 | 11 | ## Liveness Probe 12 | 13 | Periodic check used be Kubernetes to make sure the **container is still healthy**. 14 | 15 | -------------------------------------------------------------------------------- /devops/kubernetes/best-practices.md: -------------------------------------------------------------------------------- 1 | # Best Practices 2 | 3 | ## Links 4 | 5 | * [Kubernetes in Production: Readiness Checklist and Best Practices for Resource Management](https://www.replex.io/blog/kubernetes-in-production-readiness-checklist-and-best-practices-for-resource-management) 6 | * [Configuration Best Practices](https://kubernetes.io/docs/concepts/configuration/overview/) 7 | * [Setup Best Practices](https://kubernetes.io/docs/setup/best-practices/) 8 | * [A Practical Guide to Setting Kubernetes Requests and Limits](http://blog.kubecost.com/blog/requests-and-limits/) 9 | 10 | -------------------------------------------------------------------------------- /devops/kubernetes/kubectl-cheatsheet.md: -------------------------------------------------------------------------------- 1 | # kubectl Cheatsheet 2 | 3 | \[TOC\] 4 | 5 | ## References 6 | 7 | * [cheatsheet-kubernetes-A4](https://github.com/dennyzhang/cheatsheet-kubernetes-A4) \([Internet Archive link](https://web.archive.org/web/20191112135614/https://github.com/dennyzhang/cheatsheet-kubernetes-A4)\). This page is taken from it. 8 | 9 | ## 1.1 Common Commands 10 | 11 | | Name | Command | 12 | | :--- | :--- | 13 | | Run curl test temporarily | `kubectl run --rm mytest --image=yauritux/busybox-curl -it` | 14 | | Run wget test temporarily | `kubectl run --rm mytest --image=busybox -it` | 15 | | Run nginx deployment with 2 replicas | `kubectl run my-nginx --image=nginx --replicas=2 --port=80` | 16 | | Run nginx pod and expose it | `kubectl run my-nginx --restart=Never --image=nginx --port=80 --expose` | 17 | | Run nginx deployment and expose it | `kubectl run my-nginx --image=nginx --port=80 --expose` | 18 | | Set namespace preference | `kubectl config set-context --namespace=` | 19 | | List pods with nodes info | `kubectl get pod -o wide` | 20 | | List everything | `kubectl get all --all-namespaces` | 21 | | Get all services | `kubectl get service --all-namespaces` | 22 | | Get all deployments | `kubectl get deployments --all-namespaces` | 23 | | Show nodes with labels | `kubectl get nodes --show-labels` | 24 | | Get resources with json output | `kubectl get pods --all-namespaces -o json` | 25 | | Validate yaml file with dry run | `kubectl create --dry-run --validate -f pod-dummy.yaml` | 26 | | Start a temporary pod for testing | `kubectl run --rm -i -t --image=alpine test-$RANDOM -- sh` | 27 | | kubectl run shell command | `kubectl exec -it mytest -- ls -l /etc/hosts` | 28 | | Get system conf via configmap | `kubectl -n kube-system get cm kubeadm-config -o yaml` | 29 | | Get deployment yaml | `kubectl -n denny-websites get deployment mysql -o yaml` | 30 | | Explain resource | `kubectl explain pods`, `kubectl explain svc` | 31 | | Watch pods | `kubectl get pods -n wordpress --watch` | 32 | | Query healthcheck endpoint | `curl -L http://127.0.0.1:10250/healthz` | 33 | | Open a bash terminal in a pod | `kubectl exec -it storage sh` | 34 | | Check pod environment variables | `kubectl exec redis-master-ft9ex env` | 35 | | Enable kubectl shell autocompletion | `echo "source <(kubectl completion bash)" >>~/.bashrc`, and reload | 36 | | Use minikube dockerd in your laptop | `eval $(minikube docker-env)`, No need to push docker hub any more | 37 | | Kubectl apply a folder of yaml files | `kubectl apply -R -f .` | 38 | | Get services sorted by name | kubectl get services –sort-by=.metadata.name | 39 | | Get pods sorted by restart count | kubectl get pods –sort-by=’.status.containerStatuses\[0\].restartCount’ | 40 | | List pods and images | kubectl get pods -o=’custom-columns=PODS:.metadata.name,Images:.spec.containers\[\*\].image’ | 41 | | List all container images | [list-all-images.sh](https://github.com/dennyzhang/cheatsheet-kubernetes-A4/blob/master/list-all-images.sh#L14-L17) | 42 | | kubeconfig skip tls verification | [skip-tls-verify.md](https://github.com/dennyzhang/cheatsheet-kubernetes-A4/blob/master/skip-tls-verify.md) | 43 | | [Ubuntu install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) | =”deb [apt.kubernetes.io](https://apt.kubernetes.io/) kubernetes-xenial main”= | 44 | | Reference | [GitHub: kubernetes releases](https://github.com/kubernetes/kubernetes/tags) | 45 | | Reference | [minikube cheatsheet](https://cheatsheet.dennyzhang.com/cheatsheet-minikube-A4), [docker cheatsheet](https://cheatsheet.dennyzhang.com/cheatsheet-docker-A4), [OpenShift CheatSheet](https://cheatsheet.dennyzhang.com/cheatsheet-openshift-A4) | 46 | 47 | ## 1.2 Check Performance 48 | 49 | | Name | Command | 50 | | :--- | :--- | 51 | | Get node resource usage | `kubectl top node` | 52 | | Get pod resource usage | `kubectl top pod` | 53 | | Get resource usage for a given pod | `kubectl top --containers` | 54 | | List resource utilization for all containers | `kubectl top pod --all-namespaces --containers=true` | 55 | 56 | ## 1.3 Resources Deletion 57 | 58 | | Name | Command | 59 | | :--- | :--- | 60 | | Delete pod | `kubectl delete pod/ -n` | 61 | | Delete pod by force | `kubectl delete pod/ --grace-period=0 --force` | 62 | | Delete pods by labels | `kubectl delete pod -l env=test` | 63 | | Delete deployments by labels | `kubectl delete deployment -l app=wordpress` | 64 | | Delete all resources filtered by labels | `kubectl delete pods,services -l name=myLabel` | 65 | | Delete resources under a namespace | `kubectl -n my-ns delete po,svc --all` | 66 | | Delete persist volumes by labels | `kubectl delete pvc -l app=wordpress` | 67 | | Delete state fulset only \(not pods\) | `kubectl delete sts/ --cascade=false` | 68 | 69 | ## 1.4 Log & Conf Files 70 | 71 | | Name | Comment | 72 | | :--- | :--- | 73 | | Config folder | `/etc/kubernetes/` | 74 | | Certificate files | `/etc/kubernetes/pki/` | 75 | | Credentials to API server | `/etc/kubernetes/kubelet.conf` | 76 | | Superuser credentials | `/etc/kubernetes/admin.conf` | 77 | | kubectl config file | `~/.kube/config` | 78 | | Kubernets working dir | `/var/lib/kubelet/` | 79 | | Docker working dir | `/var/lib/docker/`, `/var/log/containers/` | 80 | | Etcd working dir | `/var/lib/etcd/` | 81 | | Network cni | `/etc/cni/net.d/` | 82 | | Log files | `/var/log/pods/` | 83 | | log in worker node | `/var/log/kubelet.log`, `/var/log/kube-proxy.log` | 84 | | log in master node | `kube-apiserver.log`, `kube-scheduler.log`, `kube-controller-manager.log` | 85 | | Env | `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf` | 86 | | Env | export KUBECONFIG=/etc/kubernetes/admin.conf | 87 | 88 | ## 1.5 Pod 89 | 90 | | Name | Command | 91 | | :--- | :--- | 92 | | List all pods | `kubectl get pods` | 93 | | List pods for all namespace | `kubectl get pods -all-namespaces` | 94 | | List all critical pods | `kubectl get -n kube-system pods -a` | 95 | | List pods with more info | `kubectl get pod -o wide`, `kubectl get pod/ -o yaml` | 96 | | Get pod info | `kubectl describe pod/srv-mysql-server` | 97 | | List all pods with labels | `kubectl get pods --show-labels` | 98 | | [List all unhealthy pods](https://github.com/kubernetes/kubernetes/issues/49387) | kubectl get pods –field-selector=status.phase!=Running –all-namespaces | 99 | | List running pods | kubectl get pods –field-selector=status.phase=Running | 100 | | Get Pod initContainer status | `kubectl get pod --template '{{.status.initContainerStatuses}}'` | 101 | | kubectl run command | kubectl exec -it -n “$ns” “$podname” – sh -c “echo $msg >>/dev/err.log” | 102 | | Watch pods | `kubectl get pods -n wordpress --watch` | 103 | | Get pod by selector | kubectl get pods –selector=”app=syslog” -o jsonpath=’{.items\[\*\].metadata.name}’ | 104 | | List pods and images | kubectl get pods -o=’custom-columns=PODS:.metadata.name,Images:.spec.containers\[\*\].image’ | 105 | | List pods and containers | -o=’custom-columns=PODS:.metadata.name,CONTAINERS:.spec.containers\[\*\].name’ | 106 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates) | 107 | 108 | ## 1.6 Label & Annontation 109 | 110 | | Name | Command | 111 | | :--- | :--- | 112 | | Filter pods by label | `kubectl get pods -l owner=denny` | 113 | | Manually add label to a pod | `kubectl label pods dummy-input owner=denny` | 114 | | Remove label | `kubectl label pods dummy-input owner-` | 115 | | Manually add annonation to a pod | `kubectl annotate pods dummy-input my-url=https://dennyzhang.com` | 116 | 117 | ## 1.7 Deployment & Scale 118 | 119 | | Name | Command | 120 | | :--- | :--- | 121 | | Scale out | `kubectl scale --replicas=3 deployment/nginx-app` | 122 | | online rolling upgrade | `kubectl rollout app-v1 app-v2 --image=img:v2` | 123 | | Roll backup | `kubectl rollout app-v1 app-v2 --rollback` | 124 | | List rollout | `kubectl get rs` | 125 | | Check update status | `kubectl rollout status deployment/nginx-app` | 126 | | Check update history | `kubectl rollout history deployment/nginx-app` | 127 | | Pause/Resume | `kubectl rollout pause deployment/nginx-deployment`, `resume` | 128 | | Rollback to previous version | `kubectl rollout undo deployment/nginx-deployment` | 129 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates), [Link: Pausing and Resuming a Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#pausing-and-resuming-a-deployment) | 130 | 131 | ## 1.8 Quota & Limits & Resource 132 | 133 | | Name | Command | 134 | | :--- | :--- | 135 | | List Resource Quota | `kubectl get resourcequota` | 136 | | List Limit Range | `kubectl get limitrange` | 137 | | Customize resource definition | `kubectl set resources deployment nginx -c=nginx --limits=cpu=200m` | 138 | | Customize resource definition | `kubectl set resources deployment nginx -c=nginx --limits=memory=512Mi` | 139 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates) | 140 | 141 | ## 1.9 Service 142 | 143 | | Name | Command | 144 | | :--- | :--- | 145 | | List all services | `kubectl get services` | 146 | | List service endpoints | `kubectl get endpoints` | 147 | | Get service detail | `kubectl get service nginx-service -o yaml` | 148 | | Get service cluster ip | kubectl get service nginx-service -o go-template=’’ | 149 | | Get service cluster port | kubectl get service nginx-service -o go-template=’’ | 150 | | Expose deployment as lb service | `kubectl expose deployment/my-app --type=LoadBalancer --name=my-service` | 151 | | Expose service as lb service | `kubectl expose service/wordpress-1-svc --type=LoadBalancer --name=ns1` | 152 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates) | 153 | 154 | ## 1.10 Secrets 155 | 156 | | Name | Command | 157 | | :--- | :--- | 158 | | List secrets | `kubectl get secrets --all-namespaces` | 159 | | Generate secret | `echo -n 'mypasswd'=, then redirect to =base64 --decode` | 160 | | Get secret | `kubectl get secret denny-cluster-kubeconfig` | 161 | | Get a specific field of a secret | kubectl get secret denny-cluster-kubeconfig -o jsonpath=”{.data.value}” | 162 | | Create secret from cfg file | kubectl create secret generic db-user-pass –from-file=./username.txt | 163 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates), [Link: Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) | 164 | 165 | ## 1.11 StatefulSet 166 | 167 | | Name | Command | 168 | | :--- | :--- | 169 | | List statefulset | `kubectl get sts` | 170 | | Delete statefulset only \(not pods\) | `kubectl delete sts/ --cascade=false` | 171 | | Scale statefulset | `kubectl scale sts/ --replicas=5` | 172 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates) | 173 | 174 | ## 1.12 Volumes & Volume Claims 175 | 176 | | Name | Command | 177 | | :--- | :--- | 178 | | List storage class | `kubectl get storageclass` | 179 | | Check the mounted volumes | `kubectl exec storage ls /data` | 180 | | Check persist volume | `kubectl describe pv/pv0001` | 181 | | Copy local file to pod | `kubectl cp /tmp/my /:/tmp/server` | 182 | | Copy pod file to local | `kubectl cp /:/tmp/server /tmp/my` | 183 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates) | 184 | 185 | ## 1.13 Events & Metrics 186 | 187 | | Name | Command | 188 | | :--- | :--- | 189 | | View all events | `kubectl get events --all-namespaces` | 190 | | List Events sorted by timestamp | kubectl get events –sort-by=.metadata.creationTimestamp | 191 | 192 | ## 1.14 Node Maintenance 193 | 194 | | Name | Command | 195 | | :--- | :--- | 196 | | Mark node as unschedulable | `kubectl cordon $NDOE_NAME` | 197 | | Mark node as schedulable | `kubectl uncordon $NDOE_NAME` | 198 | | Drain node in preparation for maintenance | `kubectl drain $NODE_NAME` | 199 | 200 | ## 1.15 Namespace & Security 201 | 202 | | Name | Command | 203 | | :--- | :--- | 204 | | List authenticated contexts | `kubectl config get-contexts`, `~/.kube/config` | 205 | | Set namespace preference | `kubectl config set-context --namespace=` | 206 | | Load context from config file | `kubectl get cs --kubeconfig kube_config.yml` | 207 | | Switch context | `kubectl config use-context` | 208 | | Delete the specified context | `kubectl config delete-context` | 209 | | List all namespaces defined | `kubectl get namespaces` | 210 | | List certificates | `kubectl get csr` | 211 | | [Check user privilege](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) | kubectl –as=system:serviceaccount:ns-denny:test-privileged-sa -n ns-denny auth can-i use pods/list | 212 | | [Check user privilege](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) | `kubectl auth can-i use pods/list` | 213 | | Reference | [Link: kubernetes yaml templates](https://cheatsheet.dennyzhang.com/kubernetes-yaml-templates) | 214 | 215 | ## 1.16 Network 216 | 217 | | Name | Command | 218 | | :--- | :--- | 219 | | Temporarily add a port-forwarding | `kubectl port-forward redis-134 6379:6379` | 220 | | Add port-forwaring for deployment | `kubectl port-forward deployment/redis-master 6379:6379` | 221 | | Add port-forwaring for replicaset | `kubectl port-forward rs/redis-master 6379:6379` | 222 | | Add port-forwaring for service | `kubectl port-forward svc/redis-master 6379:6379` | 223 | | Get network policy | `kubectl get NetworkPolicy` | 224 | 225 | ## 1.17 Patch 226 | 227 | | Name | Summary | 228 | | :--- | :--- | 229 | | Patch service to loadbalancer | =kubectl patch svc $svc\_name -p ‘{“spec”: {“type”: “LoadBalancer”}}’= | 230 | 231 | ## 1.18 Extenstions 232 | 233 | | Name | Summary | 234 | | :--- | :--- | 235 | | Enumerates the resource types available | `kubectl api-resources` | 236 | | List api group | `kubectl api-versions` | 237 | | List all CRD | `kubectl get crd` | 238 | | List storageclass | `kubectl get storageclass` | 239 | 240 | ## 1.19 Components & Services 241 | 242 | ### 1.19.1 Services on Master Nodes 243 | 244 | | Name | Summary | 245 | | :--- | :--- | 246 | | [kube-apiserver](https://github.com/kubernetes/kubernetes/tree/master/cmd/kube-apiserver) | exposes the Kubernetes API from master nodes | 247 | | [etcd](https://coreos.com/etcd/) | reliable data store for all k8s cluster data | 248 | | [kube-scheduler](https://github.com/kubernetes/kubernetes/tree/master/cmd/kube-scheduler) | schedule pods to run on selected nodes | 249 | | [kube-controller-manager](https://github.com/kubernetes/kubernetes/tree/master/cmd/kube-controller-manager) | node controller, replication controller, endpoints controller, and service account & token controllers | 250 | 251 | ### 1.19.2 Services on Worker Nodes 252 | 253 | | Name | Summary | 254 | | :--- | :--- | 255 | | [kubelet](https://github.com/kubernetes/kubernetes/tree/master/cmd/kubelet) | makes sure that containers are running in a pod | 256 | | [kube-proxy](https://github.com/kubernetes/kubernetes/tree/master/cmd/kube-proxy) | perform connection forwarding | 257 | | [Container Runtime](https://github.com/docker/engine) | Kubernetes supported runtimes: Docker, rkt, runc and any [OCI runtime-spec](https://github.com/opencontainers/runtime-spec) implementation. | 258 | 259 | ### 1.19.3 Addons: pods and services that implement cluster features 260 | 261 | | Name | Summary | 262 | | :--- | :--- | 263 | | DNS | serves DNS records for Kubernetes services | 264 | | Web UI | a general purpose, web-based UI for Kubernetes clusters | 265 | | Container Resource Monitoring | collect, store and serve container metrics | 266 | | Cluster-level Logging | save container logs to a central log store with search/browsing interface | 267 | 268 | ### 1.19.4 Tools 269 | 270 | | Name | Summary | 271 | | :--- | :--- | 272 | | [kubectl](https://github.com/kubernetes/kubernetes/tree/master/cmd/kubectl) | the command line util to talk to k8s cluster | 273 | | [kubeadm](https://github.com/kubernetes/kubernetes/tree/master/cmd/kubeadm) | the command to bootstrap the cluster | 274 | | [kubefed](https://kubernetes.io/docs/reference/setup-tools/kubefed/kubefed/) | the command line to control a Kubernetes Cluster Federation | 275 | | Kubernetes Components | [Link: Kubernetes Components](https://kubernetes.io/docs/concepts/overview/components/) | 276 | 277 | -------------------------------------------------------------------------------- /devops/kubernetes/ruby-on-rails.md: -------------------------------------------------------------------------------- 1 | # Ruby on Rails 2 | 3 | \[TOC\] 4 | 5 | ## References 6 | 7 | * [kubernetes-rails.com](http://kubernetes-rails.com/) by [Marco Colli](http://collimarco.com/) is a goldmine of information on running Rails on Kubernetes. I've archived it using the Wayback Machine just in case [here](https://web.archive.org/web/20191112135115/http://kubernetes-rails.com/). This page is taken from it. 8 | 9 | ## Deploying a Rails application to Kubernetes 10 | 11 | There are many ways to deploy a Ruby on Rails application: one of them is using Docker containers and Kubernetes for orchestration. This guide shows some of the advantages of Kubernetes compared to other solutions and explains how to deploy a Rails application in production using Kubernetes. We focus on the usage of containers for production, rather than development, and we value simple solutions. This guide covers all the common aspects required for running a Rails application in production, including the deployment and continuous delivery of the web application, the configuration of a load balancer and domain, the environment variables and secrets, the compilation of assets, the database migrations, logging and monitoring, the background workers and cron jobs, and how to run maintenance tasks and updates. 12 | 13 | ## History and alternatives to Kubernetes 14 | 15 | The easiest way for deploying a Rails application is probably using a PaaS, like Heroku, which makes the deployment and scaling extremely simple and lets you forget about servers. However: 16 | 17 | * as the application scales, the cost may become prohibitive for your kind of business; 18 | * you don't have full control of your application, which is managed by others, and this may raise concerns about uptime; 19 | * you have constraints imposed by the platform; 20 | * your application may become bounded to a specific platform, raising portability concerns. 21 | 22 | A cheaper alternative is using a IaaS, like DigitalOcean. You can start with a single server, but soon you will need to scale horizontally on multiple servers. Usually you have at least one load balancer with HAProxy, some web servers with nginx and Puma, a database \(probably Postgresql and Redis with replicas\) and maybe some separate servers for background processing \(e.g. Sidekiq\). When you need to scale the application you just create a snapshot of a server and you replicate it. You can also manage or update multiple servers with pssh or using configuration management tools like Chef and the application can be easily deployed with Capistrano. It is not very hard to create and configure a bunch of servers. However: 23 | 24 | * the initial setup requires some time and knowledge; 25 | * applying changes to many servers may become painful; 26 | * running the wrong command on a fleet of servers may be difficult to revert; 27 | * you must make sure to keep all the servers updated with the same configuration; 28 | * scaling requires a lot of manual work. 29 | 30 | Kubernetes offers the advantages of a PaaS at the cost of a IaaS, so it is a good compromise that you should consider. It is also an open source technology and most cloud providers already offer it as a managed service. 31 | 32 | Let's see how to deploy a Rails application in production using Kubernetes. 33 | 34 | ## Prerequisites 35 | 36 | This guide assumes that you already have general knowledge about web development. 37 | 38 | We also expect that you already have a development machine with all the necessary applciations installed, including Ruby \(e.g. using rbenv\), Ruby on Rails, Git, Docker, etc. 39 | 40 | You also need to have an account on Docker Hub and DigitalOcean in order to try Kubernetes \(or you can use your favorite alternatives\). 41 | 42 | ## The Rails application 43 | 44 | You can use an existing Rails application or you can create an example Rails application with this command: 45 | 46 | ```bash 47 | rails new kubernetes-rails-example 48 | ``` 49 | 50 | Then add a simple page to the example application: 51 | 52 | _config/routes.rb\*\*app/controllers/pages\_controller.rb_ 53 | 54 | ```ruby 55 | class PagesController < ApplicationController 56 | def home 57 | end 58 | end 59 | ``` 60 | 61 | _app/views/pages/home.html.erb_ 62 | 63 | ## The Git repository 64 | 65 | Let's save the changes in the local Git repository, which was already initialized by Rails: 66 | 67 | ```text 68 | git add . 69 | git commit -m "Initial commit" 70 | ``` 71 | 72 | Then we need to create a Git repository online. Go to Github and create a new repository, then connect the local repository to the remote one and publish the changes: 73 | 74 | ```text 75 | git remote add origin https://github.com/username/kubernetes-rails-example.git 76 | git push -u origin master 77 | ``` 78 | 79 | Although a Git repository is not strictly required for Docker and Kubernetes, I mention it here because most CI/CD tools, including Docker Hub, can be connected to your Git repository in order to build the Docker image automatically whenever you push some changes. 80 | 81 | ## The Docker image 82 | 83 | First step for containerization is to create the Docker image. A Docker image is simply a package which contains our application, together with all the dependencies and system libraries needed to run it. 84 | 85 | Add this file in the root folder of your Rails application: 86 | 87 | _Dockerfile_ 88 | 89 | First we use `FROM` to tell Docker to download a public image, which is then used as the base for our custom image. In particular we use an image which contains a specific version of Ruby. 90 | 91 | Then we use `RUN` to execute a command inside the image that we are building. In particular we use `apt-get` to install some libraries. Note that the libraries available on the default Ubuntu repositories are usually quite old: if you want to get the latest versions you need to update the repository list and tell APT to download the libraries directly from the maintainer's repository. In particular, just before `apt-get`, we can add the following commands to update the Node.js and Yarn repositories: 92 | 93 | ```text 94 | RUN curl https://deb.nodesource.com/setup_12.x | bash 95 | RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 96 | RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list 97 | ``` 98 | 99 | In the next block of code, we copy our Rails application to the image and we install all the required gems using Bundler. The Gemfile is copied before the other application code because Docker can use caching to build the image faster in case there aren't any changes to the Gemfile. 100 | 101 | We also run a task to precompile the assets \(stylesheets, scripts, etc.\). 102 | 103 | Finally we configure a default command to be executed on the image. 104 | 105 | Before building the image we want to make sure that some files are not copied to it: this is important to exclude _secrets_, for security, and useless directories, like `tmp` or `.git`, which would be a waste of resources. For this we need to create a `.dockerignore` file in the Rails root: you can usually take inspiration from your `.gitignore`, since the aim and syntax are very similar. 106 | 107 | It's time to build the image: 108 | 109 | ```text 110 | docker build -t username/kubernetes-rails-example:latest . 111 | ``` 112 | 113 | The `-t` option, followed by its argument, is optional: we use it to assign a _name_ and a _tag_ to the new image. This makes it easier to find the image later. We can also use a _repository_ name as the image name, in order to allow push to that repository later. The image name is the part before the colon, while the tag is the part after the colon. Note that we could also omit the tag `latest` since it is the default value used in case the tag is omitted. The last dot is a required argument and indicates the path to the Dockerfile. 114 | 115 | Then you can see that the image is actually available on your machine: 116 | 117 | ```text 118 | docker image ls 119 | ``` 120 | 121 | You can also use the image ID or its name to run the image \(a running image is called a _container_\): 122 | 123 | ```text 124 | docker run -p 3000:3000 username/kubernetes-rails-example:latest 125 | ``` 126 | 127 | Note that we map the host port 3000 \(on the left\) to the container port 3000 \(on the right\). You can also use other ports if you prefer: however, if you change the container port, you also need to update the image to make sure that the Rails server listens on the correct port and you also need to open that port using `EXPOSE`. 128 | 129 | You can now see your webiste by visiting `http://localhost:3000`. 130 | 131 | Finally we can push the image to the online repository. First you need to sign up to Docker Hub, or to another _registry_ and create a _reposotory_ there for your image. Then you can push the local image to the remote repository: 132 | 133 | ```text 134 | docker push username/kubernetes-rails-example:latest 135 | ``` 136 | 137 | ## The Kubernetes cluster 138 | 139 | It's time to create the Kubernetes cluster for production. Go to your favorite Kubernetes provider and create a cluster using the dashboard: we will use DigitalOcean for this tutorial. 140 | 141 | Once the cluster is created you need to downlooad the credential and cluster configuration to your machine, so that you can connect to the cluster. For example you can move the configuration file to `~/.kube/kubernetes-rails-example-kubeconfig.yaml`. Then you need to pass a `--kubeconfig` option to `kubektl` whenever you invoke a command, or you can set an environment variable: 142 | 143 | ```text 144 | export KUBECONFIG=~/.kube/kubernetes-rails-example-kubeconfig.yaml 145 | ``` 146 | 147 | Then you need to make sure that you have Kubernetes installed and that it can connect to the remote cluster. Run this command: 148 | 149 | ```text 150 | kubectl version 151 | ``` 152 | 153 | You should see the version of your command line tools and the version of the cluster. 154 | 155 | You can also play around with this command: 156 | 157 | ```text 158 | kubectl get nodes 159 | ``` 160 | 161 | A _node_ is simply a server managed by Kubernetes. Then Kubernetes creates some virtual machines \(in a broad sense\) called _pods_ on each node, based on our configuration. Pods are distributed automatically by Kubernetes on the available nodes and, in case a node fails, Kubernetes will move the pod to a different node. A pod usually contains a single _container_, but it can also have multiple related containers that need to share some resources. 162 | 163 | The next step is to run some pods with our Docker image. Since our Docker image is probably hosted in a private repository, we need to give the Docker credentials to Kubernetes, so that it can download the image. Run these commands: 164 | 165 | ```text 166 | kubectl create secret docker-registry my-docker-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL 167 | kubectl edit serviceaccounts default 168 | ``` 169 | 170 | And add this to the end after `Secrets`: 171 | 172 | ```yaml 173 | imagePullSecrets: 174 | - name: my-docker-secret 175 | ``` 176 | 177 | Then you can define the Kubernetes configuration: create a `config/kube` directory in your Rails application. 178 | 179 | We start by defining a deploy for the Rails application: 180 | 181 | _config/kube/deployment.yml_ 182 | 183 | The above is a minimal deployment: 184 | 185 | * `apiVersion` sets the API version for the configuration file; 186 | * `kind` sets the type of configuration file; 187 | * `metadata` is used to assign a name to the deployment; 188 | * `replicas` tells Kubernetes to spin up a given number of pods; 189 | * `selector` tells Kubernetes what template to use to generate the pods; 190 | * `template` defines the template for a pod; 191 | * `spec` sets the Docker image that we want to run inside the pods and other configurations, like the container port that must be exposed. 192 | 193 | Now we also need to forward and distribute the HTTP requests to the pods. Let's create a load balancer: 194 | 195 | _config/kube/load\_balancer.yml_ 196 | 197 | Basically we tell the load balancer: 198 | 199 | * listen on the default port 80; 200 | * forward the requests on port 3000 of the pods that have the label `rails-app`. 201 | 202 | Now we can apply the configuration to Kubernetes, using a _declarative_ management: 203 | 204 | ```text 205 | kubectl apply -f config/kube 206 | ``` 207 | 208 | It't time to verify that the pods are running properly: 209 | 210 | 1. `kubectl get pods` shows the pods and their status; 211 | 2. the status for all pods should be `Running`; 212 | 3. if you see the error `ImagePullBackOff` probably you have not configured properly the secret to download the image from your private repository; 213 | 4. you can get more details about any errors by running `kubectl describe pod pod-name`; 214 | 5. you can fix the configurations and then regenerate the pods by running `kubectl delete --all pods`. 215 | 216 | Now you can get the load balancer IP and other information by running the folowing commands: 217 | 218 | ```text 219 | kubectl get services 220 | kubectl describe service service-name 221 | ``` 222 | 223 | In particular you must find the `LoadBalancer Ingress` or `EXTERNAL-IP` and type it in your browser address bar: our website is up and running! 224 | 225 | ## Domain name and SSL 226 | 227 | Probably your users won't access your website using the IP address, so you need to configure a domain name. Add the following record to your DNS: 228 | 229 | ```text 230 | example.com. A 192.0.2.0 231 | ``` 232 | 233 | Obviously you need to replace the domain name with your domain and the IP address with the _external IP_ of the load balancer \(you can get it using `kubectl get services`\). 234 | 235 | An SSL certificate can be added to your website using proprietary YAML configurations, but the easiest way, if you are using DigitalOcean, is to use their dashboard to configure the SSL certificate \(i.e. go to the load balancer settings\). 236 | 237 | ## Environment variables 238 | 239 | There are different solutions for storing environment variables: 240 | 241 | * you can define the env variables inside your Rails configuration; 242 | * you can define the env variables inside your Dockerfile; 243 | * you can define the env variables using Kubernetes. 244 | 245 | I suggest that you use Kubernetes for managing the environment variables for production: that makes it easy to change them without having to build a new image each time. Also Kubernetes has more information available about your environment and it can set some variables dinamically for you \(e.g. it can set a variable with the pod name or IP\). Finally it offers more granularity when you have multiple deployments \(e.g. Puma and Sidekiq\), since you can set different values for each deployment. 246 | 247 | Add the following attribute to your _container_ definition \(e.g. after the `image` attribute\) inside _config/kube/deployment.yml_: 248 | 249 | ```yaml 250 | env: 251 | - name: EXAMPLE 252 | value: This env variable is defined by Kubernetes. 253 | ``` 254 | 255 | Then you can update the Kubernetes cluster by running this command: 256 | 257 | ```text 258 | kubectl apply -f config/kube 259 | ``` 260 | 261 | If you want to make sure that everything works, you can try to print the env variable inside your app. 262 | 263 | For development and test you can use a gem called _dotenv_ to easily define the env variables. 264 | 265 | For production you can also use Kubernetes _ConfigMaps_ to define the env variables. The advantage of using this method is that you can define the env variables once and then use them for different _Deployments_ or _Pods_. For example a Rails application usually requires the followig variables: 266 | 267 | _config/kube/env.yml_ 268 | 269 | Then add the following attribute inside a _container_ definition \(e.g. after the `image` attribute\): 270 | 271 | _config/kube/deployment.yml_ 272 | 273 | Remember that it is not safe to store secrets, like `SECRET_KEY_BASE`, in your Git repository! In the next section we will see how to use Rails credentials to safely store your secrets. 274 | 275 | ## Secrets 276 | 277 | You can store your secrets either in your Rails configuration or using Kubernetes secrets. I suggest that you use the Rails _credentials_ to store your secrets: we will use Kubernetes secrets only to store the master key. Basically we store all our credentials in the Git repository, along with our application, but this is safe because we encrypt them with a master key. Then we use the master key, not stored in the Git repository, to access those secrets. 278 | 279 | Enable this option inside _config/environments/production.rb_: 280 | 281 | ```ruby 282 | config.require_master_key = true 283 | ``` 284 | 285 | Then run this command to edit your credentials: 286 | 287 | ```text 288 | EDITOR="vi" rails credentials:edit 289 | ``` 290 | 291 | While editing the file add the following line and then save and close: 292 | 293 | ```ruby 294 | example_secret: foobar 295 | ``` 296 | 297 | Then inside your app you can try to print the secret: 298 | 299 | _app/views/pages/home.html.erb_ 300 | 301 | Note that starting from Rails 6 you can also define different credentials for different environments. 302 | 303 | If you run your website locally you can see the secret displayed properly. The last thing that we need to do is to give the master key to Kubernetes in a secure way: 304 | 305 | ```text 306 | kubectl create secret generic rails-secrets --from-literal=rails_master_key='example' 307 | ``` 308 | 309 | Your master key is usually stored in _config/master.key_. 310 | 311 | Finally we need to pass the Kubernetes secret as an environment variable to our containers. Add this variable to your `env` inside _config/kube/deployment.yml_: 312 | 313 | ```yaml 314 | - name: RAILS_MASTER_KEY 315 | valueFrom: 316 | secretKeyRef: 317 | name: rails-secrets 318 | key: rails_master_key 319 | ``` 320 | 321 | In order to test if everything works, you can rebuild the Docker image and deploy the new configuration: you should see the example secret \(not a real secret\) displayed on your homepage. 322 | 323 | ## Logging 324 | 325 | There are two different strategies for logging: 326 | 327 | * send the logs directly from your Rails app to a centralized logging service; 328 | * log to _stdout_ and let Docker and Kubernetes collect the logs on the node. 329 | 330 | The first option is simple, but you don't collect the Kubernetes logs and might be less efficient. In any case you can use a gem like _logstash-logger_ for this. 331 | 332 | If you want to use the second option, you can enable logging to stdout for your Rails app by settings the env variable `RAILS_LOG_TO_STDOUT` to `enabled`. 333 | 334 | Then you can see the latest logs using this command: 335 | 336 | ```text 337 | kubectl logs -l app=rails-app 338 | ``` 339 | 340 | Basically, when you run the command, the Kubernetes master node gets the latest logs from the nodes \(only for pods with label `rails-app`\) and displays them. This is useful for getting started, however logs are not persistent and you need to make them searchable. For this reason you need to send them to a centralized logging service: we can use Logz.io for example, which offers a managed ELK stack. In order to send the logs from Kubernetes to ELK we use Fluentd, which is a log collector written in Ruby and a CNCF graduated project. 341 | 342 | This is how logging works: 343 | 344 | 1. your Rails application and other Kubernetes components write the logs to stdout; 345 | 2. Kubernetes collects and store the logs on the nodes; 346 | 3. you use a Kubernetes DaemonSet to run a Fluentd pod on each node; 347 | 4. Fluentd reads the logs from the node and sends them to the centralized logging service; 348 | 5. you can use the logging service to read, visualize and search all the logs. 349 | 350 | You can install Fluentd on your cluster with these simple commands: 351 | 352 | ```text 353 | kubectl create secret generic logzio-secrets --from-literal=logzio_token='MY_LOGZIO_TOKEN' --from-literal=logzio_url='MY_LOGZIO_URL' -n kube-system 354 | 355 | kubectl apply -f https://raw.githubusercontent.com/collimarco/logzio-k8s/use_k8s_secrets/logzio-daemonset-rbc.yaml 356 | ``` 357 | 358 | If you need custom configurations, you can download the file and edit it before running `kubectl apply`. Note that if you use services different from Logz.io the strategy is very similar and you can find many configuration examples on the Github repository _fluent/fluentd-kubernetes-daemonset_. 359 | 360 | You can verify if everything works by visiting your website and then checking the logs. 361 | 362 | ## Background jobs 363 | 364 | Let's see how to run Sidekiq on Kubernetes, in order to have some background workers. 365 | 366 | First of all you need to add Sidekiq to your Rails application: 367 | 368 | _Gemfile_ 369 | 370 | Then run `bundle install` and create an example worker: 371 | 372 | _app/jobs/hard\_worker.rb_ 373 | 374 | Finally add the following line to your `PagesController#home` method \(or anywhere else\) to create a background job every time a request is made: 375 | 376 | ```ruby 377 | HardWorker.perform_async 378 | ``` 379 | 380 | Now the interesting part: we need to add a new deployment to Kubernetes for running Sidekiq. The deployment is very similar to what we have already done for the web application: however, instead of running Puma as the main process of the container, we want to run Sidekiq. Here's the configuration: 381 | 382 | _config/kube/sidekiq.yml_ 383 | 384 | Basically we define a new deployment with two pods: each pod runs our standard image that contains the Rails application. The most interesting part is that we set a `command` which overrides the default command defined in the Docker image. You can also pass some arguments to Sidekiq using an `args` key. 385 | 386 | Also note that we define a `REDIS_URL` variable, so that Sidekiq and Rails can connect to Redis to get and process the jobs. You should also add the same env variable to your web deployment, so that your Rails application can connect to Redis and schedule the jobs. For Redis itself you can use Kubernetes _StatefulSets_, you can install it on a custom server or use a managed solution: although it is easy to manage a single instance of Redis, scaling a Redis cluster is not straightforward and if you need scalability and reliability probably you should consider a managed solution. 387 | 388 | As always, you can apply the new configuration to Kubernetes with `kubectl apply -f config/kube`. 389 | 390 | Finally you can try to visit your website and make sure that everything works: when you load your homepage, the example job is scheduled and you should see _It works!_ in your logs. 391 | 392 | ## Cron jobs 393 | 394 | There are different strategies to create a cron job when you deploy to Kubernetes: 395 | 396 | * use Kubernetes built-in cron jobs to run a container periodically; 397 | * use some Ruby background processes to schedule and perform the jobs. 398 | 399 | A problem with the first approach is that you have to define a Kubernetes config file for each cron job. If you want to use this solution you can use _Kubernetes CronJobs_ in combination with _rake tasks_ or _rails runner_. 400 | 401 | If you use the second method, you can schedule the cron jobs easily using Ruby. Basically you need a Ruby process that is always running in background and takes care to create the jobs when the current time matches a cron pattern. For example you can install the _rufus-scheduler_ gem and then run a dedicated container: however in this case you have a single point of failure and if the pod is rescheduled a job may be lost. In order to have a more distributed and relaible environment, we can use a gem like _sidekiq-cron_: it runs a scheduler thread on each sidekiq server process and it uses Redis in order to make sure that the same job is not scheduled multiple times. For example, if you have N sidekiq replicas, then there are N processes that check the schedule every minute and if the current time matches a cron line, then they try to get a Redis lock: if a thread manages to get the lock, it means that it is responsible for scheduling the Sidekiq jobs for that time, otherwise it simply does nothing. Finally the Sidekiq jobs are executed normally, as the other background jobs, and thus can easily scale horizontally on the existing pods and get a reliable processing with retries. 402 | 403 | Let's add this gem to the Rails application: 404 | 405 | _Gemfile_ 406 | 407 | Then run `bundle install` and create an initializer: 408 | 409 | _config/initializers/sidekiq.rb_ 410 | 411 | Finally define a schedule: 412 | 413 | _config/schedule.yml_ 414 | 415 | Then when you start Sidekiq you will see that the worker is executed once every minute, regardless of the number of pods running. 416 | 417 | ## Console 418 | 419 | You can connect to a pod by running this command: 420 | 421 | ```text 422 | kubectl exec -it my-pod-name bash 423 | ``` 424 | 425 | Basically we start the bash process inside the container and we attach our interactive input to it using the `-it` options. 426 | 427 | If you need a list of the pod names you can use `kubectl get pods`. 428 | 429 | Altough you can connect to any pod, I find it useful to create a single pod named `terminal` for maintenance tasks. Create the following file and then run `kubectl apply -f kube/config`: 430 | 431 | ```yaml 432 | apiVersion: v1 433 | kind: Pod 434 | metadata: 435 | name: terminal 436 | spec: 437 | containers: 438 | - name: terminal 439 | image: username/kubernetes-rails-example:latest 440 | command: ['sleep'] 441 | args: ['infinity'] 442 | env: 443 | - name: EXAMPLE 444 | value: This env variable is defined by Kubernetes. 445 | ``` 446 | 447 | All containers must have a main running process, otherwise they exit and Kubernetes considers that as a crash. Running the default command for the image, the Rails server, would be a waste of resources, since the pod is not connected to the load balancer: instead we use `sleep infinity`, which is basically a no-op that consumes less resources and keeps the container running. 448 | 449 | Once you are connected to the bash console of a pod you can easily run any command. If you want to run only a single command, you can also start it directly. For example, if you want to start the _Rails console_ inside a pod named `terminal`, you can run this command: 450 | 451 | ```text 452 | kubectl exec -it terminal rails console 453 | ``` 454 | 455 | If you need to pass additional arguments to the process you can use `--` to separate the Kubernetes arguments from the command arguments. For example: 456 | 457 | ```text 458 | kubectl exec -it terminal -- rails console -e production 459 | ``` 460 | 461 | ## Rake tasks 462 | 463 | There are different ways to run a rake task on Kubernetes: 464 | 465 | * you can create a Kubernetes Job to run the rake task in a dedicated container; 466 | * you can connect to an existing pod and run the rake task. 467 | 468 | For simplicity I prefer the second alternative. 469 | 470 | Run the following command to list all the pods available: 471 | 472 | ```text 473 | kubectl get pods 474 | ``` 475 | 476 | Then you can run a task with this command: 477 | 478 | ```text 479 | kubectl exec my-pod-name rake task-name 480 | ``` 481 | 482 | Note that `kubectl exec` returns the status code of the command executed \(i.e. `0` if the rake task is executed successfully\). 483 | 484 | ## Database migrations 485 | 486 | Migrating the database without downtime when you deploy a new version of your application is not a simple task. The origin of most problems is that both deploying the new code to all pods and running the database migration are long tasks that take some time to be completed. Basically they are not instant and atomic operations, and during that time you have at least one of the following situations: 487 | 488 | * old code is running with the new database schema; 489 | * new code is running with the old database schema. 490 | 491 | Let's analyse in more detail some strategies: 492 | 493 | * **Downtime**: If you could afford some downtime during migrations, than you would simply scale down your replicas to zero, run the migrations with a Kubernetes Job and then scale up your application again. **Pros**: simple, with no special requirements in your application code; no runtime errors during deployment due to different schemas. **Cons**: some minutes of downtime. 494 | * **Deploy new code, then migrate**: You deploy the new code, updating the images on all pods, and then, when everything is finished, you run the migration. At first this seems to works perfectly if you can make your new code support the old schema \(which is not always easy\). However when the new database schema is applied, you still have to deal with ActiveRecord caching the old database schema in the Ruby process \(thus making an additional restart required\). If you choose this trategy, you can deploy your new code and then simply connect to one of the pods and run `rake db:migrate`. **Pros:** zero downtime; deployment is very simple. **Cons**: it is very difficult to make code backward compatible; you probably need an additional restart after the migration. 495 | * **Migrate, then deploy new code**: This is the most common approach and it is used by Capistrano, Heroku and other CI/CD tools. The problem is that rolling out an update to many pods takes time and during that period you have the old code running with the new database schema. In order to avoid transient errors, you need to make the new schema backward compatible, so that it can run with both the old code and the new code: however it is not alwasy easy to write _zero downtime migrations_ and there are many pitfalls. Also, in order to avoid additional problems, you should use a different Docker tag for each image \(and not just the tag `latest`\), otherwise an automatic reschedule may fetch the new image before the migration is complete. If you choose this strategy, you need to use a _Kubernetes Job_ to deploy a single pod with the new image and run the migration and then, if the migration succeeds, update the image on all pods. **Pros**: common and reliable strategy. **Cons**: if you don't write backward compatible migrations, some errors may occur while the new code is being rolled out; you need to use different Docker tags for each image version if you want to prevent accidental situations where the new code runs before the migration. 496 | 497 | If we choose the latest solution, we must define a job like the following: 498 | 499 | _config/kube/migrate.yml_ 500 | 501 | Then you can run the migration using this command: 502 | 503 | ```text 504 | kubectl apply -f config/kube/migrate.yml 505 | ``` 506 | 507 | Then you can see the status of the migration: 508 | 509 | ```text 510 | kubectl describe job migrate 511 | ``` 512 | 513 | The above command also displays the name of the pod where the migration took place. You can then see the logs: 514 | 515 | ```text 516 | kubectl logs pod-name 517 | ``` 518 | 519 | When the job is completed you can delete it, so that you free the resources and you can run it again in the future: 520 | 521 | ```text 522 | kubectl delete job migrate 523 | ``` 524 | 525 | ## Continuous delivery 526 | 527 | In the previous sections we have configured the Kubernetes cluster and deployed the code manually. However it would be useful to have a simple command to deploy new versions of your app whenever you want. 528 | 529 | Create the following file and make it executable \(using `chmod +x deploy.sh`\): 530 | 531 | _deploy.sh_ 532 | 533 | Then you can easiliy release a new version with this command: 534 | 535 | ```text 536 | ./deploy.sh 537 | ``` 538 | 539 | The above command executes the following steps: 540 | 541 | 1. use sh as the interpreter and set options to print each command and exit on failure; 542 | 2. build and publish the docker image; 543 | 3. run the migrations and then wait the completion of the job and delete it; 544 | 4. finally release the new code / image. 545 | 546 | Also remember that if you change the Kubernetes configuration you need to run this command: 547 | 548 | ```text 549 | kubectl apply -f kube/config 550 | ``` 551 | 552 | ## Monitoring 553 | 554 | You need to monitor the Kubernetes cluster for various reasons, for example: 555 | 556 | * understand the resource usage and scale the cluster accordingly; 557 | * check if there are anomalies in the usage of resources, like pods that are using too many resources; 558 | * check if all the pods are running properly or if there are some failures. 559 | 560 | Usually the Kubernetes provider already offers a _dashboard_ with many useful stats, like CPU usage, load average, memory usage, disk usage and bandwidth usage across all the nodes. Usually they collect the stats using a _DaemonSet_, in a way similar to what we have previously described for logging. If you prefer, you can also install custom monitoring agents on all nodes: you can use open source products like Prometheus or services like Datadog. 561 | 562 | Other ways to monitor your application performance are: 563 | 564 | * installing the Kubernetes _metrics-server_ that stores the stats in memory and allows you to use commands like `kubectl top nodes/pods`; 565 | * using stats from the load balancer; 566 | * collecting synthetic metrics generated by ad-hoc requests sent from an external service to your application, for example in order to measure the response time from an external point of view; 567 | * collecting stats directly from your Rails application using a gem for _application performance monitoring_, like Datadog APM or New Relic APM. 568 | 569 | ## Security updates 570 | 571 | There is a misconception that you can forget about security updates when you use containers. That is not true. Even if Docker and containers add an additional layer of isolation, in particular from the host and from other containers, and they are also ephemeral, which is good for security, they still need to be updated in order to avoid application exploits. Note that an attack at the application layer it is also possible when there is a security bug at a lower layer, for example in the OS or inside libraries included in the base image. 572 | 573 | If you run Rails on Kubernetes remeber to apply updates to the following layers: 574 | 575 | * **Kubernetes and nodes**: most Kubernetes providers will apply the updates for you to the underlying nodes and to Kubernetes, so that you can forget about this layer. However you may need to enable an option for automatic updates: for example, if you use DigitalOcean, remember to go the Kubernetes settings from the dashboard and enable the automatic updates option. 576 | * **Docker and containers**: you need to keep your containers updated. In particular make sure that you are using an updated version of the base image. If you use Ruby as the base image, use a tag like `2.5` instead of `2.5.1`, so that you don't forget to increase the patch version when there is a new patch available. However that is not enough: when a new OS patch is available, the Ruby maintainers release a new version of the image, with the same tag \(for example the image with tag `2.5` is not always the same\). This means that you should ckeck Docker Hub frequently to see if the base image has received some updates \(or subscribe to the official security mailing lists for Ruby, Ubuntu, etc.\): if there are new updates, build your image again and deploy. 577 | * **Rails application and dependencies**: remember to update the versions of Ruby, Rails, Gems and Yarn packages used by your application, and any other dependencies. 578 | * **Other**: you also need to update the database and other services outside Kubernetes. Usually it is useful to use managed databases so that your provider applies the security patches automatically and you can forget about this layer. 579 | 580 | Basically, if you use managed services \(for Kubernetes and database\) and you deploy your application frequently, you don't need to do anything special: just keep your Rails app updated. However, if you don't release your application frequently, remember to rebuild the image and don't run your application for months on an outdated base image. 581 | 582 | ## Conclusion 583 | 584 | We have covered all the aspects required for deploying a Ruby on Rails application in production using Kubernetes. 585 | 586 | Scaling the application or updating the configuration across hundreds of nodes is now a simple operation that can be managed by a single DevOp. Thanks to the widespread support for Kubernetes you also get a better pricing and portability, compared to PaaS solutions like Heroku. 587 | 588 | Remember that in order to achieve availability and world-scale scalability you need to avoid bottlenecks and single points of failure, in particular: 589 | 590 | * **the load balancer**, when it is a simple server, may become a bottleneck; you can use better hardware if available, but finally you will have to use _Round-Robin DNS_ to increase capacity, by distributing the clients over different load balancers and deployments; if you use a global network like CloudFlare, they can even perform health checks on your load balancers, protect them from DDoS attacks and cache most requests; 591 | * **the database** hosted on a single server may become a bottleneck; you can use better hardware and _hot standby_ servers, but finally you may have to move to a DBMS that supports _sharding_, meaning that the data is distributed automatically across different database instances, each one managing a range of keys; the database clients \(e.g. inside your Rails app\) first query a server in the database cluster to understand the current cluster configuration and then query the correct database instances directly, thus avoiding any kind of bottleneck; moreover each _shard_ is usually replicated in order to preserve data in case of hardware failures, and thus it is called a _sharded replica_; strategies similar to what we have described are provided for example by _MongoDB_ and _Redis Cluster_ and there are many managed solutions available on the market. 592 | 593 | -------------------------------------------------------------------------------- /devops/kubernetes/terminology.md: -------------------------------------------------------------------------------- 1 | # Terminology 2 | 3 | _Mostly taken from the_ [_Kubernetes glossary_](https://kubernetes.io/docs/reference/glossary/?fundamental=true) _with added changes to help me understand better_ 4 | 5 | * **Cluster** - A set of machines, called **nodes**, that run containerized applications managed by Kubernetes. A cluster has at least one worker node and at least one master node. 6 | * **Container** - A lightweight and portable executable image that contains software and all of its dependencies. 7 | * **Container Runtime** - The container runtime is the software that is responsible for running **containers**. 8 | * **Container runtime interface \(CRI\)** - The container runtime interface \(CRI\) is an API for container runtimes to integrate with **kubelet** on a **node**. 9 | * **Control Plane** - The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of **containers**. 10 | * **Controller** - In Kubernetes, controllers are control loops that watch the state of your **cluster**, then make or request changes where needed. Each **controller** tries to move the current cluster state closer to the desired state. 11 | * **DaemonSet** - Ensures a copy of a **Pod** is running across a set of **nodes** in a **cluster**. 12 | * **Deployment** - An API object that manages a replicated application. 13 | * **Ephemeral Container** - A **Container** type that you can temporarily run inside a **Pod**. 14 | * **Image** - Stored instance of a **container** that holds a set of software needed to run an application. 15 | * **Init Container** - One or more initialization containers that must run to completion before any app containers run. 16 | * **Job** - A finite or batch task that runs to completion. 17 | * **kube-controller-manager** Component on the master that runs **controllers**. 18 | * **kube-proxy** - [kube-proxy](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/) is a network proxy that runs on **each node** in **your cluster**, implementing part of the Kubernetes [Service](https://kubernetes.io/docs/concepts/services-networking/service/) concept. 19 | * **Kubectl** - A command line tool for communicating with a [Kubernetes API](https://kubernetes.io/docs/concepts/overview/kubernetes-api/) server. 20 | * **Kubelet** An agent that runs on **each node** in **the cluster**. It makes sure that **containers** are running in a **pod**. **Each node must have a Kubelet**. 21 | * **Kubernetes API** - The application that serves Kubernetes functionality through a RESTful interface and stores the state of the cluster. 22 | * **Label** - Tags objects with identifying attributes that are meaningful and relevant to users \(e.g. `"environment" : "production"`\). 23 | * **Namespace** - An abstraction used by Kubernetes to support **multiple virtual clusters on the same physical** [**cluster**](https://kubernetes.io/docs/reference/glossary/?all=true#term-cluster). 24 | * **Node** - A node is a worker machine in Kubernetes. A node has **Pods** running inside it. 25 | * **NodePort** - A service type used to expose the Service on each Node’s IP at a static port \(the `NodePort`\). A `ClusterIP` Service, to which the `NodePort` Service routes, is automatically created. You’ll be able to contact the `NodePort` Service, from outside the cluster, by requesting `:`. 26 | * **Pod** - The smallest and simplest Kubernetes object. A Pod represents a set of running [containers](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/#why-containers) on your cluster. An example of a pod is a Rails app backend, it can scale up/down horizontally through **ReplicaSets** which replicates pods. 27 | * **ReplicaSet** - A ReplicaSet \(aims to\) maintain a set of replica Pods running at any given time. 28 | * **Pod Lifecycle** - A high-level summary of what phase the **Pod** is in within its lifecyle. 29 | * **Pod Security Policy** - Enables fine-grained authorization of **Pod** creation and updates. 30 | * [**Selector**](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) - Allows users to filter a list of resources based on labels. Examples: 31 | * `environment = production` 32 | * `tier != frontend` 33 | * `environment in (production, qa)` 34 | * `tier notin (frontend, backend)` 35 | * **Service** - An abstract way to expose an application running on a set of [Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/) as a network service. 36 | * **Service Account** - Provides an identity for processes that run in a [Pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). 37 | * **StatefulSet** - Manages the deployment and scaling of a set of [Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/), _and provides guarantees about the ordering and uniqueness_ of these Pods. 38 | * **Static Pod** - A [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/) managed directly by the **kubelet daemon** on a specific node. 39 | * **Volume** - A directory containing data, accessible to the containers in a [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). 40 | 41 | -------------------------------------------------------------------------------- /devops/kubernetes/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | * Describe the deployment, `kubectl describe deployment bad_deployment`. 4 | * Decribe a pod, `kubectl describe pod bad_pod`. 5 | * Get the logs for a pod `kubectl logs pod_name`. 6 | * Exec into the pod, `kubectl exec -it pod_name /bin/bash` \(If you have multiple containers in the pod use `-c container_name` to select the desired container\) 7 | 8 | -------------------------------------------------------------------------------- /devops/kubernetes/upgrades.md: -------------------------------------------------------------------------------- 1 | # Upgrades 2 | 3 | We can upgrade by using `kubectl set image deployment/deployment_name helloworld=obahareth/new_hello_world`. 4 | 5 | When we redeploy with a new image we get a new replicaset that matches the new set of images. 6 | 7 | ## Rollouts 8 | 9 | We can view the rollout history by running `kubectl rollout history deployment/deployment_name`, we can use the revision numbers here to roll back to a specific version as well. 10 | 11 | ### Undoing 12 | 13 | `kubectl rollout undo deployment/deployment_name` 14 | 15 | This will roll back to the previous version 16 | 17 | ### Rolling Back to a Specific Version 18 | 19 | `kubectl rollout undo deployment/deployment_name --to-revision=3` 20 | 21 | This will roll back to revision 3. 22 | 23 | -------------------------------------------------------------------------------- /documentation.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | **Links** 4 | 5 | * [How to Write Good Documentation \(And Its Essential Elements\)](https://www.sohamkamani.com/blog/how-to-write-good-documentation/). 6 | 7 | -------------------------------------------------------------------------------- /education/README.md: -------------------------------------------------------------------------------- 1 | # Education 2 | 3 | I share links to courses, books, and in general "learning paths" for multiple topics here. 4 | 5 | ## Links 6 | 7 | * [1,300 Free Online Courses from Top Universities](http://www.openculture.com/freeonlinecourses). 8 | 9 | -------------------------------------------------------------------------------- /education/design/README.md: -------------------------------------------------------------------------------- 1 | # Design 2 | 3 | -------------------------------------------------------------------------------- /education/design/courses-and-books.md: -------------------------------------------------------------------------------- 1 | # Courses and Books 2 | 3 | ## Refactoring UI 4 | 5 | [Refactoring UI](https://refactoringui.com/) is everything you need to start producing better designs today. 6 | 7 | > Learn how to design beautiful user interfaces by yourself using specific tactics explained from a developer's point-of-view. 8 | 9 | -------------------------------------------------------------------------------- /education/frontend-development.md: -------------------------------------------------------------------------------- 1 | # Frontend Development 2 | 3 | ## Links 4 | 5 | * [Team Treehouse Frontend Web Development Track](https://teamtreehouse.com/tracks/front-end-web-development) 6 | * [FreeCodeCamp Courses](https://www.freecodecamp.org/learn) 7 | * Responsive Web Design 8 | * JavaScript Algorithms and Data Structures 9 | * Front End Libraries 10 | 11 | -------------------------------------------------------------------------------- /education/programming-and-computer-science/README.md: -------------------------------------------------------------------------------- 1 | # Programming & Computer Science 2 | 3 | -------------------------------------------------------------------------------- /education/programming-and-computer-science/courses.md: -------------------------------------------------------------------------------- 1 | # Courses 2 | 3 | ## Computer Science 4 | 5 | ### Specific Courses 6 | 7 | #### [Computer Science Crash Course](https://www.youtube.com/watch?v=tpIctyqH29Q&list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo) 8 | 9 | {% embed url="https://www.youtube.com/watch?v=tpIctyqH29Q&list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo" caption="" %} 10 | 11 | #### [CS50 By Harvard University](https://www.youtube.com/channel/UCcabW7890RKJzL968QWEykA) 12 | 13 | {% embed url="https://www.youtube.com/channel/UCcabW7890RKJzL968QWEykA" caption="" %} 14 | 15 | #### [Introduction to Computer Science by MIT](https://www.youtube.com/watch?v=nykOeWgQcHM&list=PLUl4u3cNGP63WbdFxL8giv4yhgdMGaZNA) 16 | 17 | {% embed url="https://www.youtube.com/watch?v=nykOeWgQcHM&list=PLUl4u3cNGP63WbdFxL8giv4yhgdMGaZNA" caption="" %} 18 | 19 | ## Programming 20 | 21 | ### Specific Courses 22 | 23 | * [Udacity - School of Programming](https://www.udacity.com/school-of-programming) 24 | 25 | ## General Course Websites 26 | 27 | * [CloudAcademy](https://cloudacademy.com) - Cloud computing and certifications. 28 | * [Codecademy](https://www.codecademy.com/) - Interactive way to learn programming. 29 | * [Coursera](http://coursera.com/) - General courses website, has degree-granting paths. 30 | * [edX](https://www.edx.org/) - General courses website. 31 | * [O'Reilly](https://oreilly.com) - Good courses and amazing books. 32 | * [PluralSight](https://pluralsight.com) - Video courses for beginners and practitioners. 33 | * [Team Treehouse](https://teamtreehouse.com/) - Courses website with a great community and great articles. 34 | * [Udacity](https://udacity.com) - General courses website, grants nanodegrees. 35 | * [Udemy](https://udemy.com) - General courses website. 36 | 37 | ## Credits 38 | 39 | Resources are compiled from various users in these Twitter threads: 40 | 41 | * [E7san](https://twitter.com/E7san/status/1164760773857431553) 42 | * [sultan\_7raag](https://twitter.com/sultan_7raag/status/1164973226092564482) 43 | 44 | -------------------------------------------------------------------------------- /engineering-management/README.md: -------------------------------------------------------------------------------- 1 | # Engineering Management 2 | 3 | -------------------------------------------------------------------------------- /engineering-management/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Learn what to expect and strive for as a developer transitioning into 4 | Engineering Management. 5 | --- 6 | 7 | # Overview 8 | 9 | Based on [a post on my blog](https://omar.engineer/engineering-management-an-overview/). 10 | 11 | I was an engineer for most of my career and one day I became a manager and I was quite lost and afraid in the beginning, I realized I hadn't shared my experiences from back then. I've been doing engineering management on and off for the past couple of years and I decided to share a short summary of what I learned. 12 | 13 | A lot of this is stuff I learned from books, articles, websites, and some of this is stuff I learned on the job. Full credit to all the resources I learned from is at the bottom in the "Great resources" section, and I heavily recommend exploring them if this article captured your interest. I like to use the term "Maker" \(engineer, designer, or anyone who makes stuff\) and "Manager", both of which I learned from the book Leading Snowflakes. I wrote this from the perspective of someone who has been a Maker for most of his career and transitioned to Management a couple of years ago. 14 | 15 | ## What to expect 16 | 17 | ### You need to write, a lot 18 | 19 | Meeting notes, peer feedback, feedback to you, documenting a task before you hand it to an engineer, and so on. Think of yourself as the standard for documentation in your organization or team, because you kind of represent that now. You'll get so much in your plate that it's impossible to remember it all, writing is your best friend. 20 | 21 | ### You'll talk to people and be in meetings a lot more 22 | 23 | Management is all about people interactions, you'll be dealing with people a lot more than before and that means meetings. Too many meetings for your team is a productivity killer and that's also something you'll need to figure out how to cut down if it becomes an issue. 24 | 25 | ### Learn to measure your success by your team's success, not what you make yourself. 26 | 27 | When I started being a leader I was used to measuring myself as an engineer or as a "maker" \(measuring by what I make\). When I first started being a manager I used to feel like I haven't accomplished anything in my day and this was difficult. 28 | 29 | ### You'll be exposed to a lot more conflicts 30 | 31 | You'll see a lot of conflicts between people, sometimes over very small issues. A lot of your time will go towards handling them. This may not be the case for every manager but it was the hardest part of the job for me. 32 | 33 | ### Hard Choices 34 | 35 | You're gonna have to let some people go, you're gonna have to step in to break up conflicts, and sometimes you'll have people who are trying their best but still hurting teammates. This isn't an easy path and it's full of people issues and conflicts. Even if you have a great hiring process, it won't be perfect and you'll hire the wrong person sometimes. There's no right or wrong answer in almost any situation, you need to have peers and mentors you can trust and ask for guidance. Don't make hard decisions alone, and definitely don't make them when you're not calm. 36 | 37 | ### You'll need to do things that many people don't want or aren't willing to do 38 | 39 | Improving code standards, bug report structures, doing some things manually until they're automated, improving communication between your team and other departments, and so on. Your goal is to keep the team focused and removing obstacles from their way, and those obstacles are often easy/boring tasks that no one wants to do. 40 | 41 | ## What to strive to do 42 | 43 | ### 1:1 meetings 44 | 45 | Regularly sit down with your team mates, connect with them, understand their goals and what they want to achieve and learn, understand what's troubling them. Put this on a schedule, it's extremely important to do this regularly. Write down the main points that go on in your 1:1 meetings, it's important for everything you need to do on this job. 46 | 47 | ### Mentorship 48 | 49 | You need to help your teammates get better, sometimes in what they want to get better at, and sometimes in things you believe they need to learn for the sake of their team. This can be accomplished by pairing them with someone more experienced in an area they want to get better at, getting them access to websites like PluralSight, etc. Sometimes by mentoring them yourself. You have to give them goals, ask them to experiment with new things, help them write articles, give talks, and so on. 50 | 51 | ### Scheduling 52 | 53 | You'll probably be in a lot of meetings and people need an easy way to sit down and talk with you. Have an easy way for them to book some of your time, Google Calendar, [Freebusy.io](https://freebusy.io/), [Calendly](https://calendly.com/), etc. are all great tools for this. 54 | 55 | You also need to learn to switch between your Maker and Manager modes, it's good to regularly have this scheduled either some days of the week or some hours of certain days. You need time to hop on in and review some work \(pull requests, designs, etc.\) and contribute to them too. 56 | 57 | ### Keeping your "Maker" skills polished 58 | 59 | You won't have as much time for "Making" as you used to before, and you might get rusty. Take the time to keep yourself up to date with what your team is doing, and of new developments in your field. You need to be able to understand at a general level what your team does so you can help them prioritize. 60 | 61 | ### Keep a list of tasks 62 | 63 | Don't forget anything. Write things down. Anything anyone asks of you, jot it down on some app and slap a due date on it \(I use [Todoist](https://todoist.com)\). This list is also great for delegating. Got a complex task coming up that you'd like a teammate to have experience in? Delegate it. Got a lot of meetings today and your teammate asked for access to something or to try out a new tool, write down the task, don't forget them. 64 | 65 | ### Hiring 66 | 67 | The first thing you need to look at when hiring is whether these candidates will fit in with your team or not. Sit down with your teammates and peers and decide what's a must-have and what's a nice-to-have for your workplace. Do you care about about writing well in your organization? Are you ok with people learning it on the job? Or is it a must-have to even join? 68 | 69 | Avoid brain teaser interview questions, avoid theoretical scenarios and whiteboard questions that people will never have to do on the job, and make sure your hiring process involves the most real scenarios as possible. Get the candidate to work with your team on an actual task, and compensate them for it. [Microsoft's new process](https://blog.usejournal.com/rethinking-how-we-interview-in-microsofts-developer-division-8f404cfd075a) is my favorite way to hire, I highly recommend reading it. Not all organizations have the resources to do all this stuff and that's understandable but try your hardest to accomplish these two things when hiring: 70 | 71 | 1. Get the candidate to do some real work. 72 | 2. Have your teammates and the candidate interact when doing real work. 73 | 74 | #### Hire juniors 75 | 76 | Too often organizations only look for people who already know most of what they need and don't hire enough juniors. Juniors are great to have in any organization because they want to learn and there's a lot of them. A lot of the time after juniors grow and gain more skills within your organization, they'll start to get better offers from other places so some think this isn't a good investment, but I believe this is something organizations must try their hardest to do, especially in developing countries, because those juniors need to grow and they need help and training, and because you'll have more manpower to deal with the many small bugs that are often overlooked. 77 | 78 | ### Let your team grow / delegate 79 | 80 | As a manager, you need to delegate. Jumping into Maker mode to get something done is something you were probably used to before but you now need to let your team be responsible for most of the "Making". 81 | 82 | Learning by doing is the best way to learn. If there's an area you're an expert in as a Maker, don't immediately jump in to Maker mode and try to do it, let your teammates experience it and grow. Write them a short guide of what needs to be done and things to look out for and trust them to get it done. 83 | 84 | ### Encourage knowledge sharing 85 | 86 | Ensure your teammates have an accessible place to find and share lessons learned, no matter how small they are \(Something like [StackOverflow for teams](https://stackoverflow.com/teams), etc.\). Ensure that nobody on your team is afraid or embarrassed to ask questions, regularly encourage your team to ask anything they can think of, and make sure your team is composed of people who are ok with that. 87 | 88 | ### Always be open for feedback and change 89 | 90 | I like to have a GitHub repo in my organization for everything related to how I do management, how 1:1 meetings are run, what I strive to do as a manager, what teammates can expect from me, what I expect from them, and so on. I put it in a GitHub repo because engineers are generally used to working with GitHub and are used to changing things with pull requests, so I wanted to be like that. Make a pull request to change how your manager does something 😛 91 | 92 | ### Get your team to be able to function without you 93 | 94 | This isn't to say that you're supposed to be useless or make yourself obsolete but that you should not be a blocker for your team. Imagine yourself going on a vacation for a month, what would go wrong? What tasks are you a blocker for? Will the person leading in your stead know what to do? Have you left them the necessary information? Does the team know what to work on? Do they know what to do or who to talk to if some disaster happens? Try going on short vacations every once in a while and see what goes wrong. At the beginning you'll most likely find that a lot of the things you handled as a "Maker" aren't being done anymore and you need to both make the team aware of them and delegate them. 95 | 96 | ## Great resources 97 | 98 | ### Books 99 | 100 | [Leading Snowflakes](https://leadingsnowflakes.com/) - Full of practical advice on day-to-day things you need to do as a manger. 101 | 102 | [The Manager's Path](https://www.amazon.com/dp/B06XP3GJ7F/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) - A guide for tech managers going through increasing levels of management complexity. 103 | 104 | [High Output Management](https://www.amazon.com/dp/B015VACHOK/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) - Great book on running and scaling a company. 105 | 106 | ### Websites 107 | 108 | [Manager Readme](https://managerreadme.com/) - A community of sharing your "manager guides" with other managers. 109 | 110 | [The Watercooler](https://thewatercooler.io/) - A community for leaders looking to become better. 111 | 112 | ### Articles 113 | 114 | [Rethinking how we interview in Microsoft's Developer Division](https://blog.usejournal.com/rethinking-how-we-interview-in-microsofts-developer-division-8f404cfd075a) - Great article on hiring processes. 115 | 116 | [Undervalued Software Engineering Skills: Writing Well](https://blog.pragmaticengineer.com/on-writing-well/). 117 | 118 | ### Newsletters 119 | 120 | [Software Lead Weekly](http://softwareleadweekly.com/) - A weekly email for busy people who care about people, culture and leadership. 121 | 122 | -------------------------------------------------------------------------------- /http/README.md: -------------------------------------------------------------------------------- 1 | # HTTP 2 | 3 | -------------------------------------------------------------------------------- /http/status-codes.md: -------------------------------------------------------------------------------- 1 | # Status Codes 2 | 3 | See [Mozilla's MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) for a full list, I'm just going to cover the odd cases that have bitten me in the past here: 4 | 5 | [HTTP 301](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301) \(Moved Permanently\) and [302](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302) \(Found, or a temporary redirect\) are supposed to leave the HTTP method unaltered \(based on this [RFC from 2014](https://tools.ietf.org/html/rfc7231#section-6.4.2)\), but many HTTP clients \(including curl\) do not respect that for historical reasons and change the method to a GET, as a result of that it's recommended to use [HTTP 308](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308) \(Permanent Redirect\) and [307](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307) \(Temporary Redirect\) if preserving the HTTP method is important. 6 | 7 | -------------------------------------------------------------------------------- /machine-learning/README.md: -------------------------------------------------------------------------------- 1 | # Machine Learning 2 | 3 | -------------------------------------------------------------------------------- /machine-learning/overfitting.md: -------------------------------------------------------------------------------- 1 | # Overfitting 2 | 3 | Overfitting is when a machine learning model is fitting a data set too exactly and will cause it to fail when new data is introduced to it. In this case, the model fails \(or simply has a high error rate\) to deal with anything outside of the data set it was trained on. 4 | 5 | tl;dr It's as if the model memorized the data set and knows nothing else outside of it. 6 | 7 | 8 | 9 | Possible solutions: 10 | 11 | Split the data set into one used for training, and one used for validation. If the model generalizes well, it should have similar loss metrics across the training and validation data sets. 12 | 13 | -------------------------------------------------------------------------------- /machine-learning/regression.md: -------------------------------------------------------------------------------- 1 | # Regression 2 | 3 | Loss metrics to optimize for: 4 | 5 | _Lower values indicate a better performing model._ 6 | 7 | * Mean Squared Error \(How close a regression line is to the set of points from it\). 8 | * Root Mean Squared Error \(to get back to the same units used in the examples\). 9 | 10 | -------------------------------------------------------------------------------- /machine-learning/terminology.md: -------------------------------------------------------------------------------- 1 | # Terminology 2 | 3 | * **Feature** - An input variable used to infer things or make predictions. 4 | * **Example** - One "row" \(or entry\) in a data set containing features and possibly labels. 5 | * **Label \(only for supervised learning\)** - An identifier for what an example is. If you're training a machine to detect if a picture contains a cat or not, the label would be the correct answer that you want the machine to be able to answer. 6 | 7 | -------------------------------------------------------------------------------- /my-stack.md: -------------------------------------------------------------------------------- 1 | # My Stack 2 | 3 | I currently use a 2020 13" Macbook Pro with an M1 Chip and my phone's a iPhone 12 Pro Max. 4 | 5 | I also share my [Mac setup](https://github.com/obahareth/my-mac-os), (old) [Linux setup](https://github.com/obahareth/my-linux) and my (old)[ Android setup](https://github.com/obahareth/my-android) on GitHub. 6 | 7 | The tools and languages I've used to solve problems across my career as a programmer are [available on StackShare](https://stackshare.io/obahareth/obahareth). 8 | 9 | {% embed url="https://stackshare.io/obahareth/obahareth" %} 10 | 11 | -------------------------------------------------------------------------------- /programming-languages/README.md: -------------------------------------------------------------------------------- 1 | # Programming Languages 2 | 3 | -------------------------------------------------------------------------------- /programming-languages/constructs.md: -------------------------------------------------------------------------------- 1 | # Constructs 2 | 3 | ### Links 4 | 5 | * [Flow-Charts of Programming Language Constructs](https://www.progsbase.com/blog/flow-charts-of-programming-language-constructs/) 6 | 7 | -------------------------------------------------------------------------------- /programming-languages/go/README.md: -------------------------------------------------------------------------------- 1 | # Go 2 | 3 | -------------------------------------------------------------------------------- /programming-languages/go/syntax.md: -------------------------------------------------------------------------------- 1 | # Syntax 2 | 3 | ### Entry Point 4 | 5 | You should always have a `main` function as your entry point. 6 | 7 | ```go 8 | package main 9 | 10 | func main() { 11 | } 12 | 13 | ``` 14 | 15 | ### Type Declarations 16 | 17 | Type declarations always go to the right of variable or function names, e.g. 18 | 19 | ```go 20 | var i int = 1 21 | ``` 22 | 23 | _This isn't necessary in this case as it can be inferred from the right hand side_ 24 | 25 | #### Type Inference 26 | 27 | Go has the `:=` operator which can infer the type and assign it to a variable at the same time. Using it we can write the same example as above and omit the `var` and `int`. 28 | 29 | ```go 30 | i := 5 31 | ``` 32 | 33 | ### Function Declarations 34 | 35 | Function declarations are actually quite similar \(the return type is to the right of the function name\), here's a function that just returns a string when called. 36 | 37 | ```go 38 | func returnHello() string { 39 | return "Hello" 40 | } 41 | ``` 42 | 43 | Here's the same version but this time it takes in a name as well 44 | 45 | ```go 46 | package main 47 | 48 | import "fmt" 49 | 50 | func main() { 51 | fmt.Println(returnHello("Omar")) 52 | } 53 | 54 | func returnHello(name string) string { 55 | return fmt.Sprintf("Hello %s", name) 56 | } 57 | 58 | ``` 59 | 60 | ### Conditionals 61 | 62 | Conditionals are quire straightforward in Go, they're similar to most languages but without the parentheses 63 | 64 | ```go 65 | package main 66 | 67 | import "fmt" 68 | 69 | func main() { 70 | name := "Omar" 71 | 72 | if name == "Omar" { 73 | fmt.Println("It's me") 74 | } else { 75 | fmt.Println("Hey there stranger!") 76 | } 77 | } 78 | ``` 79 | 80 | ### Loops 81 | 82 | There's only one type of loop in Go, a `for` loop. 83 | 84 | Here's a loop that prints "Hello" five times. 85 | 86 | ```go 87 | package main 88 | 89 | import "fmt" 90 | 91 | func main() { 92 | for i := 0; i < 5; i++ { 93 | fmt.Println("Hello") 94 | } 95 | } 96 | ``` 97 | 98 | Here's an infinite loop \(useful for servers, game engines, etc.\) 99 | 100 | **Warning:** You have to kill the program to end this 101 | 102 | ```go 103 | package main 104 | 105 | import "fmt" 106 | 107 | func main() { 108 | for { 109 | fmt.Println("Hello") 110 | } 111 | } 112 | ``` 113 | 114 | This form can also be used to make a finite loop when combined with the `break` keyword, this will print 0 to 4. 115 | 116 | ```go 117 | package main 118 | 119 | import "fmt" 120 | 121 | func main() { 122 | i := 0 123 | 124 | for { 125 | if i >= 5 { 126 | break 127 | } 128 | 129 | fmt.Println(i) 130 | i++ 131 | } 132 | } 133 | ``` 134 | 135 | There's also a form of the loop that you only need to provide with the condition, this will print 0 to 5. \(This is used to **stop it before the next run**\) 136 | 137 | ```go 138 | package main 139 | 140 | import "fmt" 141 | 142 | func main() { 143 | i := 0 144 | isLessThanFive := true 145 | 146 | for isLessThanFive { 147 | if i >= 5 { 148 | isLessThanFive = false 149 | } 150 | 151 | fmt.Println(i) 152 | i++ 153 | } 154 | } 155 | ``` 156 | 157 | ### Structs 158 | 159 | Structs are a useful way to encapsulate and reuse objects, and they can even have methods. They're similar in some ways to classes in other programming languages. 160 | 161 | Here's how to declare a struct \(can be done outside of `main`\) 162 | 163 | ```go 164 | package main 165 | 166 | import "fmt" 167 | 168 | // Struct declaration 169 | type Person struct { 170 | name string 171 | age int 172 | } 173 | 174 | func main() { 175 | // Struct usage 176 | omar := Person{name: "Omar", age: 27} 177 | fmt.Println(omar) 178 | } 179 | ``` 180 | 181 | You can add methods to structs by using [method receivers](https://spino.tech/blog/method-receiver-types-in-go/). 182 | 183 | ```go 184 | package main 185 | 186 | import "fmt" 187 | 188 | type Person struct { 189 | name string 190 | age int 191 | } 192 | 193 | func (p Person) description() string { 194 | return fmt.Sprintf("%s is a Person who is %d years old", p.name, p.age) 195 | } 196 | 197 | func main() { 198 | omar := Person{name: "Omar", age: 27} 199 | fmt.Println(omar.description()) 200 | } 201 | ``` 202 | 203 | This syntax was the most confusing to me whenever I saw Go code, the `(p Person)` part. This basically says that the type that can receive this method call is of type `Person` and that within that function we want to name that receiver `p`. 204 | 205 | ### Interfaces 206 | 207 | Interfaces add a bit of genericness to Go, they're quite similar to other languages except that you don't need to specifically declare that your struct implements an interface, the compiler infers it if the signature of your methods match your interface method's signature. 208 | 209 | ```go 210 | package main 211 | 212 | import "fmt" 213 | 214 | // Interface declaration 215 | type Eater interface { 216 | eat() string 217 | } 218 | 219 | type Cat struct { 220 | name string 221 | } 222 | 223 | func (c Cat) eat() string { 224 | return fmt.Sprintf("%s likes to eat cat food.", c.name) 225 | } 226 | 227 | type Dog struct { 228 | name string 229 | } 230 | 231 | func (d Dog) eat() string { 232 | return fmt.Sprintf("%s likes to eat dog food.", d.name) 233 | } 234 | 235 | func printEatResult(e Eater) { 236 | fmt.Println(e.eat()) 237 | } 238 | 239 | func main() { 240 | cat := Cat{name: "Felix"} 241 | dog := Dog{name: "Spark"} 242 | 243 | printEatResult(cat) 244 | printEatResult(dog) 245 | } 246 | ``` 247 | 248 | This slightly lengthy example allowed us treat both `Cat` and `Dog` as `Eater`s in the `printEatResult` function. Notice how we didn't have to do anything to explicitly say that Cats and Dogs implement the Eater interface, the compiler just figured it out because the signature of the `eat` function on each of those structs matched the `Eater` 's version of it. 249 | 250 | _It's a convention to name interfaces that have only one method \(e.g. `eat`\) to end with the name of that method plus `er`, so `eater`._ 251 | 252 | ### Arrays and Slices 253 | 254 | #### Arrays 255 | 256 | It's quite simple to declare and use an array \(_the size of the array goes to the left of the type_\). 257 | 258 | ```go 259 | package main 260 | 261 | func main() { 262 | var names [2]string 263 | names[0] = "Omar" 264 | names[1] = "John" 265 | fmt.Println(names) 266 | } 267 | ``` 268 | 269 | However with arrays you must always declare the size, if you want to use something with flexible size, that's what slices are for. 270 | 271 | #### Slices 272 | 273 | Slices are a type built on top of arrays to provide more convenience and flexibility, most array programming in Go is done using slices. 274 | 275 | ```go 276 | package main 277 | 278 | func main() { 279 | var names []string 280 | names = append(names, "Omar") 281 | names = append(names, "John") 282 | } 283 | ``` 284 | 285 | _In the example above, the size is omitted \(you don't need to know the size of your data when declaring a slice\)_ 286 | 287 | -------------------------------------------------------------------------------- /programming-languages/ruby/README.md: -------------------------------------------------------------------------------- 1 | # Ruby 2 | 3 | At this point I think I've used Ruby more than any other language in my life. I love how I can write clean, concise, and readable code in Ruby without having to think much about it. I really love the testing tools and community that Ruby has. Ruby has also greatly influenced two languages I really love: 4 | 5 | * [Elixir](https://elixir-lang.org/) - Functional programming language heavily inspired by Ruby and runs on the \[Erlang VM\]\([https://www.wikiwand.com/en/BEAM\_\(Erlang\_virtual\_machine](https://www.wikiwand.com/en/BEAM_%28Erlang_virtual_machine)\)\) which makes it easy to write concurrent/parallel code.. 6 | * [Crystal](https://crystal-lang.org/) - A compiled and very performant language that's statically typed \(with inference\) that's heavily inspired by Ruby syntax. A lot of the Ruby code I've written just works in Crystal. 7 | 8 | -------------------------------------------------------------------------------- /programming-languages/ruby/debugging/README.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | -------------------------------------------------------------------------------- /programming-languages/ruby/debugging/byebug/README.md: -------------------------------------------------------------------------------- 1 | # Byebug 2 | 3 | ## Byebug 4 | 5 | ## Links 6 | 7 | * [Byebug Guide](https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md) 8 | * [Ruby on Rails - Debugging with the byebug gem](https://edgeguides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-byebug-gem) 9 | 10 | -------------------------------------------------------------------------------- /programming-languages/ruby/debugging/byebug/cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Cheatsheet 2 | 3 | _Taken from_ [https://fleeblewidget.co.uk/2014/05/byebug-cheatsheet/](https://fleeblewidget.co.uk/2014/05/byebug-cheatsheet/) 4 | 5 | ## Starting Byebug 6 | 7 | If you’re running Byebug on a Rails application in development mode, you no longer need to start the server with `--debugger` – the debugger is on by default. 8 | 9 | To get going, simply type `byebug` \(or `debugger`\) into your source file at the line you’re interested in and run the program. If you’re running it on a Rails application, remember to switch to your terminal window to look at debugger output. 10 | 11 | **Note:** `byebug` invocations are just method calls, so you can make them conditional: 12 | 13 | ```ruby 14 | byebug if foo == “bar” 15 | ``` 16 | 17 | **Another Note:** As is common with debuggers, hitting ‘Enter’ on an empty line in Byebug repeats the last command. 18 | 19 | ## Stopping Again 20 | 21 | ### q\[uit\] — a.k.a. “exit” _unconditionally_ 22 | 23 | Quit. It stops the thing running. Also exits your program.Note:\*\* To quit without an ‘are you sure?’ prompt, use `quit unconditionally` \(shortened to `q!`\) 24 | 25 | ### kill 26 | 27 | _Really_ quit. This uses `kill -9`, for situations where quit just isn’t fierce enough. 28 | 29 | ## Essential Commands 30 | 31 | ### c\[ontinue\] <line\_number> 32 | 33 | Carry on running until program ends, hits a breakpoint or reaches line _line\_number_ \(if specified\). 34 | 35 | ### n\[ext\] <number> 36 | 37 | Go to next line, stepping over function calls. If _number_ specified, go forward that number of lines. 38 | 39 | ### s\[tep\] <number> 40 | 41 | Go to next line, stepping into function calls. If _number_ is specified, make that many steps. 42 | 43 | ### b\[ack\]t\[race\] — a.k.a. “w\[here\]” 44 | 45 | Display [stack trace](http://en.wikipedia.org/wiki/Stack_trace). 46 | 47 | ### h\[elp\] <command\_name> 48 | 49 | Get help. With no arguments, returns a list of all the commands Byebug accepts. When passed the name of a command, gives help on using that command. 50 | 51 | ## Breakpoints and Catchpoints 52 | 53 | ### b\[reak\] 54 | 55 | Sets a [breakpoint](http://en.wikipedia.org/wiki/Breakpoint) at the current line. These can be conditional: `break if foo != bar`. Keep reading for more ways to set breakpoints! 56 | 57 | ### b\[reak\] <filename>:<line\_number> 58 | 59 | Puts a breakpoint at _line-number_ in _filename_ \(or the current file if _filename_ is blank\). Again, can be conditional: `b myfile.rb:15 unless my_var.nil?` 60 | 61 | ### b\[reak\] <class>\(.\|\#\)<method> 62 | 63 | Puts a breakpoint at the start of the method _method_ in class _class_. Accepts an optional condition: `b MyClass#my_method if my_boolean` 64 | 65 | ### info breakpoints 66 | 67 | List all breakpoints, with status. 68 | 69 | ### cond\[ition\] <number> <expression> 70 | 71 | Add condition _expression_ to breakpoint <number<>>. If no _expression_ is given, removes any conditions from that breakpoint. 72 | 73 | ### del\[ete\] <number> 74 | 75 | Deletes breakpoint <number>. With no arguments, deletes all breakpoints. 76 | 77 | ### disable breakpoints <number> 78 | 79 | Disable \(but don’t delete\) breakpoint <number>. With no arguments, disables all breakpoints. 80 | 81 | ### cat\[ch\] exception> off 82 | 83 | Enable or \(with _off_ argument\) disable catchpoint on <exception>. 84 | 85 | ### cat\[ch\] 86 | 87 | Lists all catchpoints. 88 | 89 | ### cat\[ch\] off 90 | 91 | Deletes all catchpoints. 92 | 93 | ### sk\[ip\] 94 | 95 | Passes a caught exception back to the application, skipping the catchpoint. 96 | 97 | ## Program Stack 98 | 99 | ### b\[ack\]t\[race\] — a.k.a. “w\[here\]” 100 | 101 | Display [stack trace](http://en.wikipedia.org/wiki/Stack_trace). 102 | 103 | ### f\[rame\] <frame\_number> 104 | 105 | Moves to <frame\_number> \(frame numbers are shown by `bt`\). With no argument, shows the current frame. 106 | 107 | ### up <number> 108 | 109 | Move up <number> frames \(or 1, if no number specified\). 110 | 111 | ### down <number> 112 | 113 | Move down <number> frames \(or 1, if no number specified\). 114 | 115 | ### info args 116 | 117 | Arguments of the current frame. 118 | 119 | ### info locals 120 | 121 | Local variables in the current stack frame. 122 | 123 | ### info instance\_variables 124 | 125 | Instance variables in the current stack frame. 126 | 127 | ### info global\_variables 128 | 129 | Current global variables. 130 | 131 | ### info variables 132 | 133 | Local and instance variables of the current frame. 134 | 135 | ### m\[ethod\] <class\|module> 136 | 137 | Shows instance methods of the given class or module. 138 | 139 | ### m\[ethod\] i\[nstance\] <object> 140 | 141 | Shows methods of <object>. 142 | 143 | ### m\[ethod\] iv <object> 144 | 145 | Shows instance variables of <object>. 146 | 147 | ### v\[ar\] cl\[ass\] 148 | 149 | Shows class variables of self. 150 | 151 | ### v\[ar\] co\[nst\] <object> 152 | 153 | Shows constants of <object>. 154 | 155 | ### v\[ar\] g\[lobal\] 156 | 157 | Shows global variables \(same as `info global_variables`\). 158 | 159 | ### v\[ar\] i\[nstance\] <object> 160 | 161 | Shows instance variables of \ \(same as `method iv `\). 162 | 163 | ### v\[ar\] l\[ocal\] 164 | 165 | Shows local variables \(same as `info locals`\). 166 | 167 | ## Execution Control 168 | 169 | ### c\[ontinue\] <line\_number> 170 | 171 | Carry on running until program ends, hits a breakpoint or reaches line <line\_number> \(if specified\). 172 | 173 | ### n\[ext\] <number> 174 | 175 | Go to next line, stepping over function calls. If <number> specified, go forward that number of lines. 176 | 177 | ### s\[tep\] <number> 178 | 179 | Go to next line, stepping into function calls. If <number> is specified, make that many steps. 180 | 181 | ### fin\[ish\] <num\_frames> 182 | 183 | With no argument, run until the current frame returns. Otherwise, run until <num\_frames> have returned. 184 | 185 | ### irb 186 | 187 | Start an IRB session. This will have added commands `cont`, `n` and `step`, but these can’t take arguments \(unlike the proper byebug commands of the same name\). 188 | 189 | ### restart 190 | 191 | Restart the program. This also restarts byebug. 192 | 193 | ## Threads 194 | 195 | ### th\[read\] 196 | 197 | Show current thread. 198 | 199 | ### th\[read\] l\[ist\] 200 | 201 | List all threads. 202 | 203 | ### th\[read\] stop <number> 204 | 205 | Stop thread number <number>. 206 | 207 | ### th\[read\] resume <number> 208 | 209 | Resume thread number <number>. 210 | 211 | ### th\[read\] <number> 212 | 213 | Switch context to thread <number>. 214 | 215 | ## Display 216 | 217 | ### e\[val\] — a.k.a. “p” <expression> 218 | 219 | Evaluate <expression> and display result. By default, you can also just type the expression without any command and get the same thing \(disabled by using `set noautoeval`\). 220 | 221 | ### pp 222 | 223 | Evaluate expression and pretty-print the result. 224 | 225 | ### putl 226 | 227 | Evaluate an expression with an array result and columnize the output. 228 | 229 | ### ps 230 | 231 | Evaluate an expression with an array result, sort and columnize the output. 232 | 233 | ### disp\[lay\] <expression> 234 | 235 | Automatically display <expression> every time the program halts. With no argument, lists the current display expressions. 236 | 237 | ### info display 238 | 239 | List all current display expressions. 240 | 241 | ### undisp\[lay\] <number> 242 | 243 | Remove display expression number <number> \(as listed by `info display`\). With no argument, cancel all current display expressions. 244 | 245 | ### disable display <number> 246 | 247 | Stop displaying expression number <number>. The display expression is kept in the list, though, and can be turned back on again using `enable display`. 248 | 249 | ### enable display <number> 250 | 251 | Re-enable previously disabled display expression <number>. 252 | 253 | ## Controlling Byebug 254 | 255 | ### hist\[ory\] <num\_commands> 256 | 257 | View last <num\_commands> byebug commands \(or all, if no argument given\). 258 | 259 | ### save <file> 260 | 261 | Saves current byebug session options as a script file in <file>. 262 | 263 | ### source <file> 264 | 265 | Loads byebug options from a script file at <file>. 266 | 267 | ### set <option> 268 | 269 | Change value of byebug option <option>. 270 | 271 | ### show <option> 272 | 273 | View current value of byebug option <option>. 274 | 275 | Options are: 276 | 277 | * `autoeval` 278 | * `autoirb` 279 | * `autolist` 280 | * `autoreload` 281 | * `autosave` 282 | * `basename` 283 | * `callstyle` 284 | * `forcestep` 285 | * `fullpath` 286 | * `histfile` 287 | * `histsize` 288 | * `linetrace` 289 | * `tracing_plus` 290 | * `listsize` 291 | * `post_mortem` 292 | * `stack_on_error` 293 | * `testing` 294 | * `verbose` 295 | * `width` 296 | 297 | ## Source Files and Code 298 | 299 | ### reload 300 | 301 | Reload source code. 302 | 303 | ### info file 304 | 305 | Information about the current source file. 306 | 307 | ### info files 308 | 309 | All currently loaded files. 310 | 311 | ### info line 312 | 313 | Shows the current line number and filename. 314 | 315 | ### l\[ist\] 316 | 317 | Shows source code after the current point. Keep reading for more list options. 318 | 319 | ### l\[ist\] – 320 | 321 | Shows source code before the current point. 322 | 323 | ### l\[ist\] = 324 | 325 | Shows source code centred around the current point. 326 | 327 | ### l\[ist\] <first>-<list> 328 | 329 | Shows all source code from <first> to <last> line numbers. 330 | 331 | ### edit <file:line\_no> 332 | 333 | Edit <file>. With no arguments, edits the current file. 334 | 335 | -------------------------------------------------------------------------------- /programming-languages/ruby/lazy-enumerators.md: -------------------------------------------------------------------------------- 1 | # Lazy Enumerators 2 | 3 | ## Links 4 | 5 | * [Ruby Lazy Enumerators](https://blog.saeloun.com/2019/10/23/ruby-lazy-enumerators.html) 6 | * [Using lazy enumerators to work with large files in Ruby](https://www.honeybadger.io/blog/using-lazy-enumerators-to-work-with-large-files-in-ruby/) 7 | 8 | -------------------------------------------------------------------------------- /programming-languages/ruby/libraries.md: -------------------------------------------------------------------------------- 1 | # Libraries 2 | 3 | Libraries that help you build and scale Ruby \(and Rails\) applications. 4 | 5 | ## Printing \(in console\) 6 | 7 | * [awesome\_print](https://github.com/awesome-print/awesome_print) - Pretty print your Ruby objects with style -- in full color and with proper indentation. 8 | 9 | ## Resiliency and Failure 10 | 11 | * [Semian](https://github.com/Shopify/semian) - Resiliency toolkit for failing fast \(e.g. Circuit breaker and bulk heading\). 12 | 13 | ## Feature Flags 14 | 15 | * [rollout](https://github.com/fetlife/rollout) - Fast feature flags based on Redis. 16 | 17 | ## Hash Enhancements / Helpers 18 | 19 | * [Hashie](https://github.com/intridea/hashie) - Hashie is a collection of classes and mixins that make hashes more powerful. 20 | 21 | ## Background Jobs 22 | 23 | * [sidekiq](https://github.com/mperham/sidekiq) - Simple, efficient background processing for Ruby 24 | * [sidekiq-cron](https://github.com/ondrejbartas/sidekiq-cron) - Scheduler / Cron for Sidekiq jobs to easily make recurring scheduled jobs. 25 | * [sidekiq\_alive](https://github.com/arturictus/sidekiq_alive) - Liveness probe for Sidekiq in Kubernetes deployments. 26 | * [sidekiq-statistic](https://github.com/davydovanton/sidekiq-statistic) - Improved display of statistics for your sidekiq workers and jobs. 27 | 28 | ## Location 29 | 30 | * [geocoder](https://github.com/alexreisner/geocoder) - Complete Ruby geocoding solution. 31 | 32 | ## Phones 33 | 34 | * [phony](https://github.com/floere/phony) - E164 international phone number normalizing, splitting, formatting. . 35 | 36 | ## Money 37 | 38 | * [money](https://github.com/RubyMoney/money) - A Ruby Library for dealing with money and currency conversion. 39 | 40 | ## Linting and Formatting 41 | 42 | * [Standard](https://github.com/testdouble/standard) - Ruby style guide with linter & automatic code fixer, based on Rubocop. 43 | 44 | ## Pagination 45 | 46 | * [pagy](https://github.com/ddnexus/pagy) - The ultimate pagination ruby gem, **much** faster than most pagination gems. 47 | 48 | ## Testing 49 | 50 | * [test-prof](https://github.com/palkan/test-prof) - Ruby tests profiling toolbox \(measurments to improve test suite speed\). 51 | * [vcr](https://github.com/vcr/vcr) - Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests. 52 | * [parallel\_tests](https://github.com/grosser/parallel_tests) - Speedup Test::Unit + RSpec + Cucumber + Spinach by running parallel on multiple CPU cores. 53 | * [database\_cleaner](https://github.com/DatabaseCleaner/database_cleaner) - Strategies for cleaning databases in Ruby. Can be used to ensure a clean state for testing. 54 | * [factory\_bot](https://github.com/thoughtbot/factory_bot) - A library for setting up Ruby objects as test data. 55 | * [airborne](https://github.com/brooklynDev/airborne) - RSpec driven API testing framework. 56 | * [knapsack](https://github.com/ArturT/knapsack) - Knapsack splits tests across CI nodes and makes sure that tests will run comparable time on each node. 57 | 58 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/README.md: -------------------------------------------------------------------------------- 1 | # Ruby on Rails 2 | 3 | I've been using Ruby on Rails for 5 years+ and I really love how productive you can be in it. It's the best of Ruby and web development. 4 | 5 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/gotchas.md: -------------------------------------------------------------------------------- 1 | # Gotchas 2 | 3 | ## ActiveRecord 4 | 5 | * `find` raises an exception that if not handled, will result in controller endpoints returning 404. 6 | * `find_by!` is a variant that can be used to get the same behavior of `find` for `find_by`. 7 | 8 | ## database.yml 9 | 10 | If you try to have a generic database configuration controlled by environment variables, your database actions will run twice in development. 11 | 12 | e.g. 13 | 14 | ```yaml 15 | default: &default 16 | adapter: postgresql 17 | encoding: unicode 18 | pool: <%= ENV['DATABASE_POOL'] %> 19 | host: <%= ENV['DATABASE_HOST'] %> 20 | database: <%= ENV['DATABASE_NAME'] %> 21 | username: <%= ENV['DATABASE_USER'] %> 22 | password: <%= ENV['DATABASE_PASSWORD'] %> 23 | 24 | development: 25 | <<: *default 26 | 27 | test: 28 | <<: *default 29 | ``` 30 | 31 | Since Rails by default runs migrations for the `test` environment when you're on `development` , when it tries to run them the `RAILS_ENV` will be `development` so it will actually run all the database actions on the development database again. 32 | 33 | Instead ensure that you give specific and unique names for the development and test environments: 34 | 35 | ```yaml 36 | development: 37 | <<: *default 38 | database: my_app_development 39 | 40 | test: 41 | <<: *default 42 | database: my_app_test 43 | ``` 44 | 45 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/helpers.md: -------------------------------------------------------------------------------- 1 | # Helpers 2 | 3 | ## Readability 4 | 5 | * [annotate\_models](https://github.com/ctran/annotate_models) - Automatically generates attributes as comments at the top of files to see what attributes are in models, fixture files, specs, factories, and more. Example: 6 | 7 | ```ruby 8 | # == Schema Info 9 | # 10 | # Table name: line_items 11 | # 12 | # id :integer(11) not null, primary key 13 | # quantity :integer(11) not null 14 | # product_id :integer(11) not null 15 | # unit_price :float 16 | # order_id :integer(11) 17 | # 18 | 19 | class LineItem < ActiveRecord::Base 20 | belongs_to :product 21 | # ... 22 | ``` 23 | 24 | ## Migrations 25 | 26 | * [strong\_migrations](https://github.com/ankane/strong_migrations) - Detect potentially dangerous migrations and prevent them from running by default, along with instructions on safer ways to do what you want. 27 | * [native\_enum](https://github.com/iangreenleaf/native_enum) and [activerecord-postgres\_enum](https://github.com/bibendi/activerecord-postgres_enum) for backing Rails enums \(which are application-only\) by database enums, so people looking at the database can actually understand what all those integer values actually mean. 28 | 29 | ## View Helpers 30 | 31 | Rails already provides a ton of view helpers \(e.g. `number_to_currency`\), they're listed [here](https://guides.rubyonrails.org/action_view_overview.html#overview-of-helpers-provided-by-action-view). 32 | 33 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/libraries.md: -------------------------------------------------------------------------------- 1 | # Libraries 2 | 3 | ## Authentication 4 | 5 | * [Devise](https://github.com/plataformatec/devise) - Flexible and modular authentication solution. 6 | * [OmniAuth](https://github.com/omniauth/omniauth) - Flexible authentication solution for multi-provider auth \(e.g. Sign in with GitHub or Google\). 7 | 8 | ## Authorization 9 | 10 | * [Pundit](https://github.com/varvet/pundit) - Minimal authorization through OO design and pure Ruby classes. 11 | 12 | ## ActiveJob 13 | 14 | * [job-iteration](https://github.com/Shopify/job-iteration) - Make background jobs interruptible and resumable by design. 15 | 16 | ## Countries 17 | 18 | * [countries](https://github.com/hexorx/countries) - All sorts of useful information about every country packaged as convenient little country objects. It includes data from ISO 3166 \(countries and states/subdivisions \), ISO 4217 \(currency\), and E.164 \(phone numbers\). 19 | 20 | ## Payments 21 | 22 | * [ActiveMerchant](https://github.com/activemerchant/active_merchant) - Payment abstraction library extracted from Shopify. 23 | 24 | ## Phones 25 | 26 | * [phony\_rails](https://github.com/joost/phony_rails) - This Gem adds useful methods to your Rails app to validate, display and save phone numbers. It uses the super awesome Phony gem \([floere/phony](https://github.com/floere/phony)\). 27 | 28 | ## Event-Driven Architecture 29 | 30 | * [rails\_event\_store](https://github.com/RailsEventStore/rails_event_store) - A Ruby implementation of an Event Store based on Active Record. 31 | * [sequent](https://github.com/zilverline/sequent) - CQRS & event sourcing framework for Ruby. 32 | * [Eventide](https://eventide-project.org/) - Microservices, Autonomous Services, Service-Oriented Architecture, and Event Sourcing Toolkit for Ruby with Support for Event Store and Postgres. 33 | 34 | ## Enums 35 | 36 | * [Enumerize](https://github.com/brainspec/enumerize) - Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper/Sequel support. 37 | 38 | ## Database 39 | 40 | * [paranoia](https://github.com/rubysherpas/paranoia) - Overriding ActiveRecord `delete` and `destroy` to act as soft deletion. 41 | * [scenic](https://github.com/scenic-views/scenic) - Versioned database views for Rails. 42 | * See also ["Effectively Using Materialized Views in Ruby on Rails"](https://pganalyze.com/blog/materialized-views-ruby-rails). 43 | 44 | ## Auditing 45 | 46 | * [audited](https://github.com/collectiveidea/audited) - An ORM extension that logs all changes to your Rails models. 47 | * [paper\_trail](https://github.com/paper-trail-gem/paper_trail) - Track changes to your models, for auditing or versioning. See how a model looked at any stage in its lifecycle, revert it to any version, or restore it after it has been destroyed. 48 | 49 | ## Localization 50 | 51 | * [globalize](https://github.com/globalize/globalize) - Rails I18n de-facto standard library for ActiveRecord model/data translation. 52 | 53 | ## Forms 54 | 55 | * [simple\_form](https://github.com/plataformatec/simple_form) - Forms made easy for Rails! It's tied to a simple DSL, with no opinion on markup. 56 | 57 | ## Views 58 | 59 | * [view\_component](https://github.com/github/view_component) - A framework for building reusable, testable & encapsulated view components in Ruby on Rails. 60 | 61 | ## PDF 62 | 63 | * [wicked\_pdf](https://github.com/mileszs/wicked_pdf) - PDF generator \(from HTML\) plugin for Ruby on Rails. 64 | 65 | ## Monitoring 66 | 67 | * [Bullet](https://github.com/flyerhzm/bullet) - Helps to kill N+1 queries and unused eager loading. 68 | 69 | ## Testing 70 | 71 | * [shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers) - Simple one-liner tests for common Rails functionality. 72 | * [letter\_opener](https://github.com/ryanb/letter_opener) - Preview mail in the browser instead of sending. 73 | 74 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/relations.md: -------------------------------------------------------------------------------- 1 | # Relations 2 | 3 | ## One-to-Many 4 | 5 | ### belongs_to 6 | 7 | ### has_many 8 | 9 | 10 | 11 | ## Many-to-Many -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/routing.md: -------------------------------------------------------------------------------- 1 | # Routing 2 | 3 | ## Quick Cheatsheet 4 | 5 | _Mostly taken from_ [_devhints_](https://devhints.io/rails-routes)_._ 6 | 7 | ### Resources 8 | 9 | ```ruby 10 | resources :books 11 | 12 | # BooksController: 13 | # index => GET /books 14 | # new => GET /books/new 15 | # create => POST /books/new 16 | # show => GET /books/:id 17 | # edit => GET /books/:id/edit 18 | # update => PUT /books/:id 19 | # delete => DELETE /books/:id 20 | # 21 | # Helpers: 22 | # new_book_path 23 | # book_path(id) 24 | # edit_book_path(id) 25 | ``` 26 | 27 | ### Member and Collection 28 | 29 | `collection` is for routes on the collection. 30 | 31 | `member` is for routes on a specific member. 32 | 33 | ```ruby 34 | Rails.applications.routes.draw do 35 | resources :events do 36 | collection do 37 | post :validate # localhost:3000/events/validate 38 | end 39 | 40 | member do 41 | post :publish # localhost:3000/events/1/publish 42 | end 43 | end 44 | ``` 45 | 46 | ### Options 47 | 48 | ```ruby 49 | resources :photos, 50 | path_names: { new: 'brand_new' } # /photos/1/brand_new 51 | path: 'postings' # /postings 52 | only: :index 53 | only: [:index, :show] 54 | except: :show 55 | except: [:index, :show] 56 | 57 | shallow: true # also generate shallow routes 58 | shalow_path: 'secret' 59 | shallow_prefix: 'secret' 60 | ``` 61 | 62 | ### Single Resource 63 | 64 | ```ruby 65 | resource :coder 66 | 67 | # CodersController: 68 | # new => GET /coder/new 69 | # create => POST /coder/new 70 | # show => GET /coder 71 | # edit => GET /coder/edit 72 | # update => PUT /coder 73 | # delete => DELETE /coder 74 | ``` 75 | 76 | ### Matching 77 | 78 | ```ruby 79 | match 'photo/:id' => 'photos#show' # /photo/what-is-it 80 | match 'photo/:id', id: /[0-9]+/ # /photo/0192 81 | match 'photo/:id' => 'photos#show', constraints: { id: /[0-9]+/ } 82 | match 'photo/:id', via: :get 83 | match 'photo/:id', via: [:get, :post] 84 | 85 | match 'photo/*path' => 'photos#unknown' # /photo/what/ever 86 | 87 | # params[:format] == 'jpg' 88 | match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } 89 | ``` 90 | 91 | ### Redirect 92 | 93 | ```ruby 94 | match '/stories' => redirect('/posts') 95 | match '/stories/:name' => redirect('/posts/%{name}') 96 | ``` 97 | 98 | ### Named Routes 99 | 100 | ```ruby 101 | # logout_path 102 | match 'exit' => 'sessions#destroy', as: :logout 103 | ``` 104 | 105 | ### Scopes 106 | 107 | ```ruby 108 | scope 'admin', constraints: { subdomain: 'admin' } do 109 | resources ... 110 | end 111 | ``` 112 | 113 | ## Nested Resources \(routes\) 114 | 115 | Assuming an event has many registrations and we want registration routes to be nested under an event, e.g. `localhost:3000/events/1/registrations`, we can do: 116 | 117 | ```ruby 118 | Rails.applications.routes.draw do 119 | resources :events do 120 | resources :registrations 121 | end 122 | end 123 | ``` 124 | 125 | ## Splitting Up Big Routes Files 126 | 127 | _\(Mostly taken from_ [_Matt Boldt's blog post_](https://mattboldt.com/separate-rails-route-files/)_\)_ 128 | 129 | [GitLab's route files](https://gitlab.com/gitlab-org/gitlab/tree/master/config/routes) are also a great example. 130 | 131 | **First you have to make a new `draw` method into Rails's routing mapper via an initializer** 132 | 133 | ```ruby 134 | # config/initializers/routing_draw.rb 135 | 136 | # Adds draw method into Rails routing 137 | # It allows us to keep routing splitted into files 138 | class ActionDispatch::Routing::Mapper 139 | def draw(routes_name) 140 | instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb"))) 141 | end 142 | end 143 | ``` 144 | 145 | **Update your `config/routes.rb` with the names of files in `config/routes/*.rb`** 146 | 147 | ```ruby 148 | # config/routes.rb 149 | MyApp::Application.routes.draw do 150 | draw :api_v1 151 | draw :api_v2 152 | draw :admin 153 | end 154 | ``` 155 | 156 | **New route files** 157 | 158 | ```ruby 159 | # config/routes/api_v1.rb 160 | namespace :api_v1 do 161 | # lots of routes 162 | end 163 | 164 | # config/routes/api_v2.rb 165 | namespace :api_v2 do 166 | # lots of routes 167 | end 168 | 169 | # config/routes/admin.rb 170 | namespace :admin do 171 | # lots of routes 172 | end 173 | ``` 174 | 175 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/setup.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | I like to use Rails with postgres a lot, this is how to make a new Rails project with Postgres as the default database adapter: 4 | 5 | ```text 6 | rails new myapp --database=postgresql 7 | ``` 8 | 9 | In some cases I use Rails without ActiveRecord \(e.g. [mongoid](https://github.com/mongodb/mongoid) for [MongoDB](https://www.mongodb.com/), like so: 10 | 11 | ```text 12 | rails new myapp --skip-active-record 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /programming-languages/ruby/ruby-on-rails/status-code-symbols.md: -------------------------------------------------------------------------------- 1 | # Status Code Symbols 2 | 3 | _Taken from this_ [_GitHub Gist_](https://gist.github.com/mlanett/a31c340b132ddefa9cca) 4 | 5 | ## 1xx Informational 6 | 7 | 100 `:continue` 8 | 101 `:switching_protocols` 9 | 102 `:processing` 10 | 11 | ## 2xx Success 12 | 13 | 200 `:ok` 14 | 201 `:created` 15 | 202 `:accepted` 16 | 203 `:non_authoritative_information` 17 | 204 `:no_content` 18 | 205 `:reset_content` 19 | 206 `:partial_content` 20 | 207 `:multi_status` 21 | 226 `:im_used` 22 | 23 | ## 3xx Redirection 24 | 25 | 300 `:multiple_choices` 26 | 301 `:moved_permanently` 27 | 302 `:found` 28 | 303 `:see_other` 29 | 304 `:not_modified` 30 | 305 `:use_proxy` 31 | 307 `:temporary_redirect` 32 | 33 | ## 4xx Client Error 34 | 35 | 400 `:bad_request` 36 | 401 `:unauthorized` 37 | 402 `:payment_required` 38 | 403 `:forbidden` 39 | 404 `:not_found` 40 | 405 `:method_not_allowed` 41 | 406 `:not_acceptable` 42 | 407 `:proxy_authentication_required` 43 | 408 `:request_timeout` 44 | 409 `:conflict` 45 | 410 `:gone` 46 | 411 `:length_required` 47 | 412 `:precondition_failed` 48 | 413 `:request_entity_too_large` 49 | 414 `:request_uri_too_long` 50 | 415 `:unsupported_media_type` 51 | 416 `:requested_range_not_satisfiable` 52 | 417 `:expectation_failed` 53 | 422 `:unprocessable_entity` 54 | 423 `:locked` 55 | 424 `:failed_dependency` 56 | 426 `:upgrade_required` 57 | 58 | ## 5xx Server Error 59 | 60 | 500 `:internal_server_error` 61 | 501 `:not_implemented` 62 | 502 `:bad_gateway` 63 | 503 `:service_unavailable` 64 | 504 `:gateway_timeout` 65 | 505 `:http_version_not_supported` 66 | 507 `:insufficient_storage` 67 | 510 `:not_extended` 68 | 69 | -------------------------------------------------------------------------------- /programming-languages/ruby/snippets.md: -------------------------------------------------------------------------------- 1 | # Snippets 2 | 3 | A couple of snippets for things I have to do a lot but forget how every once in a while 4 | 5 | ## Using `.map` on a Hash 6 | 7 | ```ruby 8 | { a: 'a', b: 'b' }.map { |k, str| [k, "%#{str}%"] }.to_h 9 | ``` 10 | 11 | ## Convert an Array of Hashes to a Hash 12 | 13 | ```ruby 14 | # I have an array of hashes 15 | array = [ {id: 1, name: "test"} ] 16 | 17 | # I want to turn it to a hash, where the key is `id` 18 | array.map { |h| [h[:id], h] }.to_h 19 | #=> { 1 => {:id => 1, :name => "test"} } 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /sharing.md: -------------------------------------------------------------------------------- 1 | # Sharing 2 | 3 | ## **Code on** [**GitHub**](https://github.com/obahareth) 4 | 5 | I love solving problems with code. [Here](https://github.com/obahareth?tab=repositories&type=source) are all the repositories I made. 6 | 7 | ## **Thoughts on** [**Twitter**](https://twitter.com/o_bahareth) 8 | 9 | I share a lot of cool tech posts I come by, sometimes about random life tidbits, and I tweet in both Arabic and English. 10 | 11 | ## **Blog on** [**Medium**](https://medium.com/@obahareth) 12 | 13 | I write mostly about programming, tools, and management. 14 | 15 | ## **Experiences on** [**Instagram**](https://www.instagram.com/obahareth/) 16 | 17 | I mostly share cat pics or pics from my travels. 18 | 19 | ## **Ideas in** [**Notion**](https://www.notion.so/obahareth/Public-04ad2eb582a448b1ae834249d5ada9b9) 20 | 21 | My time is limited and I can't often do everything I wish. But I have many ideas and lists so I put all of them [in the open](https://www.notion.so/03b7e9880c26428596228dfb14ee6e47). 22 | 23 | ## Snippets on [GitHub Gists](https://gist.github.com/obahareth)​ 24 | 25 | I things I'm tinkering with, code that I want to embed in articles, and configurations for various tools on GitHub Gist. 26 | 27 | ## **Knowledge in** [**this wiki**](https://wiki.omar.engineer/) 28 | 29 | I am trying to fill everything I know in this wiki. It can be easily queried with the search at the top right. 30 | 31 | ## **Everything else** 32 | 33 | I share most everything else here: 34 | 35 | * [Reddit](https://www.reddit.com/user/obahareth/) 36 | * [Hacker News](https://news.ycombinator.com/user?id=obahareth) 37 | * [Stack Overflow](https://stackoverflow.com/users/1544440/omar-bahareth) 38 | * [Quora](https://www.quora.com/profile/Omar-Bahareth) 39 | * [Product Hunt](https://www.producthunt.com/@o_bahareth) 40 | * [Indie Hackers](https://www.indiehackers.com/user/obahareth) 41 | 42 | -------------------------------------------------------------------------------- /software-architecture/README.md: -------------------------------------------------------------------------------- 1 | # Software Architecture 2 | 3 | ## Links 4 | 5 | * [Modular Application Architecture - Intro](https://www.goetas.com/blog/modular-application-architecture-intro/). 6 | 7 | -------------------------------------------------------------------------------- /software-architecture/centralized-authentication.md: -------------------------------------------------------------------------------- 1 | # Centralized Authentication 2 | 3 | ## Links 4 | 5 | * [How to Implement a Secure Central Authentication Service in Six Steps](https://engineering.shopify.com/blogs/engineering/implement-secure-central-authentication-service-six-steps) 6 | 7 | -------------------------------------------------------------------------------- /software-architecture/event-sourcing.md: -------------------------------------------------------------------------------- 1 | # Event sourcing 2 | 3 | ## Links 4 | 5 | ### Articles 6 | 7 | * [Event Sourcing made Simple](https://kickstarter.engineering/event-sourcing-made-simple-4a2625113224) 8 | * [Follow these practical principles to get well-designed microservices boundaries](https://medium.freecodecamp.org/follow-these-practical-principles-and-get-well-designed-microservices-boundaries-ef2deffd69e3) 9 | * [Getting a Competitive Edge with a Microservices Based Architecture](https://auth0.com/blog/getting-a-competitive-edge-with-a-microservices-based-architecture/) 10 | * [3 Secrets to Building Microservices \| Atlassian](https://www.atlassian.com/continuous-delivery/microservices/building-microservices) 11 | * [CQRS and Event Sourcing Intro For Developers - Software House Altkom Software & Consulting \| ASC LAB](https://altkomsoftware.pl/en/blog/cqrs-event-sourcing/) 12 | * [Why Event Sourcing basically requires CQRS and Read Models](https://blog.arkency.com/why-event-sourcing-basically-requires-cqrs-and-read-models/) 13 | * [Developing Transactional Microservices Using Aggregates, Event Sourcing and CQRS - Part 2](https://www.infoq.com/articles/microservices-aggregates-events-cqrs-part-2-richardson) 14 | * [Event sourced domain objects in less than 150 LOC](https://blog.arkency.com/2016/12/event-sourced-domain-objects-in-less-than-150-loc/) 15 | * [Event Sourcing with Aggregates in Rust](https://medium.com/capital-one-tech/event-sourcing-with-aggregates-in-rust-4022af41cf67) 16 | 17 | ### Videos 18 | 19 | * [Scaling Event Sourcing for Netflix Downloads](https://www.youtube.com/watch?v=rsSld8NycCU&t=2670s) 20 | * [Building a Real-Time Microservices Payments Platform - An Engineer's Dream!](https://www.brighttalk.com/webcast/679/311839/building-a-real-time-microservices-payments-platform-an-engineers-dream) 21 | 22 | ### Slides 23 | 24 | * [Event Sourcing in practice](https://ookami86.github.io/event-sourcing-in-practice/) 25 | 26 | -------------------------------------------------------------------------------- /software-architecture/microservices.md: -------------------------------------------------------------------------------- 1 | # Microservices 2 | 3 | ## Links 4 | 5 | ### Videos 6 | 7 | * [10 Tips for failing badly at Microservices by David Schmitz](https://www.youtube.com/watch?v=X0tjziAQfNQ) 8 | 9 | ### Articles 10 | 11 | * [Should that be a Microservice? Keep These Six Factors in Mind](https://content.pivotal.io/blog/should-that-be-a-microservice-keep-these-six-factors-in-mind). 12 | * [Goodbye Microservices](https://segment.com/blog/goodbye-microservices/) 13 | * [These are the most effective microservice testing strategies, according to the experts](https://medium.freecodecamp.org/these-are-the-most-effective-microservice-testing-strategies-according-to-the-experts-6fb584f2edde) 14 | 15 | -------------------------------------------------------------------------------- /software-architecture/serverless.md: -------------------------------------------------------------------------------- 1 | # Serverless 2 | 3 | ## Links 4 | 5 | [Organizing Serverless Projects](https://serverless-stack.com/chapters/organizing-serverless-projects.html). 6 | 7 | -------------------------------------------------------------------------------- /talks/README.md: -------------------------------------------------------------------------------- 1 | # Talks 2 | 3 | -------------------------------------------------------------------------------- /talks/software-architecture/README.md: -------------------------------------------------------------------------------- 1 | # Software Architecture 2 | 3 | -------------------------------------------------------------------------------- /talks/software-architecture/an-insiders-look-at-the-technology-that-powers-shopify.md: -------------------------------------------------------------------------------- 1 | # An Insider's Look at the Technology That Powers Shopify 2 | 3 | {% embed url="https://www.youtube.com/watch?v=Th7XN__ltyc" %} 4 | 5 | [Talk link](https://www.youtube.com/watch?v=Th7XN\_\_ltyc). 6 | 7 | ## Quick Summary 8 | 9 | Watched this talk because I thought it was more software architecture related but it turned out to be a very general and high level overview on 4 areas of Shopify's technology. Lots of cool Silk Road. economical, and historical references though. 10 | 11 | ## Open Internet 12 | 13 | **Payments** 14 | 15 | * Joined W3C in 2016 as a founding member of the [payments working group](https://www.w3.org/Payments/WG/), to standardize payment actions on the internet for 3 years+. 16 | * Principles: 17 | * "Do you have a wallet?" 18 | * "Can you make a payment?" 19 | * "Let's make it fast." 20 | 21 | **3D Models** 22 | 23 | * Shopify is working with the [Khronos Group](https://khronos.org) (an open standards body) to advance 3D model formats for the internet. 24 | 25 | ## Security & Privacy 26 | 27 | * A merchant's data belongs to the merchant. 28 | * "We have the tools to support you, but you have to use them". 29 | * The biggest threat to a merchant's data is compromised credentials, mainly from phishing emails. 30 | * New identity vault launched: [https://accounts.shopfiy.com](https://accounts.shopfiy.com) 31 | * One account and one setting for everything you do on Shopify. 32 | * Supports new [Web Authentication API](https://www.w3.org/TR/webauthn/) (WebAuthn, [nice guide here](https://webauthn.guide/)). 33 | * Allows Shopify servers to interact with secure identity meechanisms on devices (TouchID, Windows Hello, etc.) 34 | * Additional support on data ownership and privacy through new webhooks and APIs 35 | * Data request and deletion API. 36 | * Greater app permission transparency. 37 | * Ranking and monitoring apps on Shopify platform to make sure that their partners are building applications that respect data on behalf of the merchant. 38 | * Processing more than 10 billion events everyday, which totals to 10 petabytes of data. 39 | * Network of 3000+ security engineers who have been paid out more than 1 million USD to find and report vulnerabilities (on test shops). 40 | * Increasing investment on [metafields](https://help.shopify.com/en/manual/products/metafields) on Shopify platform. 41 | 42 | ## Extensibility 43 | 44 | * Providing unique products and experience is a key product to make commerce exciting and enjoyable. 45 | * Guided by the philosophy of The Silk Road. 46 | * 5 years ago Shopify API had lag between announcing APIs and features. 47 | * As of this talk, Shopify is powered by the same REST and GraphQL APIs used by clients. No lag between feature announcements and API announcements anymore. 48 | * New PoS is being built with apps as a core feature built into the experience. 49 | * APIs are features. 50 | * Comitting to building as many APIs they can to keep Shopify the most creative platform for commerce experiences. 51 | 52 | ## Global Infrastructure 53 | 54 | * Scaled from 2 points of presence to 180 in over 80 countries in a single year. Decreasing latency for buyers by 30% - 50%. 55 | * Launching 4 new regions in next 18 months from this talk's date. 56 | * Requests reach around 5 million per minute. 57 | * Some merchants are selling more than 8000 orders a minute. 58 | * Speed matters more than scale for most merchants. 59 | * Two big performance wins: 60 | * Upgrade to image delivery service by using WebP (30% smaller and faster). 61 | * New Liquid renderer that's 7x faster. 62 | -------------------------------------------------------------------------------- /talks/software-architecture/building-extensible-platforms.md: -------------------------------------------------------------------------------- 1 | # Building Extensible Platforms 2 | 3 | {% embed url="https://www.youtube.com/watch?v=GqGNA8GnOOE" %} 4 | 5 | [Talk link](https://www.youtube.com/watch?v=GqGNA8GnOOE). 6 | 7 | ## Platforms 8 | 9 | > "Platforms provide a layer of abstraction to simplify otherwise complex tasks." 10 | 11 | In platforms, all functionalitywe care about as users is generally provided by apps. The difference between platforms and apps is that platforms don't necessarily provide functionality but they are an important foundation for apps. 12 | 13 | The purpose of a platform is to simplify application development and manage shared resources and services and access them through APIs. 14 | 15 | Examples of platforms: 16 | 17 | * Operating systems. 18 | * Web browsers \(They're an application from the perspective of an OS, but they also provide platform capabilities\). 19 | 20 | ## Extensibility 21 | 22 | > "Designed to allow the addition of new capabilities and functionality" 23 | 24 | Extensibility is core to Shopify product philosphy. 25 | 26 | * Platform team works with teams involved in the entire customer journey \(from business operations to selling in-person\) towards making Shopify extensible as a whole. 27 | * [Shopify Flow](https://apps.shopify.com/flow), a tool for merchants to build automated workflows based on their business operations. Works a lot like Zapier \(triggers, conditions, and actions\). Third party developers can also build extensions to build custom triggers, conditions, and actions. It works and feels like Shopify first party functionality. 28 | 29 | > "The experience of third-party developers is just as important as end-users' experience." 30 | 31 | **Other examples** 32 | 33 | * [Todoist Chrome extension](https://chrome.google.com/webstore/detail/todoist-to-do-list-and-ta/jldhpllghnbhlbpcmnajkpdmadaolakh?hl=en). Uses Chrome to render an icon button and present an overlay to manage Todoist. It feels like a native part of the browser experience thanks to the extension capabilities offered by Google Chrome. 34 | * [Slack apps](https://slack.com/apps). Extend Slack functionality using bots and slash commands. Use apps without distrupting flow of conversations. 35 | 36 | ## [App Extensions](https://help.shopify.com/en/api/embedded-apps/app-extensions) 37 | 38 | > ""App Extensions" are a deep third-party integration that feels indistinguishable from native functionality." 39 | 40 | _Example of using Shopify Flow to build new triggers and actions starts at 11:23._ 41 | 42 | App extensions are the counterpart to APIs. When using APIs the app initiates the data exchange with your platform. When using app extensions allow your platform to initiate the data exchange aas required. 43 | 44 | With app extensions, Shopify is in charge of pushing/pulling data to/from the extension, and the merchants never leave Shopify and have a consistent and seamless experience. 45 | 46 | > "It is the combination of great user experience and great developer experience that make app extensions so powerful." 47 | 48 | Merchants use Shopify Core \(can be accessed through web, apps, smart text-based assistants\), developers use the Partners Dashboard. 49 | 50 | > "You might ask: "Why provide a graphical interface \(to programmers\) instead of a programmatic one?" 51 | > 52 | > Our goal is to create a developer experience that doesn't require reading any API documentation, we want to promote exploration and allow developers to learn about the capabilities of our platform interactively." 53 | 54 | ## App Extensions From Internal Teams' Perspective 55 | 56 | > "Treat your internal teams as your customers too and provide them with the same quality tools you provide yor external customers" 57 | 58 | To reduce friction they built an internal framework that manages all persistence and communication between their core product and partner's dashboard. This significantly reduced the number of steps involved in building app extensions to only 3 steps: 59 | 60 | * Domain model. 61 | * Merchant facing UI. 62 | * Partner facing UI. 63 | 64 | They also provide a wealth of UX resources to make it easier for teams to design app extensions. 65 | 66 | Good internal documentation \(education\) was a must to enable this process. Broadcasting information on a regular basis is just as important as being around to answer questions. They maintained a Slack channel to support teams during the initial phases of the project. 67 | 68 | ## How to Build Extensibility 69 | 70 | > "Make it easy to think about 'What to make extensible' rather than 'how to build extensibility'" 71 | > 72 | > "What parts of a user workflow should we enable our ecosystem to plug into? 73 | > 74 | > Which parts of our user experience should we make adaptable to whatever our ecosystem might build?" 75 | 76 | Shopify tackles these problems by: 77 | 78 | 1. Building features that **most** of their users need \(the 80/20 rule, 80% is a core commerce need, 20% is divergent needs. Shopify enables their ecosystem to build for their niche divergent needs\). 79 | 2. Enable their partner ecosystem to build the rest. 80 | 81 | > "Company-wide platform commitment has an incredible network effect \(when a product or service gains more value as more people use it\). Merchants are drawn to Shopify because of the ways Shopify and Shopify apps solve their end to end commerce needs. At the same time partners are drawn to our platform for our growing user base and our growing business needs and growing opportunities for innovation and entrepreneurship." 82 | 83 | -------------------------------------------------------------------------------- /version-control/README.md: -------------------------------------------------------------------------------- 1 | # Version Control 2 | 3 | -------------------------------------------------------------------------------- /version-control/git/README.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | **Links** 4 | 5 | * [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/). 6 | * [How to discover a bug using git bisect](https://flaviocopes.com/git-bisect/). 7 | 8 | ## Hook managers 9 | 10 | Git hook managers are very useful if you want to ensure code is formatted/tests are run before you can commit, and you can even prevent comitting if the fail. 11 | 12 | * [overcommit](https://github.com/sds/overcommit) - A fully configurable and extendable Git hook manager. 13 | 14 | -------------------------------------------------------------------------------- /version-control/git/conventions/README.md: -------------------------------------------------------------------------------- 1 | # Conventions 2 | 3 | -------------------------------------------------------------------------------- /version-control/git/conventions/conventional-commits.md: -------------------------------------------------------------------------------- 1 | # Conventional Commits 2 | 3 | "[Conventional Commits](https://www.conventionalcommits.org/en)" is a specification for adding human and machine readable meaning to commit messages. 4 | 5 | Example of a subject for a commit adding an ability to parse arrays to a JavaScript parser 6 | 7 | `feat(javascript_parser): add ability to parse arrays` 8 | 9 | ## Why Use Conventional Commits? 10 | 11 | * Automatically generating CHANGELOGs. 12 | * Automatically determining a semantic version bump \(based on the types of commits landed\). 13 | * Communicating the nature of changes to teammates, the public, and other stakeholders. 14 | * Triggering build and publish processes. 15 | * Making it easier for people to contribute to your projects, by allowing them to explore a more structured commit history. 16 | 17 | -------------------------------------------------------------------------------- /version-control/git/conventions/gitmoji.md: -------------------------------------------------------------------------------- 1 | # gitmoji 2 | 3 | [Gitmoji](https://github.com/carloscuesta/gitmoji) make quickly visually identifying what a commit changed pretty fast and fun. 4 | 5 | ## List 6 | 7 | ### Bugs 8 | 9 | * 🐛 - `:bug:` for fixing a bug. 10 | * 🚑 - `ambulance` for a critical hotfix. 11 | 12 | ### Features 13 | 14 | * ✨ - `:sparkles:` Introducing new features. 15 | 16 | ### Code Quality 17 | 18 | * 🎨 - `:art:` Improving structure / format of code. 19 | * ♻️ - `:recycle` Refactoring code. 20 | * 👌 - `:ok_hand:` Updating code due to code review changes. 21 | * 🏗 - `:building_construction:` Making architectural changes. 22 | * 💥 - `:boom:` Introducing breaking changes. 23 | * 🍻 - `:beers:` Writing code drunkenly. 24 | * 💩 - `:poop:` Writing bad code that needs to be improved. 25 | 26 | ### Testing 27 | 28 | * ✅ - `:white_check_mark:` Updating tests. 29 | * 🤡 - `:clown_face:` Mocking things. 30 | 31 | #### CI 32 | 33 | * 👷 - `:construction_worker:` Adding CI build system. 34 | * 💚 - `:green_heart:` Fixing CI build. 35 | 36 | ### Database 37 | 38 | * 🗃 - `:card_file_box:` Performing database related changes. 39 | * 🌱 - `:seedling:` Adding or updating seed files. 40 | 41 | ### Logs 42 | 43 | * 🔊 - ​`:loud_sound:` Adding logs. 44 | * 🔇 - ​`:mute:` Removing logs. 45 | 46 | ### UI/UX 47 | 48 | * 📱 - `:iphone:` Working on responsive design. 49 | * 🚸 - `:children_crossing:` Improving user experience / usability. 50 | * ♿️ - `:wheelchair:` Improving accessibility. 51 | * 💄 - `:lipstick:` Updating UI or style files. 52 | 53 | ### Types 54 | 55 | * 🏷️ - `:label:` Adding or updating types \(Flow, TypeScript\). 56 | 57 | ### Feature flags 58 | 59 | * 🚩 - `:triangular_flag_on_post:` Adding, updating, or removing feature flags. 60 | 61 | ### Documentation 62 | 63 | * 💡 - ​`:bulb:` Documenting source code. 64 | * 📝 - `:pencil:` Writing docs. 65 | 66 | ### Dependencies 67 | 68 | * ➕ - `:heavy_plus_sign:` Adding a dependency. 69 | * ➖ - `:heavy_minus_sign:` Removing a dependency. 70 | * 📌 - `:pushpin:` Pinning dependencies to specific versions. 71 | * ⬆️ - `:arrow_up` Upgrading dependencies. 72 | * ⬇️ - `:arrow_down` Downgrading dependencies. 73 | 74 | ### Security 75 | 76 | * 🔒 - `:lock:` Fixing security issues. 77 | 78 | ### Platform-specific 79 | 80 | * 🍏 - `:green_apple:` Fixing something on iOS. 81 | * 🤖 - `:robot:` Fixing something on Android. 82 | * 🏁 - `:checkered_flag:` Fixing something on Windows. 83 | * 🍎 - `:apple:` Fixing something on macOS. 84 | * 🐧 - `:penguin:` Fixing something on Linux. 85 | * 🐳 - `:whale:` Work about Docker. 86 | * ☸️ - `:wheel_of_darma:` Work about Kubernetes. 87 | 88 | ### Git 89 | 90 | * 🎉 - `:tada:` Initial commit. 91 | * 🙈 - `:see_no_evil:` Adding or updating a .gitignore file. 92 | * 👥 - `:busts_in_silhouette` Adding contributor\(s\). 93 | * 🔀 - `:twisted_rightwards_arrows:` Merging branches. 94 | * ⏪ - `:rewind:` Reverting changes. 95 | 96 | ### Files 97 | 98 | * 🚚 - `:truck:` Moving or renaming files. 99 | * 📦 - `:package:` Updating compiled files or packages. 100 | * 🔥 - `:fire:` Removing code or files. 101 | 102 | ### Linters 103 | 104 | * 🚨 - `:rotating_light:` Removing linter warnings. 105 | 106 | ### Releases / Tags 107 | 108 | * 🔖 - `:bookmark:` Releasing / Version tags. 109 | * 🚀 - `:rocket:` Deploying stuff. 110 | 111 | ### Configuration 112 | 113 | * 🔧 - `:wrench:` Changing configuration files. 114 | 115 | ### Localization / Text 116 | 117 | * 🌐 - `:globe_with_meridians:` Internationalization and localization. 118 | * 💬 - `:speech_balloon:` Updating text and literals. 119 | * ✏️ - `:pencil2:` Fixing typos. 120 | 121 | ### Licenses 122 | 123 | * 📄 - `:page_facing_up` Adding or updating license. 124 | 125 | ### Misc. 126 | 127 | * 🔍 - `:mag:` Improving SEO. 128 | * ⚗ - `:alembic:` Experimenting new things. 129 | * 📸 - `:camera_flash:` Adding or updating snapshots. 130 | * 🥚 - `:egg:` Adding an easter egg. 131 | * 🍱 - `:bento:`​ Adding or updating assets. 132 | * 📈 - `:chart_with_upwards_trend:` Adding analytics or tracking code. 133 | * 🚧 - `:construction:` Work in progress. 134 | * ⚡️ - `:zap:` Improving performance. 135 | * 👽 - `:alien:` Updating code due to external API changes. 136 | 137 | -------------------------------------------------------------------------------- /work/README.md: -------------------------------------------------------------------------------- 1 | # Work 2 | 3 | -------------------------------------------------------------------------------- /work/hiring-process.md: -------------------------------------------------------------------------------- 1 | # Hiring Process 2 | 3 | ### Process 4 | 5 | #### Detailed Job Posting 6 | 7 | It's very important to have a detailed job posting, this will help candidates know what to expect of your workplace and help you to filter out unsuitable candidates as they will not even apply if the job doesn't suit them. A great example in detailed listings is Basecamp's listings, take a look at their [Head of Marketing](https://m.signalvnoise.com/basecamp-is-hiring-a-head-of-marketing/) example. 8 | 9 | #### Simple Coding Challenge 10 | 11 | _After some screening for communication alignment and HR screening_ 12 | 13 | This would be a simple coding challenge based on a real problem we face at our workplace; preferably solved in a language/framework we use but not mandatory, it should ideally be doable within 2 hours but I'd give you a whole week because sometimes we as humans get stuck on the silliest matters no matter how long we've been doing something, perhaps you'd like some time to learn the basics of the framework/language we use and try to solve it in it, and because you probably have other priorities. 14 | 15 | #### Interview Process 16 | 17 | Hiring is something that's hard to get right and I think most of the methodologies we currently use are quire flawed. We look too much at what someone has done in the past and almost never look at what they want to do now. I believe [Microsoft's new process](https://blog.usejournal.com/rethinking-how-we-interview-in-microsofts-developer-division-8f404cfd075a) is a huge step towards the right direction, give someone a chance to work with you using the same information you have. Solve a real problem together, do actual work. The only way to know if someone is a fit or not is to work with them and have all the different teams work with them. 18 | 19 | I realize that's expensive and few places can afford that, but that's my ideal scenario, I've never gotten to do this before but I think it would yield much better results. 20 | 21 | ### Points to Consider 22 | 23 | #### Degrees 24 | 25 | Degrees are great, but I wouldn't discredit someone because they don't have one. The gap between what you learn at university and what the market needs is growing a lot, especially in developing countries. As I said above the only solution is to work together for a bit. 26 | 27 | #### Communication 28 | 29 | As I described in [How I Want to Work](https://wiki.omar.engineer/work/what-i-want-in-a-workplace), being able to communicate in the same language and in the same style is extremely important. I once tried to build a culture of asynchronous communication based primarily on written communication, but I hired people whose stronger communication points aren't aligned with that and it didn't work out so well. In future hiring I must make sure that our style of communication works well for both parties. 30 | 31 | #### Clear Expectations 32 | 33 | [HackerRank's 2019 Developer Skills Report](https://research.hackerrank.com/developer-skills/2019) shows that the number one reason to lose candidates is unclear roles, and I've often been put in that situation as well. You join in as a backend developer and you're suddenly asked to do everything \(DevOps, sysadmin, dba, native iOS and Android development, Angular, React, Laravel, Kubernetes, etc.\), this is all too common in developing countries where specialization is still rare. I've also sadly hired people with unclear expectations in the past and it's something I do not wish on anyone. I would do everything in my power to explain everything a certain role requires and make sure it remains so. 34 | 35 | #### Compensation for Work Done During Process 36 | 37 | I have been seeing a lot of people saying that candidates should be paid for the work they do during hiring processes, and I think that is a fair point, especially with the idea of letting you work with us on a real problem. If the place I'm hiring for can afford it, this would happen. If not, I would do my best to try and make it happen. 38 | 39 | -------------------------------------------------------------------------------- /work/what-i-want-in-a-workplace.md: -------------------------------------------------------------------------------- 1 | # How I Want to Work 2 | 3 | Being able to work at a place or project that has all of these things is a rare opportunity, and if I get it I would definitely give everything I have to it. 4 | 5 | ## I want to do work I'm proud of 6 | 7 | I've often had to do work that I believed had bad performance, believed will cause bugs, and is just troublesome for other developers to deal with due to time constraints. I don't want to do that in my career anymore, I want to add value to all people who interact with my work, whether it's users or developers, and reaching a point where I've been doing this for seven years, it just hurts and it has to stop. I know I can do awesome stuff but I am held back, and I no longer want to be. I know that sometimes you have to sacrifice these things to reach a certain goal, but it's always been the sacrifice without the goal so far. 8 | 9 | I want to make software that'll make both users and developers \(performance, structure, readability, you name it\) smile. 10 | 11 | ## I want to create something meaningful 12 | 13 | Throughout my career I've built too much software for clients where almost no users use the software, and those that do suffer from lack of maintenance; and I've also built too much software that has never seen the light of day. I want to build something that at least makes someone smile or saves some time in their day. I am extremely inspired by initiatives like[ IBM's Call for Code](https://developer.ibm.com/callforcode/), a chance to save people from natural disasters using what I know? That's like a dream come true! 14 | 15 | ## I want to grow as an engineer 16 | 17 | I've been stuck doing the same kind of work over and over, building webapps and mobile apps that generally just do the same exact thing. I want to do something challenging, something new. I want to work on something that has to deal with scaling issues, I want to work on something like Docker or cloud services. I'm seeing a lot of cool stuff being done with Go, Rust, and Elixir lately and I want to be a part of those communities. 18 | 19 | ## I want to have a mentor 20 | 21 | I've never really had a mentor in my career and I've generally had to always figure things out on my own or build up teams. I want someone to build me up. 22 | 23 | ## I want my time back, and I want to see the sun 24 | 25 | Traditional work hours just drain my energy and leave me with a Vitamin-D deficiency, I honestly don't think that's healthy in any way imaginable, and it's unfair to all my loved ones. I want more time to give back to open source, I want to start a technical podcast, and do so much more. I would love to be in a workplace that enables me to do these things. 26 | 27 | ## I want to work remotely 28 | 29 | I believe remote work is definitely the next extension of our digital careers. I have distantly watched GitLab grow with that mission and am immensely impressed by what they've done. One of the things they noticed that one of the very first things people do when they join GitLab is move back to be close to their friends and family. It feels morally wrong for me to have to put friends and family second to my career \(both due to lack of time, and lack of jobs where I live\). 30 | 31 | ## I need to be able to communicate with my colleagues 32 | 33 | I would like to utilize the languages and skills I know to communicate with my colleagues. Most of my career has been in Saudi Arabia and so I have to be good with both Arabic and English. I'm pretty decent with written and spoken English, and I'm pretty decent with spoken Arabic too, but with written Arabic it's just hell for me because I believe we as Arabs still haven't decided how we want to use its written form, especially when discussing technical topics. 34 | 35 | **On Arabic** 36 | 37 | One example is that our language uses diacritics for vowels but we stopped using them in our written communication \(probably because they make writing take so much longer\) and it makes reading things involve a lot of guessing, and there are so many different dialects \(without any grammar rules, any dictionary, or written resource you can look up\), and that results in all sorts of communication issues and even bugs. I've often had to work with people who I struggle to communicate with because they dislike written communication \(which makes things like pull request reviews quite difficult\), and when they're ok with it, it's in an Arabic dialect that's different from mine. I would love to use [Moden Standard Arabic](https://www.wikiwand.com/en/Modern_Standard_Arabic) but many Arabs \(including me\) don't know it that well, and for some it feels too formal \(some even tell me, it feels like you're giving a speech rather than having a casual conversation\), although there are certain places where that form is the norm, and I really love and respect that. I don't really have a problem with Arabic, but I have a problem with how we choose to use it, how we treat our dialects as a "lesser form" that should go away and thus refuse to standardize it... Since we are both speaking and writing in these dialects, we should have references, proper spellings, and dictionaries for it. If I want to do something as simple as searching an issue tracking system for a bug that used to happen when users selected a specific city, I can't write the city's actual name, I have to try and write it the same dialect as the person who reported it \(and I may not necessarily know that dialect, and that person may not be on our team anymore, and not everyone will even expect this scenario or know how to deal with it\). This also of course makes things like Natural Language Processing incredibly more difficult, and I perhaps should move this topic to its own page in the future. 38 | 39 | --------------------------------------------------------------------------------