<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mike</title>
    <description>The latest articles on DEV Community by Mike (@strayobject).</description>
    <link>https://dev.to/strayobject</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F759574%2F16ef56f0-fb54-4585-ba04-9270c06ba894.jpg</url>
      <title>DEV Community: Mike</title>
      <link>https://dev.to/strayobject</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/strayobject"/>
    <language>en</language>
    <item>
      <title>Yubikey suddenly stopped working on Ubuntu</title>
      <dc:creator>Mike</dc:creator>
      <pubDate>Wed, 24 Apr 2024 10:17:32 +0000</pubDate>
      <link>https://dev.to/strayobject/yubikey-suddenly-stopped-working-on-ubuntu-2hn1</link>
      <guid>https://dev.to/strayobject/yubikey-suddenly-stopped-working-on-ubuntu-2hn1</guid>
      <description>&lt;p&gt;If you are on ubuntu and/or your web browser is installed via snap and you use yubikey or any other physical 2fa device, there is a chance that the key suddenly stops working. It might not be broken as there seems to be a bug in snapd v2.62.&lt;/p&gt;

&lt;p&gt;I went to report it but someone has already done that (&lt;a href="https://bugs.launchpad.net/snapd/+bug/2062148"&gt;https://bugs.launchpad.net/snapd/+bug/2062148&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The solution is to downgrade your snapd (at least at the moment).&lt;/p&gt;

&lt;h2&gt;
  
  
  Check what versions you currently have installed:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ snap --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are not currently using snapd 2.62, then you might want to stop and investigate the issue further (or downgrade nevertheless to eliminate snapd as culprit)&lt;/p&gt;

&lt;h2&gt;
  
  
  List available ones
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ snap list --all snapd
Name   Version  Rev    Tracking       Publisher   Notes
snapd  2.62     21465  latest/stable  canonical✓  snapd,disabled
snapd  2.61.2   21184  latest/stable  canonical✓  snapd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the revision numbers, in this case we want to use 2.61.2 with revision number 21184. Yours might differ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downgrade
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo snap refresh snapd --revision=21184
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might have to (however in my case it was not necessary) relaunch the affected web browser for this change to take effect.&lt;/p&gt;

&lt;p&gt;Hope this helps!&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>yubikey</category>
      <category>2fa</category>
      <category>snapd</category>
    </item>
    <item>
      <title>php root namespace functions list</title>
      <dc:creator>Mike</dc:creator>
      <pubDate>Wed, 23 Aug 2023 10:40:22 +0000</pubDate>
      <link>https://dev.to/strayobject/php-root-namespace-functions-list-43p8</link>
      <guid>https://dev.to/strayobject/php-root-namespace-functions-list-43p8</guid>
      <description>&lt;p&gt;Below is a list of functions in php which benefit from being prefixed with a root namespace, for example &lt;code&gt;\in_array()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;array_slice
assert
boolval
call_user_func
call_user_func_array
chr
count
defined
doubleval
floatval
func_get_args
func_num_args
get_called_class
get_class
gettype
in_array
intval
is_array
is_bool
is_double
is_float
is_int
is_integer
is_long
is_null
is_object
is_real
is_resource
is_string
ord
strlen
strval
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source:&lt;br&gt;
&lt;a href="https://github.com/php/php-src/blob/f2db305fa4e9bd7d04d567822687ec714aedcdb5/Zend/zend_compile.c#L3872"&gt;https://github.com/php/php-src/blob/f2db305fa4e9bd7d04d567822687ec714aedcdb5/Zend/zend_compile.c#L3872&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
    </item>
    <item>
      <title>Self-hosted Taiga.io on Scaleway</title>
      <dc:creator>Mike</dc:creator>
      <pubDate>Sun, 28 Nov 2021 20:57:11 +0000</pubDate>
      <link>https://dev.to/strayobject/self-hosted-taigaio-on-scaleway-3eoo</link>
      <guid>https://dev.to/strayobject/self-hosted-taigaio-on-scaleway-3eoo</guid>
      <description>&lt;p&gt;There may come a time in one’s life where long term project planning is needed. I’m a big fan of Taiga for project management and I’ve been using both free and paid plans on their saas platform. Check it out before you decide to follow in my footsteps as their free offering is positively good.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Task
&lt;/h2&gt;

&lt;p&gt;Deploy dockerised taiga.io&lt;br&gt;
Host it on the cheap (single instance, no external db), but ensure full, encrypted off-site backup.&lt;/p&gt;
&lt;h2&gt;
  
  
  Infrastructure
&lt;/h2&gt;

&lt;p&gt;Taiga is open source, what is more unlike a lot of open source saas the team behind Taiga offers a dockerised version, which you can config and run on the server. Pick whatever provider you like, I chose &lt;a href="https://www.scaleway.com"&gt;Scaleway&lt;/a&gt; and used one of their guides for backups. Scaleway offers an s3 compatible api for object storage, so you can use &lt;a href="https://github.com/s3tools/s3cmd"&gt;s3cmd&lt;/a&gt; if you like it. They also have a s3 glacier equivalent, which is nice. In any case, first 75GB of storage is free, and you are unlikely to hit that unless you store a lot of media with your tasks.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;At this point in time we only care about getting a running setup, upgrades may come in the future. There is a &lt;a href="https://blog.taiga.io/announcing_taiganext.html"&gt;new version of Taiga coming in 2022&lt;/a&gt;, so depending on the upgrade path, I will probably write a new post :)  &lt;/p&gt;

&lt;p&gt;Assuming you already have access to your instance, follow the &lt;br&gt;
&lt;a href="https://docs.taiga.io/setup-production.html"&gt;Install Taiga in Production guide&lt;/a&gt;. I've had a bit of a problem with email setup (gmail most likely will work for you, but before I figured out what the issue was I have already setup a free account on SendGrid), so here are my env vars:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;EMAIL_BACKEND&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django.core.mail.backends.smtp.EmailBackend"&lt;/span&gt;
&lt;span class="na"&gt;DEFAULT_FROM_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no-reply@mycompany.com"&lt;/span&gt;
&lt;span class="na"&gt;EMAIL_USE_TLS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;True"&lt;/span&gt;
&lt;span class="c1"&gt;#EMAIL_USE_SSL: "False"&lt;/span&gt;
&lt;span class="na"&gt;EMAIL_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;smtp.sendgrid.net"&lt;/span&gt;
&lt;span class="na"&gt;EMAIL_PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;587&lt;/span&gt;
&lt;span class="na"&gt;EMAIL_HOST_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apikey"&lt;/span&gt;
&lt;span class="na"&gt;EMAIL_HOST_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_KEY_HERE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the commented out &lt;code&gt;EMAIL_USE_SSL&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Nginx
&lt;/h2&gt;

&lt;p&gt;Install certbot on your server and obtain the certificate for your domain.&lt;br&gt;
Update nginx config file in 'taiga-gateway' dir. I might publish my setup, but it's unlikely given how much I would need to change or strip out to remove secrets from the base Taiga one. Just make sure you set up TLS properly and add your domain.&lt;/p&gt;
&lt;h2&gt;
  
  
  Backups
&lt;/h2&gt;

&lt;p&gt;I'm hoping that by now you have Taiga up and running, so let's move onto setting up backups. These are handled by &lt;a href="https://duplicity.gitlab.io/duplicity-web/index.html"&gt;duplicity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The steps are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install duplicity&lt;/li&gt;
&lt;li&gt;Create GPG keys&lt;/li&gt;
&lt;li&gt;Manual test&lt;/li&gt;
&lt;li&gt;Add shell scripts to cron to automate the process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have followed this &lt;a href="https://www.scaleway.com/en/docs/tutorials/backup-dedicated-server-s3-duplicity"&gt;guide from Scaleway&lt;/a&gt;, however, if like me you install the newer version of duplicity, then you will need to adjust the shell scripts as params have changed. I've installed 0.8.21 and if you look into &lt;a href="https://github.com/strayobject/scaleway-backup-scripts"&gt;my repo&lt;/a&gt; you will be able to find all the updated scripts.&lt;/p&gt;
&lt;h2&gt;
  
  
  DB backup
&lt;/h2&gt;

&lt;p&gt;This is a simple script that outputs a .pgdata file which contains snapshot of our taiga DB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-lt&lt;/span&gt; 4 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Usage &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;container_name&amp;gt; &amp;lt;db_user_name&amp;gt; &amp;lt;db_name&amp;gt; &amp;lt;backup_file_path&amp;gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Exemple:"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ $0&lt;/span&gt;&lt;span class="s2"&gt; taiga_taiga-db_1 taiga taiga /backups/db/db.pgdata ## based on defaults from Taiga docker repo
  "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;CONTAINER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;
&lt;span class="nv"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;
&lt;span class="nv"&gt;BACKUP_FILE_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$4&lt;/span&gt;

docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CONTAINER_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; /bin/bash &lt;span class="nt"&gt;-lc&lt;/span&gt; &lt;span class="s2"&gt;"pg_dump --username &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$DB_USER&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;  --format custom &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$DB_NAME&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_FILE_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Media backup
&lt;/h2&gt;

&lt;p&gt;Another simple script that copies contents of taiga media container. Note that I take a simple copy, without stopping of containers nor any data verification, which does not guarantee data integrity. In my case, with the backups scheduled at night, there is very low risk that there could be an issue. Your mileage may vary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# This script is quite pointless at the moment.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-lt&lt;/span&gt; 2 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Usage &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;source_dir_path&amp;gt; &amp;lt;backup_dir_path&amp;gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Exemple:"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ $0&lt;/span&gt;&lt;span class="s2"&gt; /var/lib/docker/volumes/taiga_taiga-media-data/_data /backups/media ## based on defaults from Taiga docker repo
  "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;SOURCE_DIR_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;BACKUP_FILE_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;

&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOURCE_DIR_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_FILE_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cron
&lt;/h2&gt;

&lt;p&gt;Set up cron to your liking, mine is similar to the one below. Note that I'm restarting gateway daily, to ensure certificate swap when certbot updates the ssl certificate. (I'm aware there are hooks I could use, but at this point this is good enough for me.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 0 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /bin/db-backup.sh &amp;lt;container_name&amp;gt; &amp;lt;db_user_name&amp;gt; &amp;lt;db_name&amp;gt; &amp;lt;backup_file_path&amp;gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/taiga-cron.log 2&amp;gt;&amp;amp;1
0 0 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /bin/media-backup.sh &amp;lt;source_dir_path&amp;gt; &amp;lt;backup_dir_path&amp;gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/taiga-cron.log 2&amp;gt;&amp;amp;1
0 3 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /bin/upload-backup.sh &amp;lt;config_dir_path&amp;gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/taiga-cron.log 2&amp;gt;&amp;amp;1
0 4 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/taiga &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /usr/local/bin/docker-compose restart taiga-gateway &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/taiga-cron.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you have reached the end then you should now have a fully working self-hosted instance of Taiga with an encrypted backup to whatever off-site storage you chose to use.  &lt;/p&gt;

&lt;p&gt;In the next part (if time allows), I will write about pulling the backup onto your local machine and importing it to a blank instance of Taiga. With that said, the relevant scripts to fetch the data from storage and to import the DB are in the &lt;a href="https://github.com/strayobject/scaleway-backup-scripts"&gt;repo on github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>taiga</category>
      <category>docker</category>
      <category>scaleway</category>
      <category>backup</category>
    </item>
  </channel>
</rss>
