<?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: Annie Taylor Chen</title>
    <description>The latest articles on DEV Community by Annie Taylor Chen (@annietaylorchen).</description>
    <link>https://dev.to/annietaylorchen</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%2F425940%2F61bd7bb3-7779-49e6-99b1-82fb069aceba.jpeg</url>
      <title>DEV Community: Annie Taylor Chen</title>
      <link>https://dev.to/annietaylorchen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/annietaylorchen"/>
    <language>en</language>
    <item>
      <title>Davinci Resolve 19.1.2 x Linux Mint 22 AAC Audio Workaround</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Fri, 03 Jan 2025 19:50:37 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/davinci-resolve-1912-x-linux-mint-22-aac-audio-workaround-1mj3</link>
      <guid>https://dev.to/annietaylorchen/davinci-resolve-1912-x-linux-mint-22-aac-audio-workaround-1mj3</guid>
      <description>&lt;p&gt;If you are new to Davinci Resolve and Linux Mint you might run into the issues with AAC audio format not loaded properly in your mp4 files. This is due to license issues but so far Davinci Resolve (19.1.2 at the time of writing) has not come up with a solution either in paid Studio version or free version. Therefore we might need a workaround for such.&lt;/p&gt;

&lt;p&gt;Step 1. First you need to install FFmpeg&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install ffmpeg 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2. Then make a new folder. Move all your mp4 files with aac audio to this folder. &lt;/p&gt;

&lt;p&gt;Step 3. Make this following into a script, save it as &lt;code&gt;towav.sh&lt;/code&gt; or any name you like, you just need to change the command line. Make sure this file lives in the same folder you made in step 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
for f in $(ls -1v | grep -i mp4);do
    extension="${f##*.}";
   ffmpeg -i "$f" -stats -hide_banner -acodec pcm_s16le -vn "${f/%$extension/wav}";
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4. Now you run the command line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ./folderYouMade
./towav.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will batch process your mp4 files and extract audios from them and save as a separate audio files in wav format. &lt;/p&gt;

&lt;p&gt;Step 5. You now can load mp4 files in Davinci Resolve, delete the associated audio track and replace them with the wav one. &lt;/p&gt;

&lt;p&gt;I do wish there would be some solution in the future so it's more intuitive to work, but before that this is the best workflow I've found so far. &lt;/p&gt;

&lt;p&gt;Read further:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.tecmint.com/install-ffmpeg-in-linux/" rel="noopener noreferrer"&gt;How to Install FFmpeg in Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forum.blackmagicdesign.com/viewtopic.php?f=33&amp;amp;t=102620" rel="noopener noreferrer"&gt;Support AAC de- and encoding on Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forum.blackmagicdesign.com/viewtopic.php?f=21&amp;amp;t=214300&amp;amp;p=1111687#p1111687" rel="noopener noreferrer"&gt;mp4 doesn't have sound in Davinci Resolve 19.1.2 Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>davinciresolve</category>
      <category>linux</category>
      <category>aac</category>
      <category>videoediting</category>
    </item>
    <item>
      <title>How to Install DaVinci Resolve 19 (studio) on Linux Mint 22 with AMD Radeon Graphics Card with a Script fast 2025</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Thu, 02 Jan 2025 13:14:30 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/how-to-install-davinci-resolve-19-studio-on-linux-mint-22-with-amd-radeon-graphics-card-with-a-kd6</link>
      <guid>https://dev.to/annietaylorchen/how-to-install-davinci-resolve-19-studio-on-linux-mint-22-with-amd-radeon-graphics-card-with-a-kd6</guid>
      <description>&lt;p&gt;If you want to do it from scratch you can refer to &lt;a href="https://dev.to/annietaylorchen/how-to-install-davinci-resolve-19-beta-on-linux-mint-22-with-amd-radeon-graphics-card-1mfb"&gt;my previous post&lt;/a&gt;. However I've tried a new method and this works like a charm and it's much hassle-free and fast. Note I've previously installed the beta version and now I bought the studio version so I am installing the studio version and use it with license key. This might be different if you're using the free version. But in theory the process should work for both. &lt;/p&gt;

&lt;p&gt;Step 1&lt;br&gt;
You need to download the zip file from Davinci Resolve website, put it in your Downloads folder. Note, you would need to change the script if you put it somewhere else. Make sure the name follows the zip file pattern in the script below. (It should be right if you download directly from the official site, you don't need to change anything.) Do NOT upzip it. &lt;/p&gt;

&lt;p&gt;Step 2&lt;br&gt;
Make this script executable, and place it in your Downloads folder. Name it as &lt;code&gt;DR_MINT.sh&lt;/code&gt;. Again change the command if you plan to name it something else!&lt;br&gt;
&lt;/p&gt;

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

# Script to Install DaVinci Resolve on Linux Mint 22

set -e  # Exit on any error

# Variables
ACTIVE_USER=$(logname)
HOME_DIR=$(eval echo "~$ACTIVE_USER")
DOWNLOADS_DIR="$HOME_DIR/Downloads"
EXTRACTION_DIR="/opt/resolve"
ZIP_FILE_PATTERN="DaVinci_Resolve_*.zip"

# Step 1: Ensure FUSE and libfuse.so.2 are Installed
echo "Checking for FUSE and libfuse.so.2..."
if ! dpkg -l | grep -q fuse; then
    echo "Installing FUSE..."
    sudo apt update
    sudo apt install -y fuse libfuse2
fi

if [ ! -f /lib/x86_64-linux-gnu/libfuse.so.2 ]; then
    echo "Error: libfuse.so.2 is not found. Installing libfuse2..."
    sudo apt install -y libfuse2
fi

# Step 2: Install Required Qt Libraries
echo "Installing required Qt libraries..."
sudo apt install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5gui5 libqt5widgets5 libqt5network5 libqt5dbus5 \
libxrender1 libxrandr2 libxi6 libxkbcommon-x11-0 libxcb-xinerama0 libxcb-xfixes0 qtwayland5 libxcb-glx0 libxcb-util1

# Step 3: Navigate to Downloads Directory
echo "Navigating to Downloads directory..."
if [ ! -d "$DOWNLOADS_DIR" ]; then
    echo "Error: Downloads directory not found at $DOWNLOADS_DIR."
    exit 1
fi
cd "$DOWNLOADS_DIR"

# Step 4: Extract DaVinci Resolve ZIP File
echo "Extracting DaVinci Resolve installer..."
ZIP_FILE=$(find . -maxdepth 1 -type f -name "$ZIP_FILE_PATTERN" | head -n 1)
if [ -z "$ZIP_FILE" ]; then
    echo "Error: DaVinci Resolve ZIP file not found in $DOWNLOADS_DIR."
    exit 1
fi

unzip -o "$ZIP_FILE" -d DaVinci_Resolve/
chown -R "$ACTIVE_USER:$ACTIVE_USER" DaVinci_Resolve
chmod -R 774 DaVinci_Resolve

# Step 5: Run the Installer or Extract AppImage
echo "Running the DaVinci Resolve installer..."
cd DaVinci_Resolve
INSTALLER_FILE=$(find . -type f -name "DaVinci_Resolve_*.run" | head -n 1)
if [ -z "$INSTALLER_FILE" ]; then
    echo "Error: DaVinci Resolve installer (.run) file not found in extracted directory."
    exit 1
fi

chmod +x "$INSTALLER_FILE"

# Set Qt platform plugin path and debug settings
export QT_DEBUG_PLUGINS=1
export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms
export QT_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/qt5/plugins
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH

# Attempt to run the installer with FUSE; fallback to extraction
if ! SKIP_PACKAGE_CHECK=1 ./"$INSTALLER_FILE" -a; then
    echo "FUSE is not functional. Extracting AppImage contents..."
    sudo mkdir -p "$EXTRACTION_DIR"
    ./"$INSTALLER_FILE" --appimage-extract
    sudo mv squashfs-root/* "$EXTRACTION_DIR/"
    sudo chown -R root:root "$EXTRACTION_DIR"
fi

# Step 6: Resolve Library Conflicts
echo "Resolving library conflicts..."
if [ -d "$EXTRACTION_DIR/libs" ]; then
    cd "$EXTRACTION_DIR/libs"
    sudo mkdir -p not_used
    sudo mv libgio* not_used || true
    sudo mv libgmodule* not_used || true

    # Replace with system versions
    if [ -f /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 ]; then
        sudo cp /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 "$EXTRACTION_DIR/libs/"
    else
        echo "Warning: System library libglib-2.0.so.0 not found. Ensure compatibility manually."
    fi
else
    echo "Error: Installation directory $EXTRACTION_DIR/libs not found. Skipping library conflict resolution."
fi

# Step 7: Cleanup
echo "Cleaning up installation files..."
cd "$DOWNLOADS_DIR"
rm -rf DaVinci_Resolve

echo "DaVinci Resolve installation completed successfully!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3&lt;br&gt;
Now you run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ./Downloads
sudo ./DR_MINT.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;enter your password it should be good to go! &lt;/p&gt;

&lt;p&gt;Note it might take a little while, so be patient! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16h66nw2f450i536jjnp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16h66nw2f450i536jjnp.gif" alt="happy cat" width="271" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this will work for you, if not leave a comment so we could see if we can debug from there. &lt;/p&gt;

</description>
      <category>linux</category>
      <category>davinciresolve</category>
      <category>amd</category>
      <category>videoediting</category>
    </item>
    <item>
      <title>How to Install DaVinci Resolve 19 (beta) on Linux Mint 22 with AMD Radeon Graphics Card</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Fri, 09 Aug 2024 20:39:02 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/how-to-install-davinci-resolve-19-beta-on-linux-mint-22-with-amd-radeon-graphics-card-1mfb</link>
      <guid>https://dev.to/annietaylorchen/how-to-install-davinci-resolve-19-beta-on-linux-mint-22-with-amd-radeon-graphics-card-1mfb</guid>
      <description>&lt;p&gt;UPDATE: if you are reading this from Jan 2025 and on, please check my latest article and see if this way works for you. &lt;br&gt;
&lt;a href="https://dev.to/annietaylorchen/how-to-install-davinci-resolve-19-studio-on-linux-mint-22-with-amd-radeon-graphics-card-with-a-kd6"&gt;How to Install DaVinci Resolve 19 (studio) on Linux Mint 22 with AMD Radeon Graphics Card with a Script fast 2025&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few years ago I wrote a post on this when I managed to solve the problem... then I wasn't really using DaVinci Resolve for a while. Fast forward to today, I was happy that Linux Mint has updated to 22, and DaVinci Resolve has grown to be 19 (beta), I thought things would become easier but nope, not at all! After naively trusting things would work like a charm, I managed to destroy my newly installed Linux Mint 22 with all things extra copied and configured nicely to my satisfaction, only to discover installing libraries required for DaVinci Resolve 19 Beta would totally destroy the whole booting process! Now I am forced to reinstall Linux Mint 22 totally from scratch, the first thing I do is to fix DaVinci Resolve first and this time I am going to do my research, experiment, and write things down!&lt;/p&gt;

&lt;p&gt;My hardware for your reference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhizyg5or3u3jebert6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhizyg5or3u3jebert6f.png" alt="Linux Mint 22 with AMD system info" width="650" height="275"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Make DaVinci Resolve a deb for Linux Mint
&lt;/h2&gt;

&lt;p&gt;If you go to DaVinci Resolve's website for download, you will find the linux version ends with &lt;code&gt;.run&lt;/code&gt; which is made for CentOS and not debian system, such as Ubuntu or Linux Mint. Daniel Tufvesson has done a good job making a tool to convert it. Here is the link. &lt;br&gt;
&lt;a href="https://www.danieltufvesson.com/makeresolvedeb" rel="noopener noreferrer"&gt;https://www.danieltufvesson.com/makeresolvedeb&lt;/a&gt; &lt;br&gt;
Follow the instruction there, until you get the deb. &lt;/p&gt;
&lt;h2&gt;
  
  
  2. run script
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sudo apt install build-essential checkinstall&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. add your user to the video and the render group
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sudo usermod -a -G render,video [username]&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4. install ROCm
&lt;/h2&gt;

&lt;p&gt;Reference: &lt;a href="https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/native-install/ubuntu.html" rel="noopener noreferrer"&gt;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/native-install/ubuntu.html&lt;/a&gt;&lt;br&gt;
You don't need to install kernel driver, just the ones that are needed. &lt;/p&gt;

&lt;p&gt;4.1 Package signing key&lt;br&gt;
Download and convert the package signing key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Make the directory if it doesn't exist yet.
# This location is recommended by the distribution maintainers.
sudo mkdir --parents --mode=0755 /etc/apt/keyrings

# Download the key, convert the signing-key to a full
# keyring required by apt and store in the keyring directory
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \
    gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.2 Register ROCm packages&lt;br&gt;
Add the ROCm repository.Makes sure it is ubuntu 24.04 as that's what LM22 is based on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/6.2 noble main" \
    | sudo tee --append /etc/apt/sources.list.d/rocm.list
echo -e 'Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600' \
    | sudo tee /etc/apt/preferences.d/rocm-pin-600
sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.3 install the rocm6.2 (this might take a bit time)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install rocm-libs6.2.0 rocm-opencl-sdk6.2.0 rocminfo6.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. add /opt/rocm/bin to your PATH
&lt;/h2&gt;

&lt;h2&gt;
  
  
  6. reboot
&lt;/h2&gt;

&lt;h2&gt;
  
  
  7. now we need to install the deb
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sudo dpkg -i davinci-resolve_19.0b6-mrd1.7.1_amd64.deb&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. start the program
&lt;/h2&gt;

&lt;p&gt;By now you should see the davinci resolve buttons shown up in the menu like below. However, if you click on them it will not work. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1psb1vjujaevr5k0kpic.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1psb1vjujaevr5k0kpic.jpg" alt="Davinci Resolve 19 icons on menu linux mint 22" width="615" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because it ships versions of some system libraries that are incompatible with current Linux Mint. But these libraries exist on your system, so you can force Resolve to use the ones provided by the system rather than it's own. Additionally it won't find your graphics card unless it looks for libraries in the rocm directory. Use this command to start DaVinci Resolve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LD_PRELOAD=/lib/x86_64-linux-gnu/libglib-2.0.so.0:/lib/x86_64-linux-gnu/libgio-2.0.so.0:/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0:/lib/x86_64-linux-gnu/libgmodule-2.0.so.0  LD_LIBRARY_PATH=/opt/rocm/lib /opt/resolve/bin/resolve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then you get something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fay75ort6orriczqoon76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fay75ort6orriczqoon76.png" alt="Davinci Resolve 19 opening on Linux Mint 22" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9. change menu entry
&lt;/h2&gt;

&lt;p&gt;On the menu, find Sound &amp;amp; Video -&amp;gt; DaVinci Resolve -&amp;gt; right click and in the dropdown you will find Properties, click on that -&amp;gt; A window will show up, you will find an input called command, paste the following command into that input. Now when you click this button in the menu, DaVinci Resolve will finally start as expected!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7nav2p9ba86t8g7akc5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7nav2p9ba86t8g7akc5.jpg" alt="Linux Mint 22 menu button for DaVinci Resolve 19" width="800" height="440"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env LD_PRELOAD=/lib/x86_64-linux-gnu/libglib-2.0.so.0:/lib/x86_64-linux-gnu/libgio-2.0.so.0:/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0:/lib/x86_64-linux-gnu/libgmodule-2.0.so.0  LD_LIBRARY_PATH=/opt/rocm/lib /opt/resolve/bin/resolve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila that's it...Now I only hope things will run from now on. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu61kq7f99kff3p6h5k8i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu61kq7f99kff3p6h5k8i.gif" alt="bittersweet smile" width="280" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Read further:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.danieltufvesson.com/makeresolvedeb" rel="noopener noreferrer"&gt;Make Resolve Deb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/native-install/ubuntu.html" rel="noopener noreferrer"&gt;ROCM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forums.linuxmint.com/viewtopic.php?t=426123" rel="noopener noreferrer"&gt;big help from LinuxMint forum&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>linux</category>
      <category>davinci</category>
      <category>amd</category>
      <category>videoediting</category>
    </item>
    <item>
      <title>How to set up Vite React TS project with Vitest</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Wed, 24 Aug 2022 17:03:44 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/how-to-set-up-vite-react-ts-project-with-vitest-2f8d</link>
      <guid>https://dev.to/annietaylorchen/how-to-set-up-vite-react-ts-project-with-vitest-2f8d</guid>
      <description>&lt;p&gt;This tutorials will work for self-generated vite react-ts projects. Please also refer to the following two repos if you have different requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/nickmccurdy/vite-react-testing-ts" rel="noopener noreferrer"&gt;https://github.com/nickmccurdy/vite-react-testing-ts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackblitz.com/edit/vitest-dev-vitest-iaqfk8?file=src%2FApp.test.tsx&amp;amp;initialPath=__vitest__" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/vitest-dev-vitest-iaqfk8?file=src%2FApp.test.tsx&amp;amp;initialPath=__vitest__&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I personally ran into quite some TS errors and after some hours of digging I found the following settings worked for me. Hence I'd like to write it down and hope it will benefit anyone who has encountered the same issue.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Install packages. You will need those following:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@testing-library/dom
@testing-library/jest-dom
@testing-library/react
@testing-library/user-event
@types/testing-library__jest-dom
@vitest/ui
vitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Add scripts:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"test": "vitest",
"test:ui": "vitest --ui",
"coverage": "vitest run --coverage",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. In your &lt;code&gt;vite.config.ts&lt;/code&gt; add, note the triple slash reference types are important to include here:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// &amp;lt;reference types="vitest" /&amp;gt;
/// &amp;lt;reference types="vite/client" /&amp;gt;

import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],

  ...bla bla bla

  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/setupTests.ts',
    // you might want to disable it, if you don't have tests that rely on CSS
    // since parsing CSS is slow
    css: true,
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. In your &lt;code&gt;tsconfig.json&lt;/code&gt; include:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "include": ["src", "@testing-library/jest-dom"],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. In your root directory, have a file named &lt;code&gt;setupTests.ts&lt;/code&gt; and include those:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// &amp;lt;reference types="vitest/globals" /&amp;gt;
import '@testing-library/jest-dom';
import "@testing-library/jest-dom/extend-expect";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Make a utils folder and include a &lt;code&gt;test-utils.tsx&lt;/code&gt; file and put those in the code:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* eslint-disable import/export */
import { cleanup, render } from '@testing-library/react'
import { afterEach } from 'vitest'

afterEach(() =&amp;gt; {
  cleanup()
})

const customRender = (ui: React.ReactElement, options = {}) =&amp;gt;
  render(ui, {
    // wrap provider(s) here if needed
    wrapper: ({ children }) =&amp;gt; children,
    ...options,
  })

export * from '@testing-library/react'
export { default as userEvent } from '@testing-library/user-event'
// override render export
export { customRender as render }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Finally, try writing a test, such as &lt;code&gt;App.test.tsx&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {describe, expect, it} from 'vitest';
import App from './App';
import { render, screen, userEvent } from './utils/test-utils'


describe('Simple working test', () =&amp;gt; {
  it('the title is visible', () =&amp;gt; {
    render(&amp;lt;App /&amp;gt;);
    expect(screen.getByText(/Ellida Admin/i)).toBeInTheDocument();
  });
``
  it('should increment count on click', async () =&amp;gt; {
    render(&amp;lt;App /&amp;gt;)
    userEvent.click(screen.getByRole('button'))
    expect(await screen.findByText(/count is: 1/i)).toBeInTheDocument()
  })

  it('uses flexbox in app header', async () =&amp;gt; {
    render(&amp;lt;App /&amp;gt;)
    const element = screen.getByRole('banner')
    expect(element.className).toEqual('App-header')
    expect(getComputedStyle(element).display).toEqual('flex')
  })
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then type in command line either &lt;code&gt;pnpm test&lt;/code&gt; if you just want it to run in the terminal or &lt;code&gt;pnpm test:ui&lt;/code&gt; if you want to see the nice UI part. &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt; would work similar. &lt;/p&gt;

</description>
      <category>vite</category>
      <category>react</category>
      <category>testing</category>
      <category>vitest</category>
    </item>
    <item>
      <title>Slimbook pro x AMD vs. MacBook Air M1, which to choose and why?</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Tue, 02 Nov 2021 22:30:32 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/slimbook-pro-x-amd-vs-macbook-air-m1-which-to-choose-and-why-2f9k</link>
      <guid>https://dev.to/annietaylorchen/slimbook-pro-x-amd-vs-macbook-air-m1-which-to-choose-and-why-2f9k</guid>
      <description>&lt;p&gt;I am comparing two laptops for web developer. I don't need much storage as it'll be used mainly as working computer. So the focus is other performance. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3qf073hxbwc6ebus3ap.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3qf073hxbwc6ebus3ap.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://slimbook.es/en/pro-x-en" rel="noopener noreferrer"&gt;Slimbook pro x AMD (Linux)&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AMD Ryzen 7 4800 H with 8 cores and 16 threads 8M cache 2.9 GHz Turbo 4.2 GHz&lt;/li&gt;
&lt;li&gt;AMD Radeon ™ Graphics Vega 7 1600 MHz Compatible with 5.5 kernels&lt;/li&gt;
&lt;li&gt;Display: 14 inches FullHD IPS LED high definition and high color range True Color cover 100% sRGB - 300 nits&lt;/li&gt;
&lt;li&gt;Keyboard: backlight&lt;/li&gt;
&lt;li&gt;Material: Aluminium&lt;/li&gt;
&lt;li&gt;USB 3.0 Ports: 2&lt;/li&gt;
&lt;li&gt;USB-C Ports: 1&lt;/li&gt;
&lt;li&gt;USB 2.0 Ports: 1&lt;/li&gt;
&lt;li&gt;HDMI Ports: 1&lt;/li&gt;
&lt;li&gt;RJ45 Ports: 1&lt;/li&gt;
&lt;li&gt;RAM: 32GB 2 non-soldered DDR4 slots 3200 Mhz&lt;/li&gt;
&lt;li&gt;SSD: 250GB SSD NVMe&lt;/li&gt;
&lt;li&gt;price: 1,169.00 EUR | 1,353.88 USD&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.tuxedocomputers.com/en/Linux-Hardware/Linux-Notebooks/10-14-inch/TUXEDO-Pulse-14-Gen1.tuxedo#!#configurator" rel="noopener noreferrer"&gt;Tuxedo Pulse 14&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Have almost exact the same with Slimbook pro above, just color is dark gray and is a bit ugly....&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;price: 1,090.00 EUR | 1,261.87 USD&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.apple.com/shop/buy-mac/macbook-air" rel="noopener noreferrer"&gt;Apple M1 Chip with 8-Core CPU and 8-Core GPU 512GB Storage&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Apple M1 chip with 8‑core CPU, 8‑core GPU, and 16‑core Neural Engine&lt;/li&gt;
&lt;li&gt;8GB unified memory&lt;/li&gt;
&lt;li&gt;512GB SSD storage¹&lt;/li&gt;
&lt;li&gt;Retina display with True Tone&lt;/li&gt;
&lt;li&gt;Magic Keyboard&lt;/li&gt;
&lt;li&gt;Touch ID&lt;/li&gt;
&lt;li&gt;Force Touch trackpad&lt;/li&gt;
&lt;li&gt;Two Thunderbolt / USB 4 ports&lt;/li&gt;
&lt;li&gt;price: 1 078,50 EUR | 1,249.00 USD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which one would you choose and why?&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>webdev</category>
      <category>hardware</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Study Notes for Kent C. Dodds' Javascript Testing Course</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Tue, 03 Aug 2021 16:19:13 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/study-notes-for-kent-c-dodds-javascript-testing-course-43n3</link>
      <guid>https://dev.to/annietaylorchen/study-notes-for-kent-c-dodds-javascript-testing-course-43n3</guid>
      <description>&lt;p&gt;This is a mini guide for developers who are new to testing. The lessons are mainly learnt from Kent C. Dodds' &lt;a href="https://testingjavascript.com/" rel="noopener noreferrer"&gt;Javascript Testing course&lt;/a&gt;. Kent C. Dodds is the library author for &lt;a href="https://testing-library.com/" rel="noopener noreferrer"&gt;Testing Library&lt;/a&gt;, which is the official recommendation for Create React App.&lt;/p&gt;

&lt;h2&gt;
  
  
  General testing strategies for frontend apps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Static test/format - Eslint and Prettier&lt;br&gt;
To  eliminate type errors and make code looks easy to read and formatted consistently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit test - Jest + React testing library&lt;br&gt;
Test individual key-components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration and Snapshot tests - Jest + MSW&lt;br&gt;
Render the login pages with different responses from the metadata endpoint and see that buttons and forms are created properly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End to End (e2e) test - Cypress + BrowserStack&lt;br&gt;
Implement cypress tests that run our login flow. Run the tests with BrowserStack to get coverage in different browsers. Integrate to GitHub to require approval before release&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Acceptance tests/Visual Regression Test - Percy from BrowserStack (without AI) or Applitools (with AI)&lt;br&gt;
Get screenshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Synthetic tests and monitoring - Datadog&lt;br&gt;
Implement synthetic tests in Datadog that runs different flows. Add real user monitoring in Datadog&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Notes from the course:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  0. Tests types, configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What are unit, static, integration and e2e tests?&lt;br&gt;
The explanation and code samples here:&lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests&lt;/a&gt;&lt;br&gt;
this post also talks about different levels of tests and the pitfalls. The more tests you have, the higher the trophy you get at, the slower the tests will run (because of too many tests) and more money it will cost. Manual testing can always be expensive. Use strategies that suit your business needs and budget.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I use Node debugger and Chrome dev tool while running my tests?&lt;br&gt;
Add a debugger in your code where you want to pause.&lt;br&gt;
Add a script like this&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;"test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --watch"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;It means we are using node’s inspect break, it would mean node will stop process, and we pass the jest binary to node, since jest will run all the tests in parallel, we want to use “runInBand” to run it one by one.&lt;br&gt;
 Then go to “chrome://inspect” in your chrome browser, and you will see the the inspect appearing in “Remote Target” section. Click on the “Inspect”, you will have a browser pop up where you can check call stacks etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Static
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to configure Eslint and Prettier?&lt;br&gt;
In the eslintrc files, the rules can be found on &lt;a href="https://eslint.org/docs/user-guide/configuring" rel="noopener noreferrer"&gt;https://eslint.org/docs/user-guide/configuring&lt;/a&gt;&lt;br&gt;
In the prettierrc, the rules for formatting can be found on &lt;a href="https://prettier.io/playground/" rel="noopener noreferrer"&gt;https://prettier.io/playground/&lt;/a&gt;, click the “show options” in the bottom left, then copy the config JSON.&lt;br&gt;
It is also recommended to use the extensions within your VSCode IDE so you can see errors while you code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What do those ignore files such as eslintignore do?&lt;br&gt;
So the linter won’t check errors for the files listed here. For instance, if you run build we will have a dist folder, and we don’t want the linter to check for errors here.&lt;br&gt;
You can configure it in package json like this:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;”lint”: “eslint --ignore-path .gitignore . “&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;It means when you run npm run lint the linter will seek ignore path, which is specified in our gitignore file and don’t check those, otherwise check the rest in the repo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What are rc files?&lt;br&gt;
In short:&lt;br&gt;
They're not specific to node.&lt;br&gt;
They're just another file&lt;br&gt;
As far as formats, they can be almost anything — it just depends on what you'll use to parse and read them. YAML, JSON, and ini are probably the most common (at least that I've seen).&lt;br&gt;
In most cases they seem to follow the convention .[program or binary name]rc&lt;br&gt;
package.json files can contain external metadata appropriate for config, it just depends on whether or not your project will expect a .rc file or expect it in package.json (or both, as in the case of babel)&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/36212256/what-are-rc-files-in-nodejs" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/36212256/what-are-rc-files-in-nodejs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is monkey patch?&lt;br&gt;
A monkey patch is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program).&lt;br&gt;
Application includes : Replace methods / classes / attributes / functions at runtime, e.g. to stub out a function during testing;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Monkey_patch" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Monkey_patch&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are githooks and husky?&lt;br&gt;
Git hooks are scripts that Git executes before or after events such as: commit, push, and receive. Git hooks are a built-in feature - no need to download anything. Git hooks are run locally.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://githooks.com/" rel="noopener noreferrer"&gt;https://githooks.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Husky is a JavaScript library that makes Git hooks easier. It offers the possibility of integrating them directly into our JavaScript projects, saving us from having to deal with startup guidelines or startup scripts on repository initialization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/better-programming/a-complete-pre-commit-workflow-cea6e34f0032" rel="noopener noreferrer"&gt;https://medium.com/better-programming/a-complete-pre-commit-workflow-cea6e34f0032&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How can I automatically format the code according to prettier and lint rules before the commit?&lt;br&gt;
Use  husky and lint-staged libs.&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/husky" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/husky&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/lint-staged" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/lint-staged&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I run all scripts at one go?&lt;br&gt;
Try &lt;a href="https://www.npmjs.com/package/npm-run-all" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/npm-run-all&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What do the ** and * means in the test file path in config file?&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;rootDir&amp;gt;/src/**/__tests__/**/*.{js,jsx,ts,tsx}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Globstar allows ** on its own as a name component to recursively match any number of layers of non-hidden directories. Also supported by the JS libraries and Python's glob.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a/*/c    //would match a/b/c, a/f/c, a/c/c etc
a/**/c   //would match a/b/c, a/b/f/t/c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here it means we want to find the “&lt;strong&gt;test&lt;/strong&gt;” folder, in src folder, but we don’t care where it is located or nested, then we look for any file that has the js, jsx, ts, or tsx extenstion within this folder (which would be our test files).&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Glob_(programming)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Glob_(programming)&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Typescript vs propTypes?&lt;br&gt;
Typescript validates types at compile time, whereas PropTypes are checked at runtime.&lt;br&gt;
If you’re using TS then it’s not necessary to use propTypes, and you can convert them. Read more in this guide&lt;br&gt;
&lt;a href="https://davemn.com/2020-07/typescript-vs-proptypes" rel="noopener noreferrer"&gt;https://davemn.com/2020-07/typescript-vs-proptypes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile time vs runtime?&lt;br&gt;
Compile-time is the time at which the source code is converted into an executable code while the run time is the time at which the executable code is started running. Both the compile-time and runtime refer to different types of error.&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/846103/runtime-vs-compile-time" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/846103/runtime-vs-compile-time&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Unit Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How do I do UI test if I have different framework or compiler rather than React?&lt;br&gt;
Try use Dom Testing Library. You need to render the components first before testing. Otherwise you can use the specific library that were built on it, but caters to specific framework or compiler, which will make it easier.&lt;br&gt;
&lt;a href="https://testing-library.com/docs/dom-testing-library/intro" rel="noopener noreferrer"&gt;https://testing-library.com/docs/dom-testing-library/intro&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is there any new update on using React Testing Library?&lt;br&gt;
a. use screen instead of extracting variables from render methods.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Old way
const { getByTestId } = render(&amp;lt;ResetPasswordForm queryParameters={route} /&amp;gt;)
expect(getByTestId('password-input')).toBeEmpty() 
// New way   
render(&amp;lt;ResetPasswordForm queryParameters={route} /&amp;gt;)         
expect(screen.getByTestId('password-input')).toBeEmpty()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;b. use “userEvent” instead of “fireEvent”, “change” becomes “type” because userEvent mimics real user usage better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Old way
fireEvent.change(
      getByTestId('email-input'), {
        target: {
          value: brokenEmail
        }
      }
    )
// New way
userEvent.type(
      getByTestId('email-input'), 
      brokenEmail
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;c. “wait” becomes “waitFor”&lt;/p&gt;

&lt;p&gt;d. new mock server is encouraged to be used&lt;br&gt;
&lt;a href="https://mswjs.io/" rel="noopener noreferrer"&gt;https://mswjs.io/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What are common mistakes I should avoid using React Testing Library?&lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/common-mistakes-with-react-testing-library" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/common-mistakes-with-react-testing-library&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to test accessibility issues?&lt;br&gt;
Use &lt;a href="https://github.com/nickcolley/jest-axe" rel="noopener noreferrer"&gt;Jest-axe ​GitHub - nickcolley/jest-axe: Custom Jest matcher for aXe for testing accessibility ♿️🃏​&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, this covers only 30% of real accessibility issues and to improve those you have to manually test with assistive technology that real people use (such as screen reader) and involve disabled people in the user research.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I got a lot of wrapping in act() warning, how it fix that?&lt;br&gt;
It depends on your situation. You shouldn’t just simply wrap things in act() to get away with the warning. Read more in this post:&lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There seems to be various ways of querying elements, which way is the best?&lt;br&gt;
There is indeed some priority you should consider when using the query methods. Mostly you should try to mimic the user’s real usage as much as possible. Read more here:&lt;br&gt;
&lt;a href="https://testing-library.com/docs/queries/about/#priority" rel="noopener noreferrer"&gt;https://testing-library.com/docs/queries/about/#priority&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why I can’t use that getByRole and aria-label to get my password input fields if I toggle between password and text types (so password can be visible)?&lt;br&gt;
It’s an aria-query error so you have to specify the attribute type in input. In this case you can use data-testid instead.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Snapshot and Integration Test
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What is snapshot testing?&lt;br&gt;
Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly. A typical snapshot test case renders a UI component, takes a snapshot, then compares it to a reference snapshot file stored alongside the test.&lt;br&gt;
In Jest, you can use toMatchSnapshot function. If you have prettier you can use toMatchInlineSnapshot function instead.&lt;br&gt;
&lt;a href="https://jestjs.io/docs/en/snapshot-testing#snapshot-testing-with-jest" rel="noopener noreferrer"&gt;https://jestjs.io/docs/en/snapshot-testing#snapshot-testing-with-jest&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do we make effective (and not meaningless and annoying) snapshot tests?&lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/effective-snapshot-testing" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/effective-snapshot-testing&lt;/a&gt;&lt;br&gt;
According to Justin mentioned by Kent, “Most developers, upon seeing a snapshot test fail, will sooner just nuke the snapshot and record a fresh passing one instead of agonizing over what broke it.” So big snapshot test without telling why is not a good idea.&lt;br&gt;
&lt;a href="https://github.com/kentcdodds/jest-glamor-react" rel="noopener noreferrer"&gt;GitHub - kentcdodds/jest-glamor-react: Jest utilities for Glamor and React&lt;/a&gt;​ is a nice tool to have if you are using css in js with react.&lt;br&gt;
And if you use styled-components, try &lt;a href="https://www.npmjs.com/package/jest-styled-components" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/jest-styled-components&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I generate test data such as fake user name or posts etc?&lt;br&gt;
Try this library: &lt;a href="https://github.com/jackfranklin/test-data-bot" rel="noopener noreferrer"&gt;​GitHub - jackfranklin/test-data-bot​&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I pass the params or query in url in my tests?&lt;br&gt;
Before it’s recommended to use history library but now the new way is to use window.history.pushState and BrowserRouter from react-router-dom.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;window.history.pushState({}, '', '/search?clientId=client-one');

    customRender(
      &amp;lt;BrowserRouter&amp;gt;
        &amp;lt;Login /&amp;gt;
      &amp;lt;/BrowserRouter&amp;gt;
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Why can’t I use the toBeNull() to test elements that should NOT show up in the dom?
Now it’s recommended to write like this instead, we use query for things that will NOT be in the dom, and get for things that will be in the dom.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expect(screen.getByRole('alert')).toBeInTheDocument()
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to debug the network request failed error?&lt;br&gt;
First check if you set up the test environment properly, and if you’re running the right test script.&lt;br&gt;
If there are still problems, follow the steps here:&lt;br&gt;
&lt;a href="https://mswjs.io/docs/recipes/debugging-uncaught-requests" rel="noopener noreferrer"&gt;https://mswjs.io/docs/recipes/debugging-uncaught-requests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test runs alright locally, but getting CI test errors such as network request failure?&lt;br&gt;
It’s complicated, but it’s likely to be caused by network request related issues. The last time we had this problem it was caused by one of the inline-svg library which doesn’t fetch properly. Also the testing environment should be setting locally for msw to work properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is the difference between jest.mock() and MSW?&lt;br&gt;
Answered by Artem who is the main contributor behind MSW lib:&lt;br&gt;
jest.mock helps you to mock an entire implementation of something. This means you become in charge of that something, reducing its integrity. That something (i.e. a request library) no longer behaves as it usually does, it listens to your mock and abides it unquestioningly. In the case of API, when you mock axois or fetch, you become in charge of them.&lt;br&gt;
In NodeJS MSW doesn't mock request clients, but monkey patches request issuing modules. That means that your app still makes a real request, it hits all the logic it should, only to get intercepted by MSW and then give you the control over how to respond to a request.&lt;br&gt;
I find it fair to compare jest.mock with NodeJS API of MSW, as jest runs in NodeJS. Apart from using MSW with jest and any other testing framework, you can reuse the mocks you write in a browser. In fact, you'd be using identical mocks, no need to rewrite/tweak/configure. MSW is a tool you adopt to be in charge of your network and does so without deviating your app, and it's a tool you can benefit from on many levels: when testing, developing or debugging.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. E2E Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cypress vs Selenium?&lt;br&gt;
&lt;a href="https://applitools.medium.com/cypress-vs-selenium-webdriver-better-or-just-different-2dc76906607d" rel="noopener noreferrer"&gt;https://applitools.medium.com/cypress-vs-selenium-webdriver-better-or-just-different-2dc76906607d&lt;/a&gt;&lt;br&gt;
Annie: I personally would prefer Cypress because it’s still Javascript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I installed cypress but see the lint error, how to fix that?&lt;br&gt;
Install eslint-plugin-cypress then configure a eslintrc.js file within cypress folder. For example:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  root: true,
  plugins: ['eslint-plugin-cypress'],
  extends: ['plugin:cypress/recommended'],
  env: { 'cypress/globals': true },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How do I configure cypress?&lt;br&gt;
Check here for options: &lt;a href="https://docs.cypress.io/guides/references/configuration.html#Folders-Files" rel="noopener noreferrer"&gt;https://docs.cypress.io/guides/references/configuration.html#Folders-Files&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cy.get.('.236r8yf0yyhsleho') with generated class names are annoying, is there any human-friendly way to select those?&lt;br&gt;
Install @testing-library/cypress in your dependencies, import in the cypress/support/index.js file import '@testing-library/cypress/add-commands, then you can use regex to select text. Since it’s asynchronous we mostly use findByXXXX series.&lt;br&gt;
Another trick is to add const user = cy, then you will see it from a user perspective instead of cypress robot. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I avoid the repeated part of the code, such as login, or register?&lt;br&gt;
You can abstract those into functions and add to Cypress commands in cypress/support/commands.js, then use it in the test such as&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; cy.createUser().then( user =&amp;gt; { the rest of the cypress tests…})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to solve the Babel env error undefined?&lt;br&gt;
Check out the solution here: ​&lt;a href="https://github.com/cypress-io/cypress/issues/6755" rel="noopener noreferrer"&gt;react-app presets in babel configuration throw error because missing &lt;code&gt;NODE_ENV&lt;/code&gt; or &lt;code&gt;BABEL_ENV&lt;/code&gt; environment variables · Issue #6755 · cypress-io/cypress​&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to test dark mode?&lt;br&gt;
See the mvp and solution in this repo:&lt;br&gt;
​&lt;a href="https://github.com/AnnieTaylorCHEN/test-cypress-darkmode" rel="noopener noreferrer"&gt;GitHub - AnnieTaylorCHEN/test-cypress-darkmode: an MVP to test cypress loading darkmode with styled components​&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cypress browser doesn’t run properly (such as not connecting to the internet) when VPN is on, why?&lt;br&gt;
&lt;a href="https://github.com/cypress-io/cypress/issues/672" rel="noopener noreferrer"&gt;Cypress cannot load pages behind a corporate proxy · Issue #672 · cypress-io/cypress​&lt;/a&gt;&lt;br&gt;
According to the above thread, isnce Cypress acts as a reverse proxy to the browser (which also ends up terminating traffic amongst other things), when it makes the external requests to 3rd party servers, it needs to respect the system proxy settings. That's why this is failing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Nodejs Test
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Any way to improve error message for jest test when there is a function with multiple cases?&lt;br&gt;
Try abstract it with &lt;a href="https://github.com/atlassian/jest-in-case" rel="noopener noreferrer"&gt;​GitHub - atlassian/jest-in-case: Jest utility for creating variations of the same test​&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are Spies, Mocks and Stub?&lt;br&gt;
Spies: Creates fake functions which we can use to track executions. This means we can tell/ find out whether the function has been executed/ how many times its been called etc. We can also use spies on existing functions and get the same capability, to track those functions executions.&lt;br&gt;
Stubs: Enables us to replace functions. This gives us more control. We can return whatever we want or have our functions work in a way that suites us to be able to test multiple scenarios.&lt;br&gt;
Mocks: They are fake methods, that have pre-programmed behavior and pre-programmed expectations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic introduction to testing with Chai and Sinon?&lt;br&gt;
​&lt;a href="https://scotch.io/tutorials/how-to-test-nodejs-apps-using-mocha-chai-and-sinonjs" rel="noopener noreferrer"&gt;How to Test NodeJS Apps using Mocha, Chai and SinonJS​&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  FAQ
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Why should I bother with testing?&lt;br&gt;
To give you more confidence that your app will run smoothly, that your users won’t be angry on weekends while nobody is there to answer phone for customer support and nobody is there to fix the bug.&lt;br&gt;
It also helps you to focus and think more about your app, its structure, the code robustness etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I cover all the test cases?&lt;br&gt;
It is advised not to go after 100% coverage but cover the most cases, especially in the UI testing. It is also suggested to use user-centered testing strategy that focuses on testing how the user will use the app, instead of implementation details. If the app pass most tests and it’s running well, you can give it a rest until later you find some edge case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I know what to test?&lt;br&gt;
Probably most asked and most difficult for beginners. Some developers said just to write more tests, explore the options and you will become more experienced. Some said you can see it from a user’s perspective, what’s important for them? How will they use the app? What possible errors they might bump into during their usage, at which stage? What is crucial for the business that failure costs more loss?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are implementation details and why we should not focus on testing on that?&lt;br&gt;
There are two distinct reasons that it's important to avoid testing implementation details. Tests which test implementation details:&lt;br&gt;
Can break when you refactor application code. False negatives&lt;br&gt;
May not fail when you break application code. False positives&lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/testing-implementation-details" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/testing-implementation-details&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why don’t we use Enzyme any more?&lt;br&gt;
It doesn’t encourage the best practice.&lt;br&gt;
You can read the above post, and Kent also said : “With shallow rendering, I can refactor my component's implementation and my tests break. With shallow rendering, I can break my application and my tests say everything's still working.”&lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/why-i-never-use-shallow-rendering" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/why-i-never-use-shallow-rendering&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to get good at testing quickly?&lt;br&gt;
There is no quick track, you just have to practice a lot! Mostly it comes from your experiences, so ultimately you just have to write more tests, fail more, and learn from that.&lt;br&gt;
Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;Jest - &lt;a href="https://jestjs.io/docs/en/getting-started" rel="noopener noreferrer"&gt;https://jestjs.io/docs/en/getting-started&lt;/a&gt;&lt;br&gt;
Jest Cheat Sheet - &lt;a href="https://github.com/sapegin/jest-cheat-sheet" rel="noopener noreferrer"&gt;​GitHub - sapegin/jest-cheat-sheet: Jest cheat sheet​&lt;/a&gt;&lt;br&gt;
Jest Dom - ​&lt;a href="https://github.com/testing-library/jest-dom" rel="noopener noreferrer"&gt;GitHub - testing-library/jest-dom: Custom jest matchers to test the state of the DOM​&lt;/a&gt;&lt;br&gt;
Testing Library / React Testing Library - &lt;a href="https://testing-library.com/docs/" rel="noopener noreferrer"&gt;https://testing-library.com/docs/&lt;/a&gt;&lt;br&gt;
Cypress: &lt;a href="https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell" rel="noopener noreferrer"&gt;https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell&lt;/a&gt;&lt;br&gt;
BrowserStack - &lt;a href="https://www.browserstack.com/docs/" rel="noopener noreferrer"&gt;https://www.browserstack.com/docs/&lt;/a&gt;&lt;br&gt;
Applitools - &lt;a href="https://applitools.com/" rel="noopener noreferrer"&gt;Applitools: Automated Visual Testing with Visual AI&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>frontend</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Add Multiple Github Accounts on One Computer (Linux)</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Wed, 14 Oct 2020 19:52:25 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/how-to-add-multiple-github-accounts-on-one-computer-linux-17kd</link>
      <guid>https://dev.to/annietaylorchen/how-to-add-multiple-github-accounts-on-one-computer-linux-17kd</guid>
      <description>&lt;p&gt;Normally, I like to separate work and personal projects by managing different accounts. However, occasionally we might bump into cases where we only have one computer but have to use it for both work and personal matters. Thus, we might need to set up two or more github accounts on one computer. Here is a simple guide on how to do that. &lt;/p&gt;

&lt;p&gt;Let's assume that we need to set up two accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annie, github username: annie (&lt;a href="mailto:annie@annie.com"&gt;annie@annie.com&lt;/a&gt;) - default, personal, global&lt;/li&gt;
&lt;li&gt;AnnieWork, github username: anniework (&lt;a href="mailto:annie@anniework.com"&gt;annie@anniework.com&lt;/a&gt;) - work only&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Generating the SSH keys
&lt;/h1&gt;

&lt;p&gt;First let's check if we already have it on our computer by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -al ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we see the id_rsa available, we could use this as our default key for Annie account. &lt;/p&gt;

&lt;p&gt;In case we don't have anything, we can generate a default key by typing (-t means type. The possible values are “dsa”, “ecdsa”, “ecdsa-sk”, “ed25519”, “ed25519-sk”, or “rsa”. This flag may also be used to specify the desired signature type when signing certificates using an RSA CA key. The available RSA signature variants are “ssh-rsa” (SHA1 signatures, not recom‐mended), “rsa-sha2-256”, and “rsa-sha2-512” (the default).)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When asked for location, you just press enter to use the default setting. The default private key and public key will be created at ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub. &lt;/p&gt;

&lt;p&gt;For our work account AnnieWork, we need to generate another different SSH key. We save it as ~/.ssh/id_rsa_anniework.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t rsa -C "annie@anniework.com" -f "id_rsa_anniework"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should see two different keys created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.ssh/id_rsa
~/.ssh/id_rsa_anniework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Adding keys to respective Github accounts
&lt;/h1&gt;

&lt;p&gt;To add ssh keys to github, so we don't need to constantly type our username and password when we want to push something to github. First we need to copy the public key. You can simply go to file folder, open it with an editor and copy, or run this command to do that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pbcopy &amp;lt; ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now login to your github account (the Annie account, since we're using the default key here). &lt;/p&gt;

&lt;p&gt;Settings &amp;gt; SSH and GPG keys &amp;gt; New SSH Key &amp;gt; Enter a name for your computer, this name should be recognizable so you know which computer it is related to &amp;gt; paste the key you just copied, which looks like a bunch of gibberish letter and numbers &amp;gt; Add key &amp;gt; DONE! &lt;/p&gt;

&lt;p&gt;Now for the work account, you repeat the above steps, except you need to copy the key from id_rsa_anniework.pub (work account) instead of id_rsa.pub (default account) and you need to add the key to your Anniework github account. &lt;/p&gt;

&lt;h1&gt;
  
  
  3. Register the new SSH keys with ssh-agent
&lt;/h1&gt;

&lt;p&gt;To use the keys, we need to register them with the ssh-agent on our computer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval "$(ssh-agent -s)"
Agent pid 132819 //this is what you will see
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gets your ssh-agent running, then you add the keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_anniework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  4. Create SSH config file
&lt;/h1&gt;

&lt;p&gt;Usually we don't have the config file, so now we can create one to add SSH configuration rules for different hosts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/.ssh/
touch config      //create config file
nano config       //use nano to edit the config file 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in your ~/.ssh/config file, paste the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Default, personal, global - Annie
Host github.com
   HostName github.com
   User git
   IdentityFile ~/.ssh/id_rsa

# Work - AnnieWork
Host github.com-anniework    
   HostName github.com
   User git
   IdentityFile ~/.ssh/id_rsa_anniework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"github.com-anniework" is a notation to differentiate the work github account. Of course you can also set it up as "anniework.github.com", just be consistent when clone the repository. &lt;/p&gt;

&lt;p&gt;Another approach is not to create config rules but manually ensure the ssh-agent to attach only one key at a time with any git operation. To do that you can remove all the keys, then add the key you plan to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-add -D       //remove all ssh entries in the ssh-agent
ssh-add ~/.ssh/id_rsa   //now we add the default key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeat the step when you need to use the work account, just remember to replace the "id_rsa" with "id_rsa_anniework". I personally found this approach a bit troublesome, and prefer the config file approach. But choose whatever suit you the best. &lt;/p&gt;

&lt;h1&gt;
  
  
  5. Set up the git config user.name and user.email
&lt;/h1&gt;

&lt;p&gt;For the default and global one, you can do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global user.name "Annie"
git config --global user.email "annie@annie.com"
git config -l
user.name=Annie
user.email=annie@annie.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, when you push code it will be the default setting. &lt;/p&gt;

&lt;p&gt;But when you need to work in the work repository, make sure you set it up locally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config user.name "AnnieWork"
git config user.email "annie@anniework.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  6. How to clone the repositories
&lt;/h1&gt;

&lt;p&gt;I assume you already know how to clone the repository normally, so I will only cover the work one. When you copy the ssh key you need to modify it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone  git@github.com-anniework/repo_name.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You remember earlier in our ssh config file we set the work account host as "github.com-anniework" right? We need to use this exact name after "git@" when you do git clone. &lt;/p&gt;

&lt;p&gt;Double check if we have done it right&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if we need to update it we do it like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote set-url origin git@github.com-anniework:anniework/repo_name.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the in the "&lt;a href="mailto:git@github.com-anniework"&gt;git@github.com-anniework&lt;/a&gt;:anniework/repo_name.git", after "git@", it's the host name we set in config file, here "github.com-anniework", then after ":", it's our github username, "anniework", it's advised that you keep the name consistent so you don't get confused. &lt;/p&gt;

&lt;p&gt;If we have a local repo that we want to push to github, then we first do git init, then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote add origin git@github.com-anniework:anniework/repo_name.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then proceed like you usually do and you will find that your work account is adding git commit to your work repository.  &lt;/p&gt;

&lt;p&gt;It might seem lengthy and slow to set at first time, but once you have it set it up you don't need to care so much! Your git work flow should just work smoothly. :)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3fngu6kix221b3nw4jw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3fngu6kix221b3nw4jw.gif" alt="slow happy" width="427" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>linux</category>
      <category>ssh</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Install DaVinci Resolve 16 on Linuxmint 20 with AMD Radeon Graphic Card</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Mon, 12 Oct 2020 22:26:39 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/how-to-install-davinci-resolve-16-on-linuxmint-20-with-amd-radeon-graphic-card-4lfh</link>
      <guid>https://dev.to/annietaylorchen/how-to-install-davinci-resolve-16-on-linuxmint-20-with-amd-radeon-graphic-card-4lfh</guid>
      <description>&lt;p&gt;Although Linuxmint usually has built in driver support for AMD graphic card, sometimes we still need to install extra support for some application. Usually it's supposed to be painless, however, I did run into some issues. &lt;/p&gt;

&lt;h1&gt;
  
  
  0. Prepare your driver
&lt;/h1&gt;

&lt;p&gt;Under linuxmint, menu &amp;gt; system info , you shall be able to see your graphic card's name. Search for its driver on AMD site. For instance mine is:&lt;br&gt;
&lt;a href="https://www.amd.com/en/support/graphics/amd-radeon-5700-series/amd-radeon-rx-5700-series/amd-radeon-rx-5700-xt" rel="noopener noreferrer"&gt;AMD Radeon RX 5600 OEM/5600 XT / 5700/5700 XT &lt;/a&gt;&lt;br&gt;
Download the version for Ubuntu x86 64bit for Ubuntu 20.04.1. You will get a zip file. Unzip it. You can rename the folder to something easy to remember but I am too lazy...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd Downloads/amdgpu-pro-20.40-1147286-ubuntu-20.04
./amdgpu-pro-install -y --opencl=pal,legacy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previously I tried other script which somehow didn't properly install the OpenCL and I got this error. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw6bir2djie67t5b209f8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw6bir2djie67t5b209f8.jpg" alt="Error OpenCL GPU for DaVinci Resolve 16" width="528" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've since goolged like crazy, posted in two forums, and read tons of posts and discussed with another friend about this... in the end I uninstalled whatever I installed previously, and re-downloaded the package again (just to make sure it's not corrupted) and reinstalled it like above, and finally got it to work! I hope if you followed my above instruction you don't need to go through the same pain I have been through. &lt;/p&gt;

&lt;h1&gt;
  
  
  1. Prepare the extra libraries needed
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install libssl1.1 ocl-icd-opencl-dev fakeroot xorriso
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;libssl1.1, ocl-icd-opencl-dev needed for running DaVinci Resolve &lt;/li&gt;
&lt;li&gt;fakeroot, xorriso for generating the deb (since the official DaVinci Resolve linux package is only made for CentOS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  2. Download the official DaVinci Resolve 16
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.blackmagicdesign.com/uk/products/davinciresolve/" rel="noopener noreferrer"&gt;DaVinci Resolve Download page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the Linux, note Studio is the paid version with more features, if you want to download the free one just download the DaVinci Resolve 16. &lt;/p&gt;

&lt;p&gt;Extract the zip in your Downloads folder, and you will see the file named DaVinci_Resolve_16.2.7_Linux.run. Don't do anything yet as this one is made for CentOS. In next step we will have a bash script to make it into a installation file that's suitable for Linuxmint.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Download the The MakeResolveDeb script to make the deb file for Linuxmint
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.danieltufvesson.com/makeresolvedeb" rel="noopener noreferrer"&gt;The MakeResolveDeb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The instruction is pretty straight forward from here. Basically you download and extract everything into one folder, and make sure they have exactly the same name. The script here makes the previous .run file we have into a .deb file, then it's suitable to install on Linuxmint. &lt;/p&gt;

&lt;h1&gt;
  
  
  4. Reboot
&lt;/h1&gt;

&lt;p&gt;After everything, don't forget to reboot for things to work properly. If everything goes well you should be able to run DaVinci Resolve on your computer. &lt;/p&gt;

&lt;h2&gt;
  
  
  Read further:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://bashbaug.github.io/opencl/2019/07/06/OpenCL-On-Linux.html" rel="noopener noreferrer"&gt;OpenCL on Linux&lt;/a&gt; - I hope you will not need to read it, I used it for trouble shooting. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://forum.blackmagicdesign.com/" rel="noopener noreferrer"&gt;DaVinci Resolve's own forum&lt;/a&gt; - You will likely find more related information here &lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>linux</category>
      <category>amd</category>
      <category>videoediting</category>
      <category>davinciresolve</category>
    </item>
    <item>
      <title>Why are there fewer female developers?</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Sun, 13 Sep 2020 18:26:49 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/why-are-there-less-female-developers-1d3d</link>
      <guid>https://dev.to/annietaylorchen/why-are-there-less-female-developers-1d3d</guid>
      <description>&lt;p&gt;Since I switched my career to web development, I can't help noticing that it's rare to see female developers. I mean, there are more and more women getting into "tech" industry, as more and more tech companies are emerging and traditional companies are embracing tech, but women who are &lt;strong&gt;developers&lt;/strong&gt; or &lt;strong&gt;engineers&lt;/strong&gt; aren't as common as men. I am just curious on why it is that way. Note a lot of hypothesis are drawn purely from my observation, so it can be very biased. Please feel free to disagree. &lt;/p&gt;

&lt;h1&gt;
  
  
  1. Hypothesis: Women in general, are more into careers that deal with people than computers.
&lt;/h1&gt;

&lt;p&gt;Where I am, Sweden, is considered to be one of the most equal countries when it comes to education, employments and gender equality in general. Girls and boys have equal access to education and technology, yet there are fewer girls choosing computer science or other STEM subjects. This might indicate that, when women are given a choice, they tend not to choose computer related subjects. They might prefer what they are naturally good at, which have something to do with people. &lt;/p&gt;

&lt;h1&gt;
  
  
  2. Hypothesis: Women from less privileged backgrounds might choose computer science because it offers better job opportunities.
&lt;/h1&gt;

&lt;p&gt;Among the very limited female developers I've encountered so far, many of them tend to come from countries that are generally less equal, less affluent than Nordic countries, such as Russia, Poland, India, China, Iran, Cambodia etc. Of course, I've also met two native Swedish female developers who actually studied at KTH, one of the universities in Stockholm that is famous for churning out engineers, but they're not a norm. &lt;/p&gt;

&lt;h1&gt;
  
  
  3. Hypothesis: When given a chance, for instance, when they no longer need to worry about job or money, some women might switch to careers that deal with people than computers.
&lt;/h1&gt;

&lt;p&gt;So far I have met several people who studied computer science before, from less affluent countries, managed to switch their career when they came to Sweden. For instance: one became a audiologist who helps people fit their hearing aids, another became a technical recruiter. Both said they don't find programming interesting, and do not like to face computer all day, and prefer to work with people, preferably face to face.&lt;/p&gt;

&lt;h1&gt;
  
  
  UPDATE: 4. Based on some reading and interaction from other readers, there exist a "systematic problem" in the IT industry that alienated women, which reduced the numbers of women as mentors and leaders, discouraged younger generation to pursue the careers.
&lt;/h1&gt;

&lt;p&gt;One argument says from 1984, personal computers were often bought as a gift for the sons, but not daughters. Boys were more likely to play with it and got mentored by their fathers. By the time they entered college, boys were significantly better at computers, which made girls who had less exposure and previous experiences with computer felt "inferior" and "intimidated" and they dropped from computer science majors or changed their majors. Those men created companies and nerdy cultures, and prefer to hire people who are just like them. Women feel unwelcomed and prefer to do something else. When there are fewer and fewer women in the industry, fewer and fewee girls choose to learn computer science. &lt;/p&gt;

&lt;p&gt;Alternatively, in countries like India, girls are encouraged to study IT because it's an indoor job that keeps them safe from "street-level sexual harassment". &lt;/p&gt;

&lt;p&gt;Further reading/watching: (thank you readers for your recommendation!)&lt;br&gt;
&lt;a href="https://www.nytimes.com/2019/02/13/magazine/women-coding-computer-programming.html" rel="noopener noreferrer"&gt;The Secret History of Women in Coding&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.imdb.com/title/tt4335520/" rel="noopener noreferrer"&gt;CODE: Debugging the Gender Gap&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Delusions_of_Gender" rel="noopener noreferrer"&gt;Delusions of Gender:How Our Minds,Society, and Neurosexism&lt;br&gt;
Create Difference&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.goodreads.com/book/show/1519450.Why_Beautiful_People_Have_More_Daughter" rel="noopener noreferrer"&gt;Why Beautiful People Have More Daughters: From Dating, Shopping, and Praying to Going to War and Becoming a Billionaire-- Two Evolutionary Psychologists Explain Why We Do What We Do&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=E577jhf25t4" rel="noopener noreferrer"&gt;Hjernevask (Brainwash) 1/7 - The Gender Equality Paradox – (Eng. sub - HQ)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=_iudkPi4_sY" rel="noopener noreferrer"&gt;Jordan B. Peterson | Full interview | SVT/TV 2/Skavlan&lt;/a&gt; - this super popular video with 9 million + views is censored in Sweden, by the uploader, SVT, a state TV station funded by Swedish tax payer's money. Swedish tax payer paid for it but can't view it, what do you think? :)&lt;/p&gt;




&lt;p&gt;Of course, there are many women who are indeed interested in computers, programming or engineering in general, and they find it fun and rewarding. And perhaps with more role models, more girls will be inspired to choose tech, and fall in love with it. However, I am not sure the number will eventually even out. I still think it's a positive thing to encourage more girls to get interested in computer science, but I don't think it's necessary to force an equal outcome. After all, we also need to respect people's own interests and choices. &lt;/p&gt;

&lt;p&gt;What is your opinion?&lt;/p&gt;

&lt;p&gt;Photo credit: &lt;a href="https://unsplash.com/photos/x7sp9JC3N3A" rel="noopener noreferrer"&gt;Photo by Christina @ wocintechchat.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
      <category>womenintech</category>
      <category>healthydebate</category>
    </item>
    <item>
      <title>What are reasons you're not using Svelte in production?</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Wed, 26 Aug 2020 16:14:03 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/what-are-reasons-you-re-not-using-svelte-in-production-1kn0</link>
      <guid>https://dev.to/annietaylorchen/what-are-reasons-you-re-not-using-svelte-in-production-1kn0</guid>
      <description>&lt;p&gt;We know there are a lot of perks using Svelte:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;less code to write, less bugs to chase&lt;/li&gt;
&lt;li&gt;smaller bundle size, fast performance&lt;/li&gt;
&lt;li&gt;compiler only, no big run-time library or virtual DOM&lt;/li&gt;
&lt;li&gt;typescript-friendly &lt;/li&gt;
&lt;li&gt;built-in easy-to-use transition and animation &lt;/li&gt;
&lt;li&gt;easy to use state management &lt;/li&gt;
&lt;li&gt;friendly for juniors to learn &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are a few reasons as cons as well:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;small community, less support for solutions &lt;/li&gt;
&lt;li&gt;eco-system is not as diverse as others, such as React's&lt;/li&gt;
&lt;li&gt;might not support vintage browsers such as pre-IE 11&lt;/li&gt;
&lt;li&gt;no big well-known application as examples to demonstrate the scalability of the apps&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Are there any other reasons you're not using it in production? Especially if you're a tech lead, CTO or senior developer who has a say about what tech stack to use for projects, I'd really love to hear your perspectives! I understand it takes time time to rewrite things if you already have an app to maintain, but if you are given a chance to select tech stack to build new apps, will you choose Svelte? Why or why not?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>svelte</category>
      <category>production</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Migrate Node.js App from Heroku to Digital Ocean Ubuntu 20.04 with Nginx, Pm2, SSL</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Fri, 24 Jul 2020 19:55:24 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/migrate-node-js-app-from-heroku-to-digital-ocean-ubuntu-20-04-with-nginx-pm2-ssl-1kpm</link>
      <guid>https://dev.to/annietaylorchen/migrate-node-js-app-from-heroku-to-digital-ocean-ubuntu-20-04-with-nginx-pm2-ssl-1kpm</guid>
      <description>&lt;p&gt;&lt;a href="https://www.heroku.com/" rel="noopener noreferrer"&gt;Heroku&lt;/a&gt; has been a really great service for developers that don't want to spend time on infrastructure. I've uploaded all my toy projects there so far, because it's faster to make them available online, and I can focus more on learning and doing things I like. However, there comes a time when I want to learn more about "behind the scene", so I want to experiment with Digital Ocean, since so many people already mentioned it. Surprisingly not many tutorials were written for what I need in details, so after quite some googling, asking around and experimenting myself, I finally got it working. 😂&lt;/p&gt;

&lt;p&gt;Are you ready?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls2otyqir0wlr4gahnur.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls2otyqir0wlr4gahnur.gif" alt="I am ready" width="480" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Sign up for a Digital Ocean account
&lt;/h2&gt;

&lt;p&gt;First you need to sign up an account. &lt;a href="https://m.do.co/c/49a33d4c6eea" rel="noopener noreferrer"&gt;Click Here&lt;/a&gt;, it is an affiliate link which will give you &lt;strong&gt;$200 for FREE for 60 days&lt;/strong&gt;. How cool is that! 😉 You can use this period to experiment and learn without any cost. Note you do need to sign up with a credit card so you can be verified.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Set up the droplet
&lt;/h2&gt;

&lt;p&gt;Next to your avatar on the top right corner, you will find a bright green button says &lt;strong&gt;Create&lt;/strong&gt;. Click on it and then click &lt;strong&gt;droplets&lt;/strong&gt;. And you will see this page:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd0erypyrgau76zlza08b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd0erypyrgau76zlza08b.jpg" alt="Digital Ocean Droplets" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
Here we choose &lt;strong&gt;Ubuntu 20.04 LTS, Shared CPU Basic, $5/Month plan&lt;/strong&gt;. Of course feel free to choose what suits you the best!&lt;/p&gt;

&lt;p&gt;Scroll down and choose a &lt;strong&gt;data center&lt;/strong&gt; that's near your target audiences, then select additional options, check &lt;strong&gt;IPv6&lt;/strong&gt; and &lt;strong&gt;monitoring&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;I like to use &lt;strong&gt;ssh&lt;/strong&gt; as authentication, so you can generate a key. I am sure there is a lot of tutorials online for this already. I also suggested you choose a name for your droplets. Depending on you, you can choose to have backup or not. After all that, click the green button &lt;strong&gt;Create Droplet&lt;/strong&gt;. Wait a few seconds, your droplet is ready! You will be able to copy the ip address now, and from now on, we will leave Digital Ocean interface and do things in the terminal. &lt;/p&gt;
&lt;h2&gt;
  
  
  3. Login and update your ubuntu system
&lt;/h2&gt;

&lt;p&gt;Now open a terminal and type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh root@youripaddress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note normally you shouldn't do stuff with root. More power more responsibility! You might mess up things by accident, so it's better to create a user. For simplicity I will continue with root for now. Note when you login as user later, you gotta make sure to give user enough right to write some files, such as some nginx conf files. I will paste some read further links at the end.&lt;/p&gt;

&lt;p&gt;It will ask you if you want to continue, then type yes. Then you will see root@DropletName:~#. &lt;/p&gt;

&lt;p&gt;Let's update now. Upgrade is optional. Some people don't do it at all, it's up to you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Let's install Node.js
&lt;/h2&gt;

&lt;p&gt;In the terminal type: (This is the latest version so far but you can replace 14 with 12 if you want stable version)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt install nodejs
node -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you see output of node version number like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v14.6.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have successfully installed node on our system.YEAH!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Let's move our repo to our droplet
&lt;/h2&gt;

&lt;p&gt;Since we already have a node.js app on github, we can easily git clone it here. Let's first create a folder called Apps for all our apps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir apps
cd apps 
git clone git clone https://github.com/username/repo.git
ls -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should see something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.  ..  repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the output is your repo's name, we successfully copied our repo here. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Install dependencies and test run
&lt;/h2&gt;

&lt;p&gt;Now first let's go into your repo here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd repo
npm install
npm start npm 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go to the ipaddress:3000 (or whatever port you're running on)&lt;/p&gt;

&lt;p&gt;can you see your app running? If so, well done! 👍 Press Ctrl + C to stop as we still have a lot to do. &lt;/p&gt;

&lt;h2&gt;
  
  
  7. Set up Pm2 to keep your app running
&lt;/h2&gt;

&lt;p&gt;Now let's install pm2 globally. You can read more about pm2 &lt;a href="https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo npm install pm2@latest -g
pm2 start app 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For instance my app's file is in src, so I cd to my apps/repo then run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 start src/index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something like this shows up, and you should still be able to see your ipaddress:3000 (or whatever port you use) in your browser to see your app running. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmzafiavwz7fvj7pndbd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmzafiavwz7fvj7pndbd0.png" alt="pm2 run successfully" width="663" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make sure your app starts when reboot you can type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 startup ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Set up firewall to block port
&lt;/h2&gt;

&lt;p&gt;When you type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will probably see Status:inactive. Now let's enable it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw enable
sudo ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it should say Status: active. Let's allow a few ports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ssh is port 22, http port 80, https port 443.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Set up and configure Nginx as reverse proxy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install nginx
sudo ufw allow 'Nginx HTTP'
sudo ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should see something like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8gk6q5om02hr6q7y0yfp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8gk6q5om02hr6q7y0yfp.png" alt="ufw status" width="460" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can go to the &lt;a href="http://ipaddress" rel="noopener noreferrer"&gt;http://ipaddress&lt;/a&gt;, (note we don't need to type port any more) and you shall see the following.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7ezi52uai7dkxwp1pkpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7ezi52uai7dkxwp1pkpx.png" alt="Alt Text" width="660" height="270"&gt;&lt;/a&gt;&lt;br&gt;
That means you're doing right so far!&lt;/p&gt;

&lt;p&gt;Now here comes the tricky part. Since I plan to host more toy projects within one droplets, which will also point to different domain names (or subdomain names). We'd better create something extra, instead of modifying the default. &lt;/p&gt;

&lt;p&gt;Let's say we're going to serve the current app at a.example.com. First let's create something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /var/www/a.example.com/html
nano /var/www/a.example.com/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we paste those simple html here, it won't show up so don't need to make it pretty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Welcome to a.example.com!&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;Success! a.example.com server block is working!&amp;lt;/h1&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To save you press Ctrl + X, yes, then press enter. Now we have this file to refer to later in our another conf file.&lt;/p&gt;

&lt;p&gt;First let's create something like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/sites-available/a.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;copy and paste the following to that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; server {
     listen 80;
     listen [::]:80;

       server_name a.example.com;

       root /var/www/a.example.com/html;
       index index.html;

       location / {
        proxy_pass http://localhost:3000; #whatever port your app runs on
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
       }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ctrl + X, yes, press enter. &lt;/p&gt;

&lt;p&gt;Now that we have our server block file, we need to enable it. We can do this by creating symbolic link from this file to the sites-enabled directory, which Nginx reads from during startup. Later when we add more apps and more domains names, we can copy the same steps.&lt;/p&gt;

&lt;p&gt;We can create these links by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ln -s /etc/nginx/sites-available/a.example.com /etc/nginx/sites-enabled/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To avoid a possible hash bucket memory problem that can arise from adding additional server names, it is necessary to adjust a single value in the /etc/nginx/nginx.conf file. Open the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the &lt;strong&gt;server_names_hash_bucket_size 64&lt;/strong&gt; directive and remove the # symbol to uncomment the line.&lt;/p&gt;

&lt;p&gt;Now let's see if our setting is ok. Type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see those lines, then you're successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can restart Nginx.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Set your domain/subdomain name
&lt;/h2&gt;

&lt;p&gt;You need to set an A record. Since I manage my domain name at Netlify, it's relatively easy to do. For instance, I want the domain to sound like meowlo.annietaylorchen.com, so I set it up as below. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fak9rz24keumw38hz5380.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fak9rz24keumw38hz5380.png" alt="set subdomain" width="601" height="531"&gt;&lt;/a&gt;&lt;br&gt;
Note it can take up to 24 to 28 hours for your domain name to propagate, so you need to be a little patient at this point.&lt;/p&gt;

&lt;p&gt;Use &lt;a href="https://www.whatsmydns.net/" rel="noopener noreferrer"&gt;whatsmydns&lt;/a&gt; to check if your domain name is available or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  11. Set up environment variables
&lt;/h2&gt;

&lt;p&gt;If you're using some api keys, we need to set up environment variables. Since I already use dotenv in my node.js app, I will do as follow. I don't know whether this is the best practice, but it somehow worked for me. &lt;/p&gt;

&lt;p&gt;Since we copied our git from github and naturally we didn't push our .env file there, now on our Digital Ocean droplet we also don't have that. But we need to use it when running our apps. &lt;/p&gt;

&lt;p&gt;Now cd to your app folder, and type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch .env
nano .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you copy your api keys like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API_KEY=49upogjergeu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then Ctrl + X, yes, press enter to save. Now you type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should be able to see them showing up in your terminal. Ok, now make sure when you use dotenv you write something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (process.env.NODE_ENV == 'production'){
    require('dotenv').config()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in your npm script it's sth like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"start": "NODE_ENV=production node src/index.js",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's inform pm2 about this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=production pm2 restart src/index.js --update-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your apis should be working! 😺&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Add SSL with LetsEncrypt
&lt;/h2&gt;

&lt;p&gt;Now let's go back to our home directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d a.example.com
sudo certbot renew --dry-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply follow the instruction they prompt in the terminal. If you don't see any error, we're all set. Now refresh your browser, you should see your a.example.com serving your apps, api working, and it's secure too! Pfew! That's a lot, I know! Congrats if you make it to the end. Let's high five!🙌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsoqwxkz4t8htc4wali1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsoqwxkz4t8htc4wali1.gif" alt="happy dance" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least, I have made it as short as possible. There are quite some details I didn't cover, but I think if you have time you should read further later. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=oykl1Ih9pMg" rel="noopener noreferrer"&gt;Full Node.js Deployment - NGINX, SSL With Lets Encrypt by Brad Traversy&lt;/a&gt; - note this is not the latest version I used, but many concepts are the same.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-20-04" rel="noopener noreferrer"&gt;How To Install Git on Ubuntu 20.04&lt;/a&gt; - ubuntu usually comes with git already, but you can set up with your own name and email etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps" rel="noopener noreferrer"&gt;How To Set Up Automatic Deployment with Git with a VPS&lt;/a&gt; - teaches you how to commit from local repo through git, and how to set up beta version &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-20-04" rel="noopener noreferrer"&gt;How To Set Up a Node.js Application for Production on Ubuntu 20.04&lt;/a&gt; - general guide for node.js app &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04" rel="noopener noreferrer"&gt;How To Install Nginx on Ubuntu 20.04&lt;/a&gt; - general guide for nginx&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04" rel="noopener noreferrer"&gt;How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 16.04&lt;/a&gt; - if you want to serve different sites on the same droplets this is useful&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04" rel="noopener noreferrer"&gt;How To Secure Nginx with Let's Encrypt on Ubuntu 20.04&lt;/a&gt; - how to add SSL to your site&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-20-04" rel="noopener noreferrer"&gt;How To Install and Use PostgreSQL on Ubuntu 20.04&lt;/a&gt; - my simple node.js app doesn't require a database, but you will probably need one&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devops</category>
      <category>node</category>
      <category>digitalocean</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Which computer to choose for Linux OS with good graphical processing power? + UPDATE</title>
      <dc:creator>Annie Taylor Chen</dc:creator>
      <pubDate>Wed, 08 Jul 2020 16:07:37 +0000</pubDate>
      <link>https://dev.to/annietaylorchen/which-computer-to-choose-for-linux-os-with-good-graphical-processing-power-3200</link>
      <guid>https://dev.to/annietaylorchen/which-computer-to-choose-for-linux-os-with-good-graphical-processing-power-3200</guid>
      <description>&lt;p&gt;Currently I use Linuxmint on an average laptop that's custom-built from &lt;a href="https://www.pcspecialist.co.uk/" rel="noopener noreferrer"&gt;PCSpecialist&lt;/a&gt;, part of the reasons I got it is that I need a physical ENGLISH keyboard but it's hard to find those in Sweden. I got it a few years ago and am thinking about upgrading to a desktop. I would love to explore more on graphic design or 3D modeling in the future, so hopefully I can get something more powerful. I'm not so familiar with hardware, would love some help from experts! Thank you! 🙏&lt;/p&gt;

&lt;p&gt;What would you recommend as hardware?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;desktop, physical English keyboard (I have monitor already)&lt;/li&gt;
&lt;li&gt;must be compatible with Linux OS&lt;/li&gt;
&lt;li&gt;can deliver to Sweden without tax and duty (it's damn expensive in Sweden)&lt;/li&gt;
&lt;li&gt;should handle powerful graphical tasks (design, 3d modeling, videos)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Current candidates:&lt;br&gt;
UK:&lt;br&gt;
&lt;a href="https://www.pcspecialist.co.uk/" rel="noopener noreferrer"&gt;PCSpecialist&lt;/a&gt;&lt;br&gt;
&lt;a href="https://junocomputers.com/" rel="noopener noreferrer"&gt;JUNO&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Germany:&lt;br&gt;
&lt;a href="https://www.tuxedocomputers.com/" rel="noopener noreferrer"&gt;TUXEDO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spain:&lt;br&gt;
&lt;a href="https://slimbook.es/en/" rel="noopener noreferrer"&gt;Slimbook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't know anyone else, can perhaps suggest some machines from suppliers I list above? &lt;/p&gt;




&lt;p&gt;UPDATE 2020-10-10 &lt;/p&gt;

&lt;p&gt;I now got my computer from &lt;br&gt;
&lt;a href="https://www.komplett.se/" rel="noopener noreferrer"&gt;https://www.komplett.se/&lt;/a&gt;&lt;br&gt;
Special thanks to &lt;a class="mentioned-user" href="https://dev.to/joelbonetr"&gt;@joelbonetr&lt;/a&gt; for suggestion!&lt;br&gt;
They've assembled all the pieces I chose. It took over a month from order to arrival, which is understandable during pandemic period. Here are what I bought for reference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;computer case: Fractal Design Define C Black&lt;/li&gt;
&lt;li&gt;graphic card: Sapphire Radeon RX 5600 XT PULSE&lt;/li&gt;
&lt;li&gt;processor: AMD Ryzen 5 3600 Processor&lt;/li&gt;
&lt;li&gt;DDR Memory: HyperX Fury DDR4 2666MHz 32GB&lt;/li&gt;
&lt;li&gt;Harddrive: Kingston A2000 500GB NVMe M.2 SSD&lt;/li&gt;
&lt;li&gt;Motherboard: ASUS EX-A320M-GAMING, Socket-AM4&lt;/li&gt;
&lt;li&gt;Powersupply: Corsair CV550, 550W PSU&lt;/li&gt;
&lt;li&gt;Network card: ASUS PCE-AC68 Nätverkskort&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total cost: 11,410 kr / 1,299 USD / 1,098 EUR&lt;/p&gt;

&lt;p&gt;Today I installed my Linuxmint 20 and all the applications I need. The process is quite smooth. Although, at the beginning I was not sure how to do as there is no proper boot menu like I normally saw on laptop, through googling I found that if I turn the "realtek PXE Oprom" off then insert the usb stick it will work. Just in case anyone might also run into issue of not seeing the WIFI detected, you just need to insert the usb stick to install the hardware driver after you install the main OS and restart it. For fast installation, if you have wired connection, better use that than WIFI. &lt;/p&gt;

&lt;p&gt;I did a few tests on sites featuring 3D models but since I don't play games I probably haven't tested it to its maximum ability haha... hope I can test something serious soon such as video editing, which has been slow and clumsy on my previous laptop.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>linux</category>
      <category>computer</category>
      <category>hardware</category>
    </item>
  </channel>
</rss>
