Browse Source

vault backup: 2024-09-26 14:50:07

master
Julio Biason 3 weeks ago
commit
b5ba45531e
  1. 1
      .obsidian/app.json
  2. 1
      .obsidian/appearance.json
  3. 4
      .obsidian/community-plugins.json
  4. 30
      .obsidian/core-plugins-migration.json
  5. 20
      .obsidian/core-plugins.json
  6. 22
      .obsidian/graph.json
  7. 56
      .obsidian/plugins/obsidian-git/data.json
  8. 350
      .obsidian/plugins/obsidian-git/main.js
  9. 10
      .obsidian/plugins/obsidian-git/manifest.json
  10. 566
      .obsidian/plugins/obsidian-git/styles.css
  11. 151
      .obsidian/plugins/obsidian-kanban/main.js
  12. 11
      .obsidian/plugins/obsidian-kanban/manifest.json
  13. 1
      .obsidian/plugins/obsidian-kanban/styles.css
  14. 168
      .obsidian/workspace.json
  15. 4
      Links.md
  16. 51
      Pages/8 versions of UUID and when to use them.md
  17. 514
      Pages/Server Setup Basics.md
  18. 142
      PythonSul 2025/0. Doc.md
  19. 29
      PythonSul 2025/Z. Kanban.md

1
.obsidian/app.json

@ -0,0 +1 @@
{}

1
.obsidian/appearance.json

@ -0,0 +1 @@
{}

4
.obsidian/community-plugins.json

@ -0,0 +1,4 @@
[
"obsidian-kanban",
"obsidian-git"
]

30
.obsidian/core-plugins-migration.json

@ -0,0 +1,30 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false
}

20
.obsidian/core-plugins.json

@ -0,0 +1,20 @@
[
"file-explorer",
"global-search",
"switcher",
"graph",
"backlink",
"canvas",
"outgoing-link",
"tag-pane",
"page-preview",
"daily-notes",
"templates",
"note-composer",
"command-palette",
"editor-status",
"bookmarks",
"outline",
"word-count",
"file-recovery"
]

22
.obsidian/graph.json

@ -0,0 +1,22 @@
{
"collapse-filter": true,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": true,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": true,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 1,
"close": true
}

56
.obsidian/plugins/obsidian-git/data.json

@ -0,0 +1,56 @@
{
"commitMessage": "vault backup: {{date}}",
"commitDateFormat": "YYYY-MM-DD HH:mm:ss",
"autoSaveInterval": 0,
"autoPushInterval": 0,
"autoPullInterval": 0,
"autoPullOnBoot": false,
"disablePush": false,
"pullBeforePush": true,
"disablePopups": false,
"disablePopupsForNoChanges": false,
"listChangedFilesInMessageBody": false,
"showStatusBar": true,
"updateSubmodules": false,
"syncMethod": "merge",
"customMessageOnAutoBackup": false,
"autoBackupAfterFileChange": false,
"treeStructure": false,
"refreshSourceControl": true,
"basePath": "",
"differentIntervalCommitAndPush": false,
"changedFilesInStatusBar": false,
"showedMobileNotice": true,
"refreshSourceControlTimer": 7000,
"showBranchStatusBar": true,
"setLastSaveToLastCommit": false,
"submoduleRecurseCheckout": false,
"gitDir": "",
"showFileMenu": true,
"authorInHistoryView": "hide",
"dateInHistoryView": false,
"lineAuthor": {
"show": false,
"followMovement": "inactive",
"authorDisplay": "initials",
"showCommitHash": false,
"dateTimeFormatOptions": "date",
"dateTimeFormatCustomString": "YYYY-MM-DD HH:mm",
"dateTimeTimezone": "viewer-local",
"coloringMaxAge": "1y",
"colorNew": {
"r": 255,
"g": 150,
"b": 150
},
"colorOld": {
"r": 120,
"g": 160,
"b": 255
},
"textColorCss": "var(--text-muted)",
"ignoreWhitespace": false,
"gutterSpacingFallbackLength": 5
},
"autoCommitMessage": "vault backup: {{date}}"
}

350
.obsidian/plugins/obsidian-git/main.js

File diff suppressed because one or more lines are too long

10
.obsidian/plugins/obsidian-git/manifest.json

@ -0,0 +1,10 @@
{
"author": "Vinzent",
"authorUrl": "https://github.com/Vinzent03",
"id": "obsidian-git",
"name": "Git",
"description": "Integrate Git version control with automatic backup and other advanced features.",
"isDesktopOnly": false,
"fundingUrl": "https://ko-fi.com/vinzent",
"version": "2.27.0"
}

566
.obsidian/plugins/obsidian-git/styles.css

@ -0,0 +1,566 @@
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.workspace-leaf-content[data-type="git-view"] .button-border {
border: 2px solid var(--interactive-accent);
border-radius: var(--radius-s);
}
.workspace-leaf-content[data-type="git-view"] .view-content {
padding: 0;
}
.workspace-leaf-content[data-type="git-history-view"] .view-content {
padding: 0;
}
.loading > svg {
animation: 2s linear infinite loading;
transform-origin: 50% 50%;
display: inline-block;
}
.obsidian-git-center {
margin: auto;
text-align: center;
width: 50%;
}
.obsidian-git-textarea {
display: block;
margin-left: auto;
margin-right: auto;
}
.obsidian-git-disabled {
opacity: 0.5;
}
.obsidian-git-center-button {
display: block;
margin: 20px auto;
}
.tooltip.mod-left {
overflow-wrap: break-word;
}
.tooltip.mod-right {
overflow-wrap: break-word;
}
.git-tools {
display: flex;
margin-left: auto;
}
.git-tools .type {
padding-left: var(--size-2-1);
display: flex;
align-items: center;
justify-content: center;
width: 11px;
}
.git-tools .type[data-type="M"] {
color: orange;
}
.git-tools .type[data-type="D"] {
color: red;
}
.git-tools .buttons {
display: flex;
}
.git-tools .buttons > * {
padding: 0 0;
height: auto;
}
.is-active .git-tools .buttons > * {
color: var(--nav-item-color-active);
}
.git-author {
color: var(--text-accent);
}
.git-date {
color: var(--text-accent);
}
.git-ref {
color: var(--text-accent);
}
.workspace-leaf-content[data-type="diff-view"] .d2h-d-none {
display: none;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-wrapper {
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-header {
background-color: var(--background-primary);
border-bottom: 1px solid var(--interactive-accent);
font-family: var(--font-monospace);
height: 35px;
padding: 5px 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-header,
.workspace-leaf-content[data-type="diff-view"] .d2h-file-stats {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-stats {
font-size: 14px;
margin-left: auto;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-lines-added {
border: 1px solid #b4e2b4;
border-radius: 5px 0 0 5px;
color: #399839;
padding: 2px;
text-align: right;
vertical-align: middle;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-lines-deleted {
border: 1px solid #e9aeae;
border-radius: 0 5px 5px 0;
color: #c33;
margin-left: 1px;
padding: 2px;
text-align: left;
vertical-align: middle;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-name-wrapper {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 15px;
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-name {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-wrapper {
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
margin-bottom: 1em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse {
-webkit-box-pack: end;
-ms-flex-pack: end;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
cursor: pointer;
display: none;
font-size: 12px;
justify-content: flex-end;
padding: 4px 8px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse.d2h-selected {
background-color: #c8e1ff;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse-input {
margin: 0 4px 0 0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-diff-table {
border-collapse: collapse;
font-family: Menlo, Consolas, monospace;
font-size: 13px;
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-files-diff {
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-diff {
overflow-y: hidden;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-side-diff {
display: inline-block;
margin-bottom: -8px;
margin-right: -4px;
overflow-x: scroll;
overflow-y: hidden;
width: 50%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line {
padding: 0 8em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line {
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line {
padding: 0 4.5em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-ctn {
word-wrap: normal;
background: none;
display: inline-block;
padding: 0;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
vertical-align: middle;
white-space: pre;
width: 100%;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-line del,
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
del {
background-color: #ffb6ba;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-line del,
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
del {
background-color: #8d232881;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line del,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line del,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line ins {
border-radius: 0.2em;
display: inline-block;
margin-top: -1px;
text-decoration: none;
vertical-align: middle;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins,
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
ins {
background-color: #97f295;
text-align: left;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins,
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
ins {
background-color: #1d921996;
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-prefix {
word-wrap: normal;
background: none;
display: inline;
padding: 0;
white-space: pre;
}
.workspace-leaf-content[data-type="diff-view"] .line-num1 {
float: left;
}
.workspace-leaf-content[data-type="diff-view"] .line-num1,
.workspace-leaf-content[data-type="diff-view"] .line-num2 {
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
padding: 0 0.5em;
text-overflow: ellipsis;
width: 3.5em;
}
.workspace-leaf-content[data-type="diff-view"] .line-num2 {
float: right;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-muted);
cursor: pointer;
display: inline-block;
position: absolute;
text-align: right;
width: 7.5em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber:after {
content: "\200b";
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-muted);
cursor: pointer;
display: inline-block;
overflow: hidden;
padding: 0 0.5em;
position: absolute;
text-align: right;
text-overflow: ellipsis;
width: 4em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-diff-tbody tr {
position: relative;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber:after {
content: "\200b";
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-emptyplaceholder,
.workspace-leaf-content[data-type="diff-view"] .d2h-emptyplaceholder {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-prefix,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber,
.workspace-leaf-content[data-type="diff-view"] .d2h-emptyplaceholder {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber {
direction: rtl;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-del {
background-color: #fee8e9;
border-color: #e9aeae;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-ins {
background-color: #dfd;
border-color: #b4e2b4;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-del {
background-color: #521b1d83;
border-color: #691d1d73;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-ins {
background-color: rgba(30, 71, 30, 0.5);
border-color: #13501381;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-info {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
color: var(--text-normal);
}
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-del.d2h-change {
background-color: #fdf2d0;
}
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-del.d2h-change {
background-color: #55492480;
}
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-ins.d2h-change {
background-color: #ded;
}
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-ins.d2h-change {
background-color: rgba(37, 78, 37, 0.418);
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper {
margin-bottom: 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper a {
color: #3572b0;
text-decoration: none;
}
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-list-wrapper
a:visited {
color: #3572b0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-header {
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-title {
font-weight: 700;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-line {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list {
display: block;
list-style: none;
margin: 0;
padding: 0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list > li {
border-bottom: 1px solid var(--background-modifier-border);
margin: 0;
padding: 5px 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list > li:last-child {
border-bottom: none;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-switch {
cursor: pointer;
display: none;
font-size: 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-icon {
fill: currentColor;
margin-right: 10px;
vertical-align: middle;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-deleted {
color: #c33;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-added {
color: #399839;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-changed {
color: #d0b44c;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-moved {
color: #3572b0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-tag {
background-color: var(--background-primary);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 10px;
margin-left: 5px;
padding: 0 2px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-deleted-tag {
border: 2px solid #c33;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-added-tag {
border: 1px solid #399839;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-changed-tag {
border: 1px solid #d0b44c;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-moved-tag {
border: 1px solid #3572b0;
}
/* ====================== Line Authoring Information ====================== */
.cm-gutterElement.obs-git-blame-gutter {
/* Add background color to spacing inbetween and around the gutter for better aesthetics */
border-width: 0px 2px 0.2px 2px;
border-style: solid;
border-color: var(--background-secondary);
background-color: var(--background-secondary);
}
.cm-gutterElement.obs-git-blame-gutter > div,
.line-author-settings-preview {
/* delegate text color to settings */
color: var(--obs-git-gutter-text);
font-family: monospace;
height: 100%; /* ensure, that age-based background color occupies entire parent */
text-align: right;
padding: 0px 6px 0px 6px;
white-space: pre; /* Keep spaces and do not collapse them. */
}
@media (max-width: 800px) {
/* hide git blame gutter not to superpose text */
.cm-gutterElement.obs-git-blame-gutter {
display: none;
}
}

151
.obsidian/plugins/obsidian-kanban/main.js

File diff suppressed because one or more lines are too long

11
.obsidian/plugins/obsidian-kanban/manifest.json

@ -0,0 +1,11 @@
{
"id": "obsidian-kanban",
"name": "Kanban",
"version": "2.0.51",
"minAppVersion": "1.0.0",
"description": "Create markdown-backed Kanban boards in Obsidian.",
"author": "mgmeyers",
"authorUrl": "https://github.com/mgmeyers/obsidian-kanban",
"helpUrl": "https://publish.obsidian.md/kanban/Obsidian+Kanban+Plugin",
"isDesktopOnly": false
}

1
.obsidian/plugins/obsidian-kanban/styles.css

File diff suppressed because one or more lines are too long

168
.obsidian/workspace.json

@ -0,0 +1,168 @@
{
"main": {
"id": "da3b9acb34a7d997",
"type": "split",
"children": [
{
"id": "c1aae382605179d4",
"type": "tabs",
"children": [
{
"id": "c8b340e1143b88a2",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Links.md",
"mode": "source",
"source": false
}
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "a4cb6d579ea5938b",
"type": "split",
"children": [
{
"id": "b09b072fd2d900c0",
"type": "tabs",
"children": [
{
"id": "247b79e107e8f407",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical"
}
}
},
{
"id": "588e1bb53249145d",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
}
}
},
{
"id": "eb12a6f656f7117c",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {}
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "00a4acb8d9bd63e3",
"type": "split",
"children": [
{
"id": "f106955a7b0f8173",
"type": "tabs",
"children": [
{
"id": "c2de443e174f4663",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "Links.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "56da3dd219ed10dd",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "Links.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "d04410ce7440fca9",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true
}
}
},
{
"id": "938d3fd002c00784",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "Links.md"
}
}
}
]
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
},
"left-ribbon": {
"hiddenItems": {
"switcher:Open quick switcher": false,
"graph:Open graph view": false,
"canvas:Create new canvas": false,
"daily-notes:Open today's daily note": false,
"templates:Insert template": false,
"command-palette:Open command palette": false,
"obsidian-kanban:Create new board": false
}
},
"active": "c8b340e1143b88a2",
"lastOpenFiles": [
"PythonSul 2025/Z. Kanban.md",
"PythonSul 2025/0. Doc.md",
"Links.md",
"PythonSul 2025",
"Images/Pasted image 20240827110604.png",
"Images/Pasted image 20240827105449.png",
"Images/Pasted image 20240827105408.png",
"Images/Sorry, couldn't resist.md",
"Images/Evolution.md",
"Images/Do Not Connect To The Internet.md",
"Images",
"Pages",
"Pages/Server Setup Basics.md",
"Pages/8 versions of UUID and when to use them.md",
"Welcome.md"
]
}

4
Links.md

@ -0,0 +1,4 @@
https://github.com/elastio/bon: `bon` is a Rust crate for generating compile-time-checked builders for functions and structs.
https://github.com/spring-rs/spring-rs: **spring-rs** is a microservice framework written in Rust, similar to SpringBoot in java. **spring-rs** provides an easily extensible plug-in system for integrating excellent projects in the Rust community, such as axum, sqlx, sea-orm, etc.
https://d07riv.github.io/diabloweb/: Run Diablo I in your browser
https://owickstrom.github.io/the-monospace-web/: # The Monospace Web

51
Pages/8 versions of UUID and when to use them.md

@ -0,0 +1,51 @@
[ntietz.com](https://ntietz.com/blog/til-uses-for-the-different-uuid-versions/)
# TIL: 8 versions of UUID and when to use them
3–4 minutes
---
**Saturday, June 29, 2024**
About a month ago[1](about:reader?url=https%3A%2F%2Fntietz.com%2Fblog%2Ftil-uses-for-the-different-uuid-versions%2F#not-today), I was onboarding a friend into one of my side project codebases and she asked me why I was using a particular type of UUID. I'd heard about this type while working on that project, and it's really neat. So instead of hogging that knowledge for just us, here it is: some good uses for different versions of UUID.
## What are the different versions?
Usually when we have multiple numbered versions, the higher numbers are newer and presumed to be better. In contrast, there are 8 UUID versions (v1 through v8) which are different and all defined in [the standard](https://datatracker.ietf.org/doc/html/rfc9562).
Here, I'll provide some explanation of what they are at a high level, linking to the specific section of the RFC in case you want more details.
- [UUID Version 1 (v1)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-1) is generated from timestamp, monotonic counter, and a MAC address.
- [UUID Version 2 (v2)](https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-2) is reserved for security IDs with no known details[2](about:reader?url=https%3A%2F%2Fntietz.com%2Fblog%2Ftil-uses-for-the-different-uuid-versions%2F#dce).
- [UUID Version 3 (v3)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-3) is generated from MD5 hashes of some data you provide. The RFC suggests DNS and URLs among the candidates for data.
- [UUID Version 4 (v4)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-4) is generated from entirely random data. This is probably what most people think of and run into with UUIDs.
- [UUID Version 5 (v5)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-5) is generated from SHA1 hahes of some data you provide. As with v3, the RFC suggests DNS or URLs as candidates.
- [UUID Version 6 (v6)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-6) is generated from timestamp, monotonic counter, and a MAC address. These are the same data as Version 1, but they change the order so that sorting them will sort by creation time.
- [UUID Version 7 (v7)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7) is generated from a timestamp and random data.
- [UUID Version 8 (v8)](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-8) is entirely custom (besides the required version/variant fields that all versions contain).
## When should you use them?
With eight different versions, which should you use? There are a few common use cases that dictate which you should use, and some have been replaced by others.
You'll usually be picking between two of them: v4 or v7. There are also some occasions to pick v5 or v8.
- Use v4 when you just want a random ID. _This is a good default choice._
- Use v7 if you're using the ID in a context where you want to be able to sort. For example, consider using v7 if you are using UUIDs as database keys.
- v5 or v8 are used if you have your own data you want in the UUID, but generally, you will know if you need it.
What about the other ones?
- [Per the RFC](https://www.rfc-editor.org/rfc/rfc9562.html#section-5.7-4), v7 improves on v1 and v6 and should be used over those if possible. So you usually won't want v1 or v6. If you do want one of those, you _can_ use v6.
- v2 is reserved for unspecified security things. If you _are_ using these, you probably can't tell me or anyone else about it, and you're probably not reading this post to figure out more about them.
- v3 is superceded by v5, which uses a stronger hash. This one is one where you probably _know_ if you need it.
---
---
If this post was enjoyable or useful for you, **please share it!** If you have comments, questions, or feedback, you can email [my personal email](mailto:me@ntietz.com). To get new posts and support my work, subscribe to the [newsletter](https://ntietz.com/newsletter/). There is also an [RSS feed](https://ntietz.com/atom.xml).
Want to become a better programmer? [Join the Recurse Center!](https://www.recurse.com/scout/click?t=c9a1a9e2e7a2ffefd4af20020b4af1e6)
Want to hire great programmers? [Hire via Recurse Center!](https://recurse.com/hire?utm_source=ntietz&utm_medium=blog)

514
Pages/Server Setup Basics.md

@ -0,0 +1,514 @@
[becomesovran.com](https://becomesovran.com/blog/server-setup-basics.html)
# Server Setup Basics
Enki 13 Aug 2024
28–36 minutes
---
This is a post I've been meaning to do for a while. While it's simple to explain how to set up an app for self-hosting, it's pointless to host an app on a weak foundation. It's a massive pain in my ass to start every how to with a section on server setup, so I'm also making this post for myself as a reference on how I like to set up a server for apps I'm hosting. I'll start with basic stuff like proper login with SSH and non-root user set up and making users for each app. I'll also touch on NGINX setup, some quality of life tools that make server management easier, log management and basic network security.
- [SSH](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#ssh)
- [Users](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#users)
- [Logs](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#logs)
- [Backups](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#backups)
- [Basic Network Safety](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#network)
- [NGINX](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#nginx)
- [Quality of Life Tools](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#qol)
- [DNS](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#dns)
- [Docker](about:reader?url=https%3A%2F%2Fbecomesovran.com%2Fblog%2Fserver-setup-basics.html#docker)
##
SSH
First is login. You’ll need a way to access your device securely. Don't even mess with username and password. You want to use SSH (Secure Shell) and make sure that SSH is the only way to log in. To do that, you’ll need an SSH key and a new user account. On a newly provisioned VPS, you'll be logged in as root, and you want to protect the root account. First off on the VPS or remote machine make a new regular user with and add them to the “sudo” group with:
```
sudo adduser newuser
sudo usermod -aG sudo newuser
```
Now on your local machine run:
```
ssh-keygen -t ed25519 -C "your_email@example.com"
```
Follow the instructions, it should ask you where you want to save the file and if you want a password or not. Make sure you set a string one. To copy the public key over to your server run on your local machine:
```
ssh-copy-id -i ~/.ssh/id_ed25519.pub newuser@your_server_ip
```
Keep in mind newuser@your-server-ip is the username and the remote device you are trying to copy your public key into. When you get prompted for a password, it will be the password for the account on the remote device, NOT the password you just made for the SSH key. Once verified, it will copy over the public key, and you can now log in Via SSH. To turn off username and password login, type in:
```
sudo nano /etc/ssh/sshd_config
```
Find these values and set them as you see them here.
```
Port 2222 # Change default port (use a number between 1024 and 65535)
PermitRootLogin no # Disable root login
PasswordAuthentication no # Disable password authentication
PubkeyAuthentication yes # Enable public key authentication
AuthorizedKeysFile .ssh/authorized_keys # Specify authorized_keys file location
AllowUsers newuser # Only allow specific users to login
```
This disallows every login method besides SSH under the user you copied your public key to. Stops login as Root and only allows the user you specify to log in. Hit CTL+S to save and CTL+x to get out of the file editor. Restart SSH:
```
sudo service ssh restart
```
This might boot you out of the session. If it does, this is a good time to test the other login methods to see if they are declined before continuing. Also, it should go without saying, but you need to keep the private key safe and if you lose it you will not be able to get in remotely anymore.You can further lock down your login with:
```
Protocol 2 # Use only SSH protocol version 2
MaxAuthTries 3 # Limit authentication attempts
ClientAliveInterval 300 # Client alive interval in seconds
ClientAliveCountMax 2 # Maximum client alive count
```
Now, let's dive into users a bit more and see how we can leverage them for a bit of organization and security.
##
Users
Users are important when it comes to managing a Linux server. There is an idea in server management called the “Principle of The Least Privilege” this basically means that you want to give an app or process the minimum amount of privileges that it needs to do its job. Root has unlimited power, and no app really needs this. Making a user for apps that you're running accomplishes a few things. It can limit potential damage if an application you are running is compromised. It adds isolation when running more than one app, it helps with auditing so you know what app is using what system resources.
In short, users are a great way of helping organize your system and helps you troubleshoot if and when things go wrong. To add a new user, run:
```
sudo useradd -rms /usr/sbin/nologin -c "a comment" youruser
```
This command makes a user and gives them a home directory for app data but does not allow login as the user. The -c flag is optional, but It's nice to know what the user is for, like “Running Nextcloud” or whatever. Clone app files into the /opt directory with:
```
sudo mkdir /opt/myapp
```
This command makes a user and gives them a home directory for app data but does not allow login as the user. The -c flag is optional, but It's nice to know what the user is for, like “Running Nextcloud” or whatever. Clone app files into the /opt directory with:
```
sudo chown appuser:appuser /opt/myapp
```
Ok, with this your login is locked down, and you should have a decent idea about how to use users. Next is logs.
## **
Logs
**
Logs are crucial to system administration. They keep track of system health, help troubleshoot issues and detect threats. So you want to set up proper log rotation so they do not take up too much space on your system, plus are easier to read and manage. To set up proper log rotation, you want to edit the logrotate.conf file located in /etc. Individual application configurations are typically stored in /etc/logrotate.d/, so an example configuration for NGINX would look like:
```
/var/log/nginx/*.log {
weekly
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
```
This configuration rotates logs weekly, keeps 52 weeks of logs, compresses old logs, makes new logs with the right permissions and then signals NGINX to reopen log files after rotation. You can test it with:
```
sudo logrotate -d /etc/logrotate.conf
```
This will show what it will do without actually rotating logs. With this all set up, you can start to do more advanced stuff like triggering alerts based on log entries. Now this is good for a single server but if you manage more than one server it's a good idea to look into tools like Grafana Loki, Graylog and Fluentd. I won't go into detail here, but if you're looking to up your log game, these a decent place to start.
## **
Backups
**
Backups, and more importantly, testing your backups, are extremely important in server management. Remember: a backup is not a backup unless you test it. Untested backups are essentially useless.
There are three main types of backups. Full, Differential, Incremental. Full backups are a complete copy of all data on a disk. Takes the most resources, but is the easiest to restore from. Differential backups back up all the changes since the last full backup, it's a middle ground strategy for backups on both space and restoration speed. An incremental backup backs up data that was changed since the last backup, this is the fastest backup option but can be the most complex to restore.
I think of it like this. I use incremental backups for things like photos and documents or project files and folders that get edited a lot. I'll use a full backup for backing up and entire server or disk. Differential backups Ill use for backing up full folders like /etc, /opt and log folders.
Now what about storage? If you follow the 3-2-1 rule, you will be golden. 3 copies of your data, 2 storage types, and 1 offsite backup. I'd say if this seems like too much, the “offsite” storage is the most important and not one to skip. In case of a catastrophic meltdown, having a hard disk with your backups is invaluable. Offsite / offline backups can also save your ass from ransomware. So keep that in mind. There is a huge amount of backup software out there. [This link](https://github.com/awesome-foss/awesome-sysadmin#backups) is for exploring some more professional backup tools. [This link](https://github.com/awesome-selfhosted/awesome-selfhosted?tab=readme-ov-file#file-transfer--synchronization) has file sync, transfer and could storage solutions. I use a combo of sync-thing, Borg backup and good old-fashioned FTP.
Remember, that backup, logs and server monitoring is an evolving process based on your needs. The specific strategy you implement should be tailored to your needs and the criticality of your data.
## **
Basic Network Safety
**
The next step in securing a server is to lock down ports that need don’t need to be exposed to the internet and banning things that try to log in when they should not. UFW and Fail2Ban are two tools that are in widespread use for this. They are simple and easy to use, UFW lets you set traffic rules for ports and Fail2Ban will ban and IP address when it knocks on a port they should not be or if they fail to log in after some predefined rules. UFW or uncomplicated firewall often comes preinstalled on a lot of VPS services, same with Fail2Ban, but if you are on a new machine and you're unsure, run:
```
sudo apt install ufw
sudo apt install fail2ban
```
### **
UFW**
We will worry about Fail2Ban later, for now let's focus on UFW setup. First run some default policys with:
```
sudo ufw default deny incoming
sudo ufw allow outgoing
```
This is considered best practice, as it follows the “the least privileges” idea I touched on earlier. It reduces attack surface on your machine and gives you precise control over what you do expose. In short, this configuration creates a balance between security and functionality. Your server can reach out to the internet as needed, but external entities can only connect to your server in ways you've explicitly allowed. Now let's allow some stuff in.
```
sudo ufw allow ssh
sudo ufw allow 80
sudo ufw allow 443
```
If you are going to be running a web server, you need port 80 and port 443 open. 80 is HTTP and 443 is HTTPS. By default, port 22 is SSH, if you changed this you need to specify the port instead of using the “allow ssh” command. Here are some other useful commands:
```
#List rules with numbers:
sudo ufw status numbered
#Delete by number:
sudo ufw delete NUMBER
#Delete by rule specification:
sudo ufw delete allow 80
#You can allow connections from specific IP addresses:
sudo ufw allow from 192.168.1.100
#You can also only allow an IP to connect to a specfic port with:
sudo ufw allow from 192.168.1.100 to any port 22
#If you neeed to allow a range of ports:
sudo ufw allow 6000:6007/tcp
#To further protect from brut force attacks you can rate limit specific ports with:
sudo ufw limit ssh
#This would limit port 22 to 6 connections in 30 seconds from a single IP. To see the status of the firewall you can use:
#Adding this goves you more info
sudo ufw status verbose
#and to reset incase you need to start over:
sudo ufw reset
#and to enable and disable:
sudo ufw enable
sudo ufw disable
#finaly to enable logging and adjusting the log level:
sudo ufw logging on
sudo ufw logging medium # levels are low, medium, high, full
```
On to Fail2Ban now.
### **
Fail2Ban**
The main configuration is located in /etc/fail2ban/jail.conf, but it's recommended to create a local configuration file:
```
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
```
There are some basic settings in the [DEFAULT] section of the jail.local section those are:
```
bantime = 10m
findtime = 10m
maxretry = 5
```
Ban time is how long an IP is banned. Find time is the time frame in witch Fail2Ban looks for repeated failure, and max retry is the number of failures before an IP is banned. You can tune these as you see fit. There are also custom jails you can set, Fail2Ban also supports jails for commonly used services like SSH. There are even more steps you can take, but I think this covers the basics.
### **
NGINX
**
There are a small mess of web servers out there that you can use. Apache, Caddy, nginx, IIS to name a few. I use Nginx. It's what I know, and it works really damn well. Nginx (pronounced engine-x) is a web server, reverse proxy, and load balancer. As a web server, it excels at serving static content and can handle loads of concurrent connections with fairly low resource usage. As a reverse proxy, it can sit in front of your application servers and forward traffic to them while enchaining the apps' security. Its load balancing aspects can effectively balance traffic between servers, improving reliability and scalability.
When installed via apt, the default location for nginx is /etc/nginx/ the nginx.conf is mostly used for global server configuration and includes filed from the /etc/nginx/sites-enabled folder. This modular structure allows for easy management of multiple sites. Two folders to be aware of are the sites-enabled folder and the sites-available folders. You can think of the sites available as a staging place to test your site configurations, while the sites enabled is for live sites and apps. A common practice is to set up and test your configuration in the sites in the sites available, then when you're ready to go live and get an SSL cert, you link the file to the sites-enabled folder. You do that with:
```
ln -s /etc/nginx/sites-available/yoursitefile /etc/nginx/sites-enabled
```
Then reload nginx and double check nginx status with:
```
sudo systemctl reload nginx
sudo systemctl status nginx
```
Your site should be live now.
Below, I’ll show you some boilerplate Nginx site configurations. Be sure to look into your app or sites needs as these are just starting points. For static sites, this is a decent starting point. 
Basic Static Website Configuration:
```
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Logging
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;
# SSL configuration (uncomment after running Certbot)
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Certbot will add its own SSL certificate paths
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}
```
Proxy Pass Configuration:
```
server {
listen 80;
listen [::]:80;
server_name app.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Logging
access_log /var/log/nginx/app.example.com.access.log;
error_log /var/log/nginx/app.example.com.error.log warn;
# SSL configuration (uncomment after running Certbot)
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Certbot will add its own SSL certificate paths
# ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
}
```
WebSocket Upgrade Configuration:
```
server {
listen 80;
listen [::]:80;
server_name ws.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# WebSocket timeout settings
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# Logging
access_log /var/log/nginx/ws.example.com.access.log;
error_log /var/log/nginx/ws.example.com.error.log warn;
# SSL configuration (uncomment after running Certbot)
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Certbot will add its own SSL certificate paths
# ssl_certificate /etc/letsencrypt/live/ws.example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/ws.example.com/privkey.pem;
}
```
The basic configuration is for serving a simple static site. It specifies the domain name, listens on port 80 for both IPv4 and IPv6, sets the root directory for the site, configures error handling with try_files, adds some basic headers that protect from common web vulnerabilities, sets up logging for access and errors and includes a section for SSL that is commented out. Most of the SSL config will be handled by certbot, but there are a few lines in there that add some SSL security that can be uncommented after certbot is ran.
The proxy pass configuration is similar to the basic configuration, but instead of serving files directly, it proxies requests to a local application (in this case, running on port 3000).
The third configuration file is geared towards apps that need website connections, it's a lot like the proxy pass configuration with some changes to allow web sockets.  
Ok, any bit about web servers is not really complete without talking about SSL. For casual use, certbot is a pleb's best friend. It's free, it is fast, and it fucking works. I use the python version of certbot. You can install that with:  
```
sudo apt install certbot python3-certbot-nginx
```
Once it's installed you can simply run “certbot” in your terminal, this will detect the configs in your sites-enabled folder and ask what you want to do (renew, reissue, etc…). Follow the walk-through, certbot gives you It's pretty straight forward.
So nowadays certbot when getting a new cert will set up auto-renew for you, so it's a sit-and-forget kinda task. But to make sure it worked you can run:
```
sudo systemctl status certbot.timer
```
if this is up and running, you should be good to go if you're using systemd.
## **
Quality Of Life Tools
**
On the topic of tools that make managing your system easier, I'm going to present some tools I use on my servers that I think make management just a bit nicer. Not going to do a deep dive on any tool. All of these are optional and in no particular order. A lot of these I found on the site [terminal trove](https://terminaltrove.com/), a great site to browse if you're a terminal junkie like me. 
First tool, [Btop](https://terminaltrove.com/btop/) this is in my personal must haves list. Btop is a terminal monitor of resources. It shows you real time visuals of usage stats for your box’s CPU, RAM, disks, network and running possesses it's written in C++ and can be installed via most package managers. 
For servers that have a lot of outside connections, i.e. a nostr relay, a tool like [Neoss](https://terminaltrove.com/neoss/) is helpful. Neoss aims to replace usual ss command for basic usage. It provides a list of in use TCP and UDP sockets with their respective stats. Its main advantage over SS raw output is its clear and simple TUI (terminal user interface) that allows you to sort, refresh and navigate what is connected to your machine. It's installed Via NPM, meaning you need JavaScript installed.
[GoAccess](https://github.com/allinurl/goaccess) is a terminal based log analyzer for web servers. It's great for a quick real time look at logs while in the terminal, but it can also generate real time HTML, JSON, and CSV reports. GoAccess can be installed via most package managers, works on all platforms. 
Next on the list is [MC or “midnight commander”](https://terminaltrove.com/mc/) Its a powerful text based file manager with a two panel display and lots of features for manipulating files and directories. It's also cross-platform and can be installed via most package managers. 
In the same thread of server file management is [NCDU](https://dev.yorhel.nl/ncdu). This one is in my must-have list. It is a disk usage analyzer that is designed to find space hogs. It's fast and very simple to use. It can be installed on most systems and package managers. Windows will need Linux subsystems installed to use it. 
Hopefully you find some use out of these. The last topic I'd like to touch on is DNS it's a bit topic, so I'm not going to do a massive deep dive, but if you're self-hosting it helps to have some of the basics of DNS down. ing doesn’t work.
## **
DNS
**
DNS or The Domain Name System is a core part of how the internet as we know it works. Love it or hate it, it's what we have to work with If you want to be accessible to the wider internet. (I dislike what it currently is it, but I’m not opening that can of worms here.) Basically, Think of DNS like a phone book. It’s what allows you to type duckduckgo.com instead of “52.250.42.157” every time you need to search the internet. It translates something easy for humans to remember into the information needed by computers to actually reach “duckduckgo.com”
If you're hosting on a VPS, the only thing you really need to know is to know how to point an A record at your server's IP after you decide on a domain to use. Pretty much all VPS hosts can give you a static IP, so that's mostly a set and forget type deal.
Hosting from home presents some challenges. One prominent one is (and a valid question that I often hear) not having a static IP address. Nowadays with the number of devices online needing IP addresses we do a lot of juggling, and most IP addresses are assigned dynamically unless you pay for it from your ISP.  But there is a solution. The answer to this is called Dynamic DNS or DDNS. This allows automatic updating of DNS servers every time an IP address changes. There are a mess of ways to set up dynamic DNS. You can host your own service or use a host. [Here is a link](https://dynamic.domains/dynamic-dns/providers-list/default.aspx) with some hosts and projects to check out.
In a nutshell, it works like so. You chose a provider or set up your own. You get a domain, install the client on your home router or server and the client periodically checks to see if the IP address has changed, if so it updates your DNS record for that domain. 
## **
Docker
**
I'm not gonna cover how to install docker here. It's best to follow [the official installation](https://docs.docker.com/engine/install/debian/) guide anyway. But I want to touch on a few things. First off, docker is useful as hell for testing new apps. But that's about as far as I take it. I personally do not like using docker all that much, and where possible run applications directly. Here are some pros and cons to keep in mind.
### **Docker Pros**
Consistency is a big one it can make things more constant between development, testing, and deploying if your system can run docker you can run most docker apps. It can help with isolation, reducing conflicts between apps. In some cases it can help with efficiency as it takes less resources than traditional VM’s. It can help with scaling as it's pretty easy to spin up more containers and the microservice architecture can be useful because you can break down an application into smaller manageable services, allowing for independent scaling of said services. Lastly the community is large, so the documentation is good, and community support is always helpful, plus there is a wide range of ready to go docker images for deployment.
### **Docker Cons**
I’ll start with overhead. While it's better than a traditional VM, it uses more resources than running something directly on the host, and I/O operations can be slower. The fact that docker shares the system's kernel means that a compromised app could affect the system. Persistent data is doable but adds a layer of complexity that can cause data loss with new users, it also makes backups more complex. Networking can also be more complex with docker, making it not as straightforward. It's also good to note that if you use UFW or firewalld for a firewall, docker bypasses those rules. Docker is only compatible with iptables. Also, while a well managed docker container can help manage server resources, an improperly manged on can be detrimental to resources as well. Containers can get too large, effecting disk size, and misconfiguration can use too many of your servers resources. It also adds extra layers of complexity when monitoring and debugging applications, especially across multiple containers.
At the end of the day, it's your system. But I wanted to lay out some pros and cons when it comes to using Docker. Moving on. 
## **
Wrap Up
**
Well, that about does it for the basics of server setup and tools. There is a [a script that I wrote](https://git.sovbit.dev/Enki/sovran-scripts) that will do most of this for you. I wrote it to make my own server setup faster. You can get that here, it includes all of my must-haves and does some basic configuration. Tweak it to your own needs, and as always stay safe out there and ping me on nostr or simplex if you have questions or if I fucked something up in this post.

142
PythonSul 2025/0. Doc.md

@ -0,0 +1,142 @@
# Definição do evento
(PS24 = PythonSul 2024)
## Data
Pessoal (Ana Dulce, Érico) tem pedido no primeiro semestre, precisaríamos ver qual a melhor data (algo que não seja na época de chuvas próximo a agosto). Também não tem como pensar em algo como "fevereiro/março" por falta de tempo pra fazer tudo.
Os demais Py-Regionais estão todos tentando fechar datas em maio, junho e julho. São 5 regionais (PyCerrado, PyNordeste, PyNorte, PySudeste e PySul) e mais o evento nacional (PythonBrasil).
PythonBrasil provavelmente vai cair em Outubro, e a idéia entre os kahunas dos regionais é que podemos fazer os regionais "brigarem" entre si com eventos próximos, mas não ficar muito próximo da PythonBrasil, até para servir de "ponta de lança" para o nacional -- se o pessoal curtir o regional, vai se sentir motivado a ir no nacional.
Ana Dulce sugeriu ter um prazo de 3 meses antes do nacional, pro pessoal reagrupar recursos. Assim, teríamos até alguma data em julho para o evento. Temos que considerar questões climáticas -- tirando os "abusos" que tem acontecido -- desconsiderando épocas de muito frio para não assustar os visitantes.
# Equipe de Organização
Eu acabei ficando de Kahuna, mas preciso de, pelo menos:
- 1 pessoa criativa
- Alguém mais espontâneo (estou considerando o Perceu para esse "cargo", mas não falei com ele ainda)
Para identificação do pessoal da organização, eu pensei em usar lenços de pescoço, como é a tradição gaúcha, só que ao invés de branco e vermelho, termos lenços azuis e amarelos (sem distinção de cor).
A [documentação de eventos](https://manual.pythonbrasil.org.br/organizacao/index.html) coloca pelo menos 8 times:
## Captação de Recursos
**Atribuições**: Plano de patrocínio, patrocínios, parcerias (restaurantes, hotéis), ingressos, check-in.
Membros:
### Plano de Patrocínio
**Atribuições**: Identidade visual do plano de patrocínio, redes sociais, postagens.
Talita me passou o contato da Bruna, que trabalhou no PyCaixas. Eu comentei que sabia de nada do que fazer, e por isso passei por esse documento.
Pessoalmente, eu pensei em usar o mesmo esquema de cores do Python (azul e amarelo), e tentar ter algo relacionado com o que passamos nas enchentes, como o [Cavalo Caramelo](https://pt.wikipedia.org/wiki/Caramelo_(cavalo)). Talita me avisou pra tentar ficar longe de temas farroupilhas (por motivos de não ser muito legal para comunidades indígenas) e cavalos caem nessa categoria. Pensando em Porto Alegre, poderíamos ter algo como a [Ponte Elevadiça](https://pt.dreamstime.com/imagens-de-stock-ponte-de-porto-alegre-e-rio-de-guaiba-image26856824) ou o [prédio da CAFF](http://poafilmcommission.portoalegre.rs.gov.br/sites/default/files/usu_img/locacoes/A%C3%A9rea%203%20-%20Centro%20Administrativo%20Fernando%20Ferrari%20e%20Monumento%20aos%20A%C3%A7orianos.jpg) -- embora esse último já tenha sido usado pacas.
### Leads Patrocínio
- Azion
- CWI
## Financeiro
**Atribuições**: Fluxo de caixa, previsão de custos, pedidos de notas, reembolso, relacionamento com APyB, ferramenta dos ingressos.
Membros:
## Marketing/Publicidade
**Atribuições**: Implementar a identidade visual, gerenciar redes sociais, mocks site/redes/lonas/banners/paineis/adesivos/camisetas.
Membros:
## Infraestrutura
**Atribuições**: local do evento, equipe de limpeza, internet, fotografia, som, filmagem/transmissão, tradução simultânea, equipe de libras (PS24 não teve)
Membros:
### Local
- UNISINOS, Av Nilo Peçanha, 1600: Próximo ao shopping, quase caminho direto pra cidade baixa/4o distrito. Proximidade do Holiday Inn (hotel) facilitaria a vida de quem vem de fora.
Ílson Bolzan tem um possível contato.
- Instituto Caldera, R. Frederico Mentz, 1606: Espaço especializado em coisas de tecnologia. Requer aluguel, mas o maior espaço é para 200 pessoas (PythonSul 2024 teve 375 inscritos -- não necessariamente 375 pessoas ao mesmo tempo).
- Tecnopuc, Av. Ipiranga, 6681: Dentro da PUC, teríamos que ver se eles querem participar e/ou procurar alguma das empresas de lá (como a Thoughtworks). Fica distante de um monte de coisa, principalmente hotéis, mas tem os "botequinhos" próximos.
- ~~Auditório Araujo Viana, Parque Farroupilha, 685: Local usado pelo BrazilJS. Possivelmente precisariamos, além de alugar o local, procurar empresa para montar a estrutura.~~ Capacidade para 3000 pessoas é demais para o que precisamos.
### Fotos
Acho que dá pra chamar o Tomkiel e ele vem fácil (dependendo da data).
### Transmissão
### Gravação
### Internet
## Experiência de Evento
**Atribuições**: Coffee break, organizar lightning talks, guarda volumes, espaço relax, guia da cidade.
PS24 teve um "silent space" pra quem queria ter uma folga e/ou era neurodivergente e precisava dar uma desligada. Seria interessante termos algo parecido.
Membros:
### PyBar
Um ponto importante pra levantar aqui: A Belisa comentou que PyBar tem dado muito foco em "encher a cara" e que isso pode levar algumas pessoas a terem problemas e/ou se sentirem excluídas por não beber alcool (Jeff/Badtux fez um comentário parecido uma vez, dizendo que ele tem que cuidar pra se maneirar nos vídeos pro pessoal não achar que tem que beber pra programar). Assim, é importante que a gente procure lugares onde "dê" pra beber, e não lugares onde "é" pra beber.
Por exemplo, podemos colocar o Cavanhas como um dos lugares pra se encontrar, já que o ponto em si é mais de xis e baurú do que especificamente para beber (sem contar que promover xis do Rio Grande do Sul era umas). O Dado Bier também é uma opção, já que apesar do "bier" no nome, eles tem uma pegada mais "fora do trabalho" do que realmente encher a cara. (Faltaria 1 dia de evento e o PyBar da véspera.)
### "Trucks"
Uma coisa que pareceu interessante para a organização do PS24 foi o estande de tatuagem (que tava de graça). Poderíamos pensar em outras "carrocinhas" (ou "trucks" hoje em dia) que poderiam vir e prover serviços para quem estiver no evento.
Vários eventos de moto -- como o Moto Custom Total -- tem pelo menos um pessoal de tatuagem, e daria para verificar em eventos passados quem foi que apareceu e verificar a possibilidade deles participarem. _Depende da definição de local._
### Demonstração Regional
PS24 teve uma apresentação do grupo local de Bernunça/Boi de Mamão. Seria legal ter alguma coisa também regional.
Pensei em algo como demonstração de chula, mas é muito batido. O que talvez fosse interessante seria um duelo de gaitas (imagine o Borghettinho tocando). Algo instrumental. Poderíamos verficar isso com algum CTG. _Depende da deinição de local, pois pode ser que o local não permite esse tipo de evento._
## Administração
**Atribuições**: Tomadas de decisões.
Membros:
- Julio Biason
## Técnico
**Atribuições**: Site (atualizando com novas informações), sistema de notificação, integração sistema de ingressos.
PS24 usou o Sympla, que controlou tanto os ingressos quanto o check-in.
Membros:
## Conteúdo
**Atribuições**: Submissão e escolha das atividades.
Membros:
### Keynotes
- Felipe de Morais (sugestão): Desenvolvedor da Thoughworks.
- Andressa Rocha ("passalahnorh", sugestão): Andressa vive ocupada com vários eventos, mas talvez ela consiga dar um pulo na PythonSul. Entretanto, já foi keynote da PythonBrasil em Caxias e seria abuso demais pedir pra ela vir.
- Hisham Muhammad (sugestão): Desenvolvedor do Luarocks, Teal e Htop. Poderia falar sobre tipos, já que o último projeto é um sistema de tipos para Lua (e falar da linguagem como linguagem convidada).
# Atividades
- [ ] Definir datas
- [ ] Decidir local
- [ ] Procurar alguém da UNISINOS
- [ ] Conversar com Bruna sobre artes
- [ ] Conseguir contrato
- [ ] Procurar local que venda lenços (https://www.republicasul.com.br/tradicionais_trama_republicasul.php => Caro, mas tem azul e amarelo)

29
PythonSul 2025/Z. Kanban.md

@ -0,0 +1,29 @@
---
kanban-plugin: board
---
## A fazer
- [ ] Definir datas
- [ ] Verificar possibilidade de fazer na UNISINOS
- [ ] Fazer contrato de artes
- [ ] Compra dos lenços
## Bloqueado
## Feito
%% kanban:settings
```
{"kanban-plugin":"board","list-collapse":[false,false,false]}
```
%%
Loading…
Cancel
Save