aboutsummaryrefslogtreecommitdiff
path: root/public/debian-based-riced-up-distribution-for-developers-and-devops-folks.html
diff options
context:
space:
mode:
Diffstat (limited to 'public/debian-based-riced-up-distribution-for-developers-and-devops-folks.html')
-rwxr-xr-xpublic/debian-based-riced-up-distribution-for-developers-and-devops-folks.html139
1 files changed, 139 insertions, 0 deletions
diff --git a/public/debian-based-riced-up-distribution-for-developers-and-devops-folks.html b/public/debian-based-riced-up-distribution-for-developers-and-devops-folks.html
new file mode 100755
index 0000000..df58abf
--- /dev/null
+++ b/public/debian-based-riced-up-distribution-for-developers-and-devops-folks.html
@@ -0,0 +1,139 @@
1<!doctype html><html lang=en-us><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><link href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL69vf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv76+/8LBwQkAAAAAAAAAAAAAAAC+vb3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+9vf/Bv78JAAAAAAAAAAAAAAAAu7q6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7ubr/vr29CAAAAAAAAAAAy8nJAZ6foP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnqGj/6GipAoAAAAAHLjU/xcXHf/BwsL/I8XY/yPK3v8XGiD/IbjL/yPF2f8XGiD/Fxkf/yLF2f8gnK3/Fxog/62ztv8fwNf/FRcd/x271v8mz93/GRsi/xkXHf8p097/GiIp/xobIv8p0t3/KdPe/xocIv8fYmr/KNPe/xoZH/8aHCL/J87c/xy81/8VFxz/IsPZ/8zS0/8XGiD/Ir/R/yPH2/8XGiD/Fxkf/yPH2/8dd4T/GBog/yPJ3f8jyNr/uru9/xcUGv8cudb/EhITDKi5vRKlvMP/RUpOERwcHRAdOj4QHTk8EBwdHRAdNTgQHTo/EBwcHRAcHB0QSGduEKW4vf+koqQfHzg+EBqz0ewSFRv7EyMr/xq51vsTERb7ExUb+xq41fsau9j7ExUb+xiPp/sZudb7ExUb+xMVG/sZuNX/GKvI/BIUGfMdvdn/IrfL/xcaIP8n1eb/J9Dh/xkcIf8ZGR7/J8/f/xxCSv8ZGyH/J9Dg/ybQ4P8ZHCL/FSQs/yPK3/8UExj/GE1b/ybS5P8ZGB7/Ghwj/ynW5P8p2Ob/Ghwi/yWrtv8p1eH/Ghwi/xocIv8p1uT/J8XT/xkcIv8m1un/Hb7d/xUYH/8hzOr/HtHu/xcaIf8XGB//I8vi/xgxOv8XGSD/I8rg/yPK4P8XGiD/GUFL/yPP6f8SERj/Fhkh/x3A4f8AAAAAJ2f9/ydr//8mZPH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlYu38J2v//ydo/f8AAAAAAAAAAAd8/fkFqf//Iob8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMY39awWr//8FfP3/AAAAAAAAAAAFm/7/SfD//wR+/f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOB/f9B7v//BaX+/wAAAAAAAAAAQ878SAyZ/v9n1v4KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu9v8DDJb+/z3N/XgAAAAA3/sAAN/7AADf+wAA3/sAAAAAAAAAAAAAAAAAAN/7AAAAAAAAAAAAAAAAAAAAAAAAj/EAAI/5AACP8QAA3/sAAA==" rel=icon type=image/x-icon><title>Debian based riced up distribution for Developers and DevOps folks</title><meta name=description content="IntroductionI have been using Ubuntu for quite a longtime now."><link rel=alternate type=application/rss+xml title="Mitja Felicijan's posts" href=https://mitjafelicijan.com/index.xml><link rel=alternate type=application/rss+xml title="Mitja Felicijan's notes" href=https://mitjafelicijan.com/notes.xml><style>body{padding:1rem;max-width:760px;background:#fff;font-family:sans-serif;line-height:1.35rem;font-size:16px;margin:0 auto}hr{margin-block-start:1.5rem}h1,h2,h3{line-height:initial}h1{font-size:xx-large}footer{margin-block-start:2rem}cap{text-transform:capitalize}table{max-width:100%;width:100%;border-collapse:separate;border-spacing:2px;border:1px solid #000;border-left:1px solid #999;border-top:1px solid #999}blockquote{font-style:italic}table thead{background:#eee}ul.list li{padding:.2em 0}ul{line-height:1.4em}td,th{border:1px solid #000;padding:4px;border-right:1px solid #999;border-bottom:1px solid #999;text-align:left}pre{text-wrap:nowrap;overflow-x:auto;padding:0 1em;border:1px solid #dcdcdc}code{padding:0 3px;font-size:14px;border:0}pre code{line-height:1.3em}pre,code,pre *,code *{font-family:monospace}figure{margin-inline-start:0;margin-inline-end:0}figcaption{text-align:center}figcaption p{margin:.3em 0 0}img,video,audio{max-width:100%}header{display:flex;flex-direction:row;gap:3rem}nav{display:flex;gap:.75rem}nav.main{flex-grow:1}.pstatus-orange{background:gold}.pstatus-green{background:#9acd32}.pstatus-red{background:#cd5c5c}@media only screen and (max-width:600px){body{padding:15px}header{flex-direction:column;gap:1rem}a{word-wrap:break-word}}</style><header><nav class=main itemscope itemtype=http://schema.org/SiteNavigationElement role=toolbar><a href=/>Home</a>
2<a href=https://git.mitjafelicijan.com/ target=_blank>Git</a>
3<a href=https://files.mitjafelicijan.com/ target=_blank>Files</a>
4<a href=/radio.pls target=_blank>Radio</a>
5<a href=/mitjafelicijan.pgp.pub.txt target=_blank>PGP</a>
6<a href=/curriculum-vitae.html>CV</a>
7<a href=/index.xml target=_blank>RSS</a></nav></header><main role=main><article itemtype=http://schema.org/Article><h1 itemtype=headline>Debian based riced up distribution for Developers and DevOps folks</h1><p><cap>post</cap>, Dec 3, 2021 on <a href=https://mitjafelicijan.com>Mitja Felicijan's blog</a><div><h2 id=introduction>Introduction</h2><p>I have been using <a href=https://ubuntu.com/>Ubuntu</a> for quite a longtime now. I have
8used <a href=https://www.debian.org/>Debian</a> in the past and
9<a href=https://manjaro.org/>Manjaro</a>. Also had <a href=https://archlinux.org/>Arch</a> for
10some time and even ran <a href=https://www.gentoo.org/>Gentoo</a> way back.<p>What I learned from all this is that I prefer running a bit older versions and
11having them be stable than run bleeding edge rolling release. For that reason, I
12stuck with Ubuntu for a couple of years now. I am also at a point in my life
13where I just don't care what is cool or hip anymore. I just want a stable system
14that doesn't get in my way.<p>During all this, I noticed that these distributions were getting very bloated
15and a lot of software got included that I usually uninstall on fresh
16installation. Maybe this is my OCD speaking, but why do I have to give fresh
17installation min 1 GB of ram out of the box just to have a blank screen in front
18of me? I get it, there are many things included in the distro to make my life
19easier. I understand. But at this point I have a feeling that modern Linux
20distributions are becoming similar to <a href=https://devhumor.com/content/uploads/images/August2017/node-modules.jpg>Node.js project with
21node_modules</a>.
22Just a crazy number of packages serving very little or no purpose, just
23supporting other software.<p>I felt I needed a fresh start. To start over with something minimal and clean.
24Something that would put a little more joy into using a computer again.<p>For the first version, I wanted to target the following machines I have at home
25that I want this thing to work on.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span><span style=color:green># My main stationary work machine</span>
26</span></span><span style=display:flex><span>Resolution: 3840x1080 (Super Ultrawide Monitor 32:9)
27</span></span><span style=display:flex><span>CPU: Intel i7-8700 (12) @ 4.600GHz
28</span></span><span style=display:flex><span>GPU: AMD ATI Radeon RX 470/480/570/570X/580/580X/590
29</span></span><span style=display:flex><span>Memory: 32020MiB
30</span></span></code></pre><pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span><span style=color:green># Thinkpad x220 for testing things and goofing around</span>
31</span></span><span style=display:flex><span>Resolution: 1366x768
32</span></span><span style=display:flex><span>CPU: Intel i5-2520M (4) @ 3.200GHz
33</span></span><span style=display:flex><span>GPU: Intel 2nd Generation Core Processor Family
34</span></span><span style=display:flex><span>Memory: 15891MiB
35</span></span></code></pre><h2 id=how-should-i-approach-this>How should I approach this?</h2><p>I knew I wanted to use <a href=https://www.debian.org/CD/netinst/>minimal Debian netinst</a> for the base to give myself a head
36start. No reason to go through changing the installer and also testing all that
37behemoth of a thing. So, some sort of ricing was the only logical option to get
38this thing of the grounds somewhat quickly.<blockquote><p><strong>What is ricing anyway?</strong>
39The term “RICE” stands for Race Inspired Cosmetic Enhancement. A group of
40people (could be one, idk) decided to see if they could tweak their own
41distros like they/others did their cars. This gave rise to a community of
42Linux/Unix enthusiasts trying to make their distros look cooler and better
43than others... For more information, read this article
44<a href=https://pesos.github.io/2020/07/14/what-is-ricing.html>What in the world is ricing!?</a>.</blockquote><p>I didn't want this to just be a set of config files for theming purpose. I
45wanted this to include a set of pre-installed tools and services that are being
46used all the time by a modern developer. Theming is just a tiny part of it.
47Fonts being applied across the distro and things like that.<p>First, I choose terminal installer and left it to load additional components.
48Avoid using graphical installer in this case.<figure><img src=/posts/dfd-rice/install-00.png alt></figure><p>After that I selected hostname and created a normal user and set password for
49that user and root user and choose guided mode for disk partitioning.<figure><img src=/posts/dfd-rice/install-01.png alt></figure><p>I left it run to install all the things required for the base system and opted
50out of scanning additional media for use by the package manager. Those will be
51downloaded from the internet during installation.<figure><img src=/posts/dfd-rice/install-02.png alt></figure><p>I opted out of the popularity contest, and <strong>now comes the important part</strong>.
52Uncheck all the boxes in Software selection and only leave 'standard system
53utilities'. I also left an SSH server, so I was able to log in to the machine
54from my main PC.<figure><img src=/posts/dfd-rice/install-03.png alt></figure><p>At this point, I installed GRUB bootloader on the disk where I installed the
55system.<figure><img src=/posts/dfd-rice/install-04.png alt></figure><p>That concluded the installation of base Debian and after restarting the computer
56I was prompted with the login screen.<figure><img src=/posts/dfd-rice/install-05.png alt></figure><p>Now that I had the base installation, it was time to choose what software do I
57want to include in this so-called distribution. I wanted out of the box
58developer experience, so I had plenty to choose.<p>Let's not waste time and go through the list.<h2 id=desktop-environments>Desktop environments</h2><p>I have been using <a href=https://www.gnome.org/>Gnome</a> for my whole Linux life. From
59version 2 forward. It's been quite a ride. I hated version 3 when it came out
60and replaced version 2. But I got used to it. And now with version 40+ they also
61made couple of changes which I found both frustrating and presently surprised.<p>The amount of vertical space you loose because of the beefy title bars on
62windows is ridiculous. And then in case of
63<a href=https://gnunn1.github.io/tilix-web/>Tilix</a> you also have tabs, and you are
64100px deep. Vertical space is one of the most important things for a
65developer. The more real estate you have, the more code you can have in a
66viewport.<p>But on the other hand, I still love how Gnome feels and looks. I gotta give them
67that. They really are trying to make Gnome feel unified and modern.<p>Regardless of all the nice things Gnome has, I was looking at the tiling window
68managers for some time, but never had the nerve to actually go with it. But now
69was the ideal time to give it a go. No guts, no glory kind of a thing.<p>One of the requirements for me was easy custom layouts because I use a really
70strange monitor with aspect ratio of 32:9. So relying on included layouts most
71of them have is a non-starter.<p>What I was doing in Gnome was having windows in a layout like the diagram
72below. This is my common practice. And if you look at it you can clearly see I
73was replicating tiling window manager setup in Gnome.<figure><img src=/posts/dfd-rice/layout.png alt></figure><p>That made me look into a bunch of tiling window managers and then tested them
74out. Candidates I was looking at were:<ul><li><a href=https://i3wm.org/>i3</a><li><a href=https://github.com/baskerville/bspwm>bspwm</a><li><a href=https://awesomewm.org/index.html>awesome</a><li><a href=https://xmonad.org/>XMonad</a><li><a href=https://swaywm.org/>sway</a><li><a href=http://www.qtile.org/>Qtile</a><li><a href=https://dwm.suckless.org/>dwm</a></ul><p>You can also check article <a href=https://www.tecmint.com/best-tiling-window-managers-for-linux/>13 Best Tiling Window Managers for
75Linux</a> I was
76referencing while testing them out.<p>While all of them provided what I needed, I liked i3 the most. What particular
77caught my eye was the ease to use and tree based layouts which allows flexible
78layouts. I know others can be set up also to have custom layouts other than<br>spiral, dwindle etc. I think i3 is a good entry-level window manager for
79somebody like me.<h2 id=batteries-included>Batteries included</h2><p>The source for the whole thing is located on Github
80<a href=https://github.com/mitjafelicijan/dfd-rice>https://github.com/mitjafelicijan/dfd-rice</a>.<p>Currenly included:<ul><li><code>non-free</code> (enables non-free packages in apt)<li><code>sudo</code> (adds sudo and adds user to sudo group)<li><code>essentials</code> (gcc, htop, zip, curl, etc...)<li><code>wifi</code> (network manager nmtui)<li><code>desktop</code> (i3, dmenu, fonts, configurations)<li><code>pulseaudio</code> (pulseaudio with pavucontrol)<li><code>code-editors</code> (vim, micro, vscode)<li><code>ohmybash</code> (make bash pretty)<li><code>file-managers</code> (mc)<li><code>git-ui</code> (terminal git gui)<li><code>meld</code> (diff tool)<li><code>profiling</code> (kcachegrind, valgrind, strace, ltrace)<li><code>browsers</code> (brave, firefox, chromium)<li>programming languages:<ul><li><code>python</code><li><code>golang</code><li><code>nodejs</code><li><code>rust</code><li><code>nim</code><li><code>php</code><li><code>ruby</code></ul><li><code>docker</code> (with docker-compose)<li><code>ansible</code></ul><p>Install script also allows you to install only specific packages (example for:
81essentials ohmybash docker rust).<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>su - root <span style=color:#a31515>\
82</span></span></span><span style=display:flex><span><span style=color:#a31515></span> bash -c <span style=color:#a31515>&#34;</span><span style=color:#00f>$(</span>wget -q https://raw.github.com/mitjafelicijan/dfd-rice/master/tools/install.sh -O -<span style=color:#00f>)</span><span style=color:#a31515>&#34;</span> -- <span style=color:#a31515>\
83</span></span></span><span style=display:flex><span><span style=color:#a31515></span> essentials ohmybash docker rust
84</span></span></code></pre><p>Currently, most of these recipes use what Debian and this is totally fine with
85me since I never use bleeding edge features of a package. But if something major
86would come to light, I will replace it with a possible compilation script or
87something similar.<p>This is some of the output from the installation script.<figure><img src=/posts/dfd-rice/script.png alt></figure><p>Let's take a look at some examples in the installation script.<h3 id=docker-recipe>Docker recipe</h3><pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span><span style=color:green># docker</span>
88</span></span><span style=display:flex><span>print_header <span style=color:#a31515>&#34;Installing Docker&#34;</span>
89</span></span><span style=display:flex><span>curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --yes --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
90</span></span><span style=display:flex><span>echo <span style=color:#a31515>&#34;deb [arch=</span><span style=color:#00f>$(</span>dpkg --print-architecture<span style=color:#00f>)</span><span style=color:#a31515> signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian </span><span style=color:#00f>$(</span>lsb_release -cs<span style=color:#00f>)</span><span style=color:#a31515> stable&#34;</span> | tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
91</span></span><span style=display:flex><span>apt update
92</span></span><span style=display:flex><span>apt -y install docker-ce docker-ce-cli containerd.io docker-compose
93</span></span><span style=display:flex><span>
94</span></span><span style=display:flex><span>systemctl start docker
95</span></span><span style=display:flex><span>systemctl enable docker
96</span></span><span style=display:flex><span>systemctl status docker --no-pager
97</span></span><span style=display:flex><span>
98</span></span><span style=display:flex><span>/sbin/usermod -aG docker $USERNAME
99</span></span></code></pre><h3 id=making-bash-pretty>Making bash pretty</h3><p>I really like <a href=https://ohmyz.sh/>Oh My Zsh</a>, but I don't like zsh shell. When
100I used it, I constantly needed to be aware of it and running bash scripts was a
101pain. So, I was really delighted when I found out that a version for bash
102existed called <a href=https://ohmybash.nntoan.com/>Oh My Bash</a>. Let's take a look at
103the recipe for installing it.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span><span style=color:green># ohmybash</span>
104</span></span><span style=display:flex><span>print_header <span style=color:#a31515>&#34;Enabling OhMyBash&#34;</span>
105</span></span><span style=display:flex><span>sudo -u $USERNAME sh -c <span style=color:#a31515>&#34;</span><span style=color:#00f>$(</span>curl -fsSL https://raw.github.com/ohmybash/oh-my-bash/master/tools/install.sh<span style=color:#00f>)</span><span style=color:#a31515>&#34;</span> &amp;
106</span></span><span style=display:flex><span>T1=<span style=color:#a31515>${</span>!<span style=color:#a31515>}</span>
107</span></span><span style=display:flex><span>wait <span style=color:#a31515>${</span>T1<span style=color:#a31515>}</span>
108</span></span></code></pre><p>Because OhMyBash does <code>exec bash</code> at the end, this traps our script inside
109another shell and our script cannot continue. For that reason, I executed this
110in background. But that presents a new problem. Because this is executed in
111background, we lose track of progress naturally. And that strange trick with
112<code>T1=${!}</code> and <code>wait ${T1}</code> waits for the background process to finish before
113continuing to another task in bash script.<p>Check <a href=https://www.cloudsavvyit.com/12277/how-to-use-multi-threaded-processing-in-bash-scripts/>Multi-Threaded Processing in Bash Scripts</a>
114for more details.<h2 id=conclusion>Conclusion</h2><p>Take a look at
115<a href=https://github.com/mitjafelicijan/dfd-rice/blob/develop/tools/install.sh>https://github.com/mitjafelicijan/dfd-rice/blob/develop/tools/install.sh</a> script
116to get familiar with it. This is just a first iteration and I will continue to
117update it because I need this in my life.<p>The current version boots in 4s to the login prompt, and after you log in, the
118desktop environment loads in 2s. So, its fast, very fast. And on clean boot, I
119measured ~230 MB of RAM usage.<p>And this is how it looks with two terminals side by side. I really like the
120simplicity and clean interface. I will polish the colors and stuff like that,
121but I really do like the results.<figure><img src=/posts/dfd-rice/desktop.png alt></figure></div></article></main><section><hr><h2>Posts from blogs I follow around the net</h2><ul><li><a href=https://chotrin.org/writing/2023-10-20.html target=_blank rel=noopener>OpenBSD upgrade and fall things.</a><div>Been AFK for a bit. It's autumn and I upgraded this server to OpenBSD 7.4! — <a href=https://chotrin.org>chötrin's wiki.</a><li><a href=https://mirzapandzo.com/next-image-url-parameter-is-valid-but-upstream-response-is-invalid target=_blank rel=noopener>Next/Image "url" parameter is valid but upstream response is invalid</a><div>Getting "url" parameter is valid but upstream response is invalid error with Next/Image on WSL2 — <a href=https://mirzapandzo.com/>Mirza Pandzo's Blog</a><li><a href=https://drewdevault.com/2023/10/13/Going-off-script.html target=_blank rel=noopener>Going off-script</a><div>There is a phenomenon in society which I find quite bizarre. Upon our entry to
122this mortal coil, we are endowed with self-awareness, agency, and free will.
123Each of th… — <a href=https://drewdevault.com>Drew DeVault's blog</a><li><a href=https://solar.lowtechmagazine.com/2023/10/workshop-in-rotterdam-how-to-build-a-bike-generator/ target=_blank rel=noopener>Workshop in Rotterdam: How to Build a Bike Generator</a><div>Afbeelding: Low-tech Magazine workshop in Rotterdam, the Netherlands. Poster: Marie Verdeil. Image: Sara Vercauteren
124The workshop takes place on behalf of the “Hou… — <a href=https://solar.lowtechmagazine.com/posts/>LOW←TECH MAGAZINE English</a><li><a href="http://offbeatpursuit.com:80/blog/?id=24" target=_blank rel=noopener>Printf debugging</a><div>tags:
125plan9
126There’s no shame in that. Yes, there is documentation, code to be
127read, and debuggers to be used. But sometimes you just need to “see”
128what is happening.
129So… — <a href=http://offbeatpursuit.com:80/blog/>WLOG - blog</a><li><a href=https://neil.computer/notes/chart-of-accounts-for-startups-and-saas-companies/ target=_blank rel=noopener>Chart of Accounts for Startups and SaaS Companies</a><div>Accounting is fundamental to starting a business. You need to have a basic understanding of accounting principles and essential bookkeeping. I had to learn it. Ther… — <a href=https://neil.computer/>Neil Panchal</a><li><a href=https://journal.valeriansaliou.name/deploy-a-nomad-cluster-on-alpine-linux-with-vultr/ target=_blank rel=noopener>Deploy a Nomad Cluster on Alpine Linux with Vultr</a><div>After spending countless hours trying to understand how to deploy my apps on Kubernetes for the first time to host Mirage, an AI API service that I run, I ended up … — <a href=https://journal.valeriansaliou.name/>Valerian Saliou</a><li><a href=https://jcs.org/2023/10/17/wikipedia target=_blank rel=noopener>Wikipedia Reader 1.0 Released</a><div>Wikipedia Reader
1301.0 has been released:
131wikipedia-1.0.sit
132(StuffIt 3 archive, includes
133source code
134and THINK C 5 project file)
135SHA256: 360e12d064f6579695f1e627ce34cb2f0… — <a href=https://jcs.org/>joshua stein</a></ul><p><a href=https://git.sr.ht/~sircmpwn/openring>Generated with openring.</a></section><footer><hr><p><big><strong>Want to comment or have something to add?</strong></big><p>You can write me an email
136at <a href=mailto:m@mitjafelicijan.com>m@mitjafelicijan.com</a> or
137catch up with me <a href=https://telegram.me/mitjafelicijan target=_blank>on Telegram</a>.<hr><p>This website does not track you. Content is made available under
138the <a href=https://creativecommons.org/licenses/by/4.0/ target=_blank rel=noreferrer>CC BY 4.0 license</a> unless specified
139otherwise. Blog is also available as <a href=/index.xml target=_blank>RSS feed</a>.</footer> \ No newline at end of file