<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Jin Li</title><link>https://blog.jinli.io/en/post/</link><description>Recent content in Posts on Jin Li</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2026 Jin Li</copyright><lastBuildDate>Sat, 15 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.jinli.io/en/post/index.xml" rel="self" type="application/rss+xml"/><item><title>Migrating from Powerlevel10k to Oh My Posh</title><link>https://blog.jinli.io/en/p/migrating-from-powerlevel10k-to-oh-my-posh/</link><pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/migrating-from-powerlevel10k-to-oh-my-posh/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Why migrate?
 &lt;div id="why-migrate" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-migrate" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;My previous shell setup used &lt;a href="https://ohmyz.sh/" target="_blank" rel="noreferrer"&gt;Oh My Zsh&lt;/a&gt; with
&lt;a href="https://github.com/romkatv/powerlevel10k" target="_blank" rel="noreferrer"&gt;Powerlevel10k&lt;/a&gt;. It was polished and
fast, but it tied the prompt to Zsh. I wanted the same visual language on
macOS, Linux, HPC clusters, and Windows PowerShell, so I moved the prompt to
&lt;a href="https://ohmyposh.dev/" target="_blank" rel="noreferrer"&gt;Oh My Posh&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Oh My Posh separates the prompt theme from the shell. One JSON configuration can
therefore be initialized by both Zsh and PowerShell. The result is my Koi-fish
(锦鲤) theme, &lt;a href="https://github.com/jin-li/ShellConfig/blob/main/jinli.omp.json" target="_blank" rel="noreferrer"&gt;&lt;code&gt;jinli.omp.json&lt;/code&gt;&lt;/a&gt;,
with Catppuccin-inspired colors.&lt;/p&gt;</description></item><item><title>Automatic TLS Certificates with Traefik and Let's Encrypt</title><link>https://blog.jinli.io/en/p/automatic-tls-certificates-with-traefik-and-lets-encrypt/</link><pubDate>Sun, 05 Jul 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/automatic-tls-certificates-with-traefik-and-lets-encrypt/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I was previously using Cloudflare Tunnel (free plan) to reverse proxy my Nextcloud container. While convenient, the free tier has a &lt;strong&gt;100MB upload limitation&lt;/strong&gt; that became problematic for my usage.&lt;/p&gt;
&lt;p&gt;This article documents my migration from Cloudflare Tunnel to direct Traefik reverse proxy with Let&amp;rsquo;s Encrypt TLS certificates, including the complete setup, issues encountered, and troubleshooting steps.&lt;/p&gt;</description></item><item><title>Deploying Local LLMs for Agent Use: A Comprehensive Guide</title><link>https://blog.jinli.io/en/p/deploying-local-llms-for-agent-use-a-comprehensive-guide/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/deploying-local-llms-for-agent-use-a-comprehensive-guide/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Running large language models (LLMs) locally has become increasingly practical as quantization techniques and hardware capabilities have advanced. For agent frameworks like &lt;strong&gt;OpenClaw&lt;/strong&gt; and &lt;strong&gt;Hermes&lt;/strong&gt;, having a local LLM with a large context window (100k+ tokens) is essential for maintaining conversation history and executing complex multi-step tasks.&lt;/p&gt;
&lt;p&gt;This guide covers the best models available in June 2026 for machines with &lt;strong&gt;128GB VRAM&lt;/strong&gt; (such as Strix Halo setups), how to deploy them using &lt;strong&gt;Ollama in Docker&lt;/strong&gt;, and how to leverage &lt;strong&gt;speculative decoding&lt;/strong&gt; with Multi-Token Prediction (MTP) for faster inference.&lt;/p&gt;</description></item><item><title>OpenClaw AI Assistant Setup Summary</title><link>https://blog.jinli.io/en/p/openclaw-ai-assistant-setup-summary/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/openclaw-ai-assistant-setup-summary/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After setting up my AI assistant OpenClaw, I&amp;rsquo;m documenting the entire setup process including configuring online models, local models, testing model performance, and adding skills.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A server or local computer&lt;/li&gt;
&lt;li&gt;Docker and docker-compose installed&lt;/li&gt;
&lt;li&gt;Network configured (Tailscale VPN)&lt;/li&gt;
&lt;li&gt;Ollama installed (for running local models)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;OpenClaw Overview
 &lt;div id="openclaw-overview" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#openclaw-overview" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;OpenClaw is an AI assistant framework supporting multiple model providers, including online and local models. Key features:&lt;/p&gt;</description></item><item><title>Local Large Language Model (2): Comparison of vLLM and Ollama and Deploy Open WebUI Frontend</title><link>https://blog.jinli.io/en/p/local-large-language-model-2-comparison-of-vllm-and-ollama-and-deploy-open-webui-frontend/</link><pubDate>Fri, 13 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/local-large-language-model-2-comparison-of-vllm-and-ollama-and-deploy-open-webui-frontend/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Previously, we discussed building private large language model services, where we used Ollama as the backend service and LobeChat as the frontend, communicating through API calls to the backend Ollama to implement conversations.&lt;/p&gt;
&lt;p&gt;Recently, I have been trying to use OpenClaw, but its token consumption rate is too fast, so I thought about running a local large language model to provide tokens. After talking with ChatGPT, it told me that in this case, it&amp;rsquo;s better to use vLLM rather than Ollama, because vLLM provides API compatibility with OpenAI, supports Copilot, and has better performance. So I decided to switch to vLLM.&lt;/p&gt;</description></item><item><title>Container (7): Building Your Own Container Image Registry</title><link>https://blog.jinli.io/en/p/container-7-building-your-own-container-image-registry/</link><pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container-7-building-your-own-container-image-registry/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Due to the network environment issues in China, we cannot directly pull container images from Docker Hub. To facilitate the deployment of some container services on computers within China, I decided to build my own container image registry (i.e., Registry) on a server located overseas.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Solution
 &lt;div id="solution" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#solution" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Docker official provides the image of container image registry &lt;a href="https://github.com/distribution/distribution" target="_blank" rel="noreferrer"&gt;Registry&lt;/a&gt;, we can use this image to deploy our own container image registry.&lt;/p&gt;</description></item><item><title>Building a Personal Website (Part 5): Choosing and Configuring a Content Management System (CMS) for Hugo</title><link>https://blog.jinli.io/en/p/building-a-personal-website-part-5-choosing-and-configuring-a-content-management-system-cms-for-hugo/</link><pubDate>Mon, 09 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/building-a-personal-website-part-5-choosing-and-configuring-a-content-management-system-cms-for-hugo/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This website has been online for five years, consistently using the Hugo framework. Hugo is an excellent framework, but after years of use, I&amp;rsquo;ve encountered some inconveniences.&lt;/p&gt;
&lt;p&gt;Specifically, since my website is deployed using Docker containers and the blog content is managed through a GitHub repository, every time I need to update the blog content, I have to modify markdown files on my local computer, commit to the GitHub repository, and then pull the updates on the server, rebuild the container, and restart it.&lt;/p&gt;</description></item><item><title>Linux System Monitor: Conky</title><link>https://blog.jinli.io/en/p/linux-system-monitor-conky/</link><pubDate>Fri, 14 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/linux-system-monitor-conky/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When using Linux systems, it is often necessary to monitor the system status in real-time, such as monitoring CPU and GPU usage and temperature while gaming, checking VRAM usage when training machine learning models, or tracking network speed when downloading large files. Although there are graphical tools like System Monitor and command-line tools like &lt;code&gt;htop&lt;/code&gt; and &lt;code&gt;nvidia-smi&lt;/code&gt; available for monitoring system status, these tools usually require manual opening and do not display information directly on the desktop, which can be inconvenient at times.&lt;/p&gt;</description></item><item><title>Installation and Usage of ClipCascade: A Free Cross-Platform Clipboard Sharing Software</title><link>https://blog.jinli.io/en/p/installation-and-usage-of-clipcascade-a-free-cross-platform-clipboard-sharing-software/</link><pubDate>Tue, 07 Oct 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/installation-and-usage-of-clipcascade-a-free-cross-platform-clipboard-sharing-software/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In a previous article, I introduced several software solutions for sharing keyboard and mouse across multiple computers, including Barrier, InputLeap, and Deskflow. These tools greatly enhance the experience of working with multiple computers by allowing seamless sharing of keyboard and mouse input between Windows, macOS, and Linux systems. However, I discovered that the clipboard sharing feature is not available in Wayland environments. Unfortunately, my primary computer runs Fedora 42, which uses Wayland as its default graphical interface, preventing me from using the clipboard sharing functionality of Barrier, InputLeap, and Deskflow on this machine.&lt;/p&gt;</description></item><item><title>Nvidia GPU (4): Containerized Configuration of Nvidia GPU for CUDA Programming and Deep Learning Environment</title><link>https://blog.jinli.io/en/p/nvidia-gpu-4-containerized-configuration-of-nvidia-gpu-for-cuda-programming-and-deep-learning-environment/</link><pubDate>Wed, 20 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/nvidia-gpu-4-containerized-configuration-of-nvidia-gpu-for-cuda-programming-and-deep-learning-environment/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the fourth article in the &amp;ldquo;Nvidia GPU&amp;rdquo; series, which mainly records how to use Nvidia GPU, especially on Linux systems. In previous articles, I recorded the settings for using Nvidia GPU on Ubuntu, including games, CUDA programming, deep learning, Docker containers, etc. Later, I switched to Fedora system, thinking that configuring Nvidia GPU for CUDA programming and deep learning environment on Fedora would be similar to that on Ubuntu, and with the support of RPM Fusion, installation and configuration would be more convenient. However, I actually encountered unexpected difficulties, so I had to write another article to record these problems and solutions.&lt;/p&gt;</description></item><item><title>Boot Configuration (II): Dual Boot Setup for Windows/Linux on Dual Drives</title><link>https://blog.jinli.io/en/p/boot-configuration-ii-dual-boot-setup-for-windows/linux-on-dual-drives/</link><pubDate>Sat, 16 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/boot-configuration-ii-dual-boot-setup-for-windows/linux-on-dual-drives/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the second article in the &amp;ldquo;Boot Configuration&amp;rdquo; series. I never expected such a simple topic could turn into a series, because I thought I had already explained the relevant concepts of boot configuration clearly in the first article, and I had successfully configured dual boot many times. However, recently I encountered a huge pitfall while setting up a dual boot with Windows and Linux on separate drives, so I felt it was necessary to write another article to document it.&lt;/p&gt;</description></item><item><title>Nvidia GPU (3): Gaming, CUDA, Deep Learning, Docker, etc. on Fedora</title><link>https://blog.jinli.io/en/p/nvidia-gpu-3-gaming-cuda-deep-learning-docker-etc.-on-fedora/</link><pubDate>Fri, 15 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/nvidia-gpu-3-gaming-cuda-deep-learning-docker-etc.-on-fedora/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the third article in the &amp;ldquo;Nvidia GPU&amp;rdquo; series, which mainly documents how to use Nvidia GPUs, especially on Linux systems. In the previous articles, I documented the relevant settings for using Nvidia GPUs on Ubuntu, including gaming, CUDA programming, deep learning, Docker containers, etc. Now I have migrated from Ubuntu to Fedora, and the settings for using Nvidia GPUs on Fedora are different from those on Ubuntu, so I am documenting them here.&lt;/p&gt;</description></item><item><title>SSH: SSH to Windows, SSH Configuration, Passwordless Login, VSCode Remote Development, etc.</title><link>https://blog.jinli.io/en/p/ssh-ssh-to-windows-ssh-configuration-passwordless-login-vscode-remote-development-etc./</link><pubDate>Mon, 11 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/ssh-ssh-to-windows-ssh-configuration-passwordless-login-vscode-remote-development-etc./</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;SSH (Secure Shell) is a widely used remote login protocol. I have used it extensively, and setting it up is not difficult, with many configurations being one-time setups. However, most of these configurations are only done when changing computers or reinstalling the system, leading to a low usage frequency. As a result, I often have to look up related information each time.&lt;/p&gt;</description></item><item><title>Virtual Private Network VPN (3): Using Headscale to Build Your Own Tailscale Server</title><link>https://blog.jinli.io/en/p/virtual-private-network-vpn-3-using-headscale-to-build-your-own-tailscale-server/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/virtual-private-network-vpn-3-using-headscale-to-build-your-own-tailscale-server/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the third article in the &amp;ldquo;Virtual Private Network VPN&amp;rdquo; series. In the first two articles, I introduced the basic concepts and use cases of VPNs, as well as how to set up a private virtual network using Tailscale. Other articles in this series can be found at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/private-virtual-network-vpn-1-setting-up-a-vpn-with-shadowsocks-on-a-cloud-server/" &gt;Private Virtual Network VPN (1): Setting up a VPN with Shadowsocks on a Cloud Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/private-virtual-network-vpn-2-basic-concepts-and-tailscale-setup-guide/" &gt;Private Virtual Network VPN (2): Basic Concepts and Guide to Setting up with Tailscale&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the previous article, I explained how to set up a private virtual network using Tailscale. Tailscale is a VPN solution based on WireGuard that allows us to quickly create a private virtual network. However, the official version of Tailscale uses Tailscale&amp;rsquo;s control servers, meaning our data and network traffic pass through Tailscale&amp;rsquo;s servers. Although this data and traffic are encrypted, if we want complete control over our network environment or have privacy and security concerns, we can set up our own Tailscale control server. The tool to achieve this is Headscale.&lt;/p&gt;</description></item><item><title>Obsidian (2): Deployment and Use of Web-based Obsidian</title><link>https://blog.jinli.io/en/p/obsidian-2-deployment-and-use-of-web-based-obsidian/</link><pubDate>Mon, 21 Jul 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/obsidian-2-deployment-and-use-of-web-based-obsidian/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In the previous post, I covered how to use Obsidian and Nextcloud to manage notes. The title of the previous article uses the word &amp;ldquo;all platform&amp;rdquo;, which means that Obsidian supports multiple platforms such as Windows, Linux, Mac, Android, etc. Generally speaking, this is enough, but it is still inconvenient in some scenarios.&lt;/p&gt;</description></item><item><title>Access Personal Website from Internet (3): Using Cloudflare Tunnel for Reverse Proxy</title><link>https://blog.jinli.io/en/p/access-personal-website-from-internet-3-using-cloudflare-tunnel-for-reverse-proxy/</link><pubDate>Mon, 02 Jun 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/access-personal-website-from-internet-3-using-cloudflare-tunnel-for-reverse-proxy/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In order to access the websites and services I have set up on my personal server from the internet, my previous approach was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use a Dynamic DNS (DDNS) service to bind my public IP address to a domain name.&lt;/li&gt;
&lt;li&gt;Then configure Nginx as a reverse proxy to point the domain name to the services on my server.&lt;/li&gt;
&lt;li&gt;Finally, use acme to obtain SSL certificates for HTTPS access.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Later, to containerize the reverse proxy, I switched to Traefik, which combined steps 2 and 3 into a more convenient solution. You can refer to my previous articles for these solutions:&lt;/p&gt;</description></item><item><title>Homelab（1）：Using Kubernetes (K8s) or K3s to Build a Home Lab</title><link>https://blog.jinli.io/en/p/homelab1using-kubernetes-k8s-or-k3s-to-build-a-home-lab/</link><pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/homelab1using-kubernetes-k8s-or-k3s-to-build-a-home-lab/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After about 5 years of building my own home server and using container technology to deploy various private services, I have become familiar with a solution that manages all containers using Docker Compose. This solution is elegant and useful, but it is limited to a single computer. Recently, I suddenly had the need to manage multiple computers, and I finally began to feel the necessity of transitioning from a single server to a server cluster, or what is known as a Homelab.&lt;/p&gt;</description></item><item><title>Accessing Personal Websites from the Public Network (2) - Traefik Reverse Proxy Configuration</title><link>https://blog.jinli.io/en/p/accessing-personal-websites-from-the-public-network-2-traefik-reverse-proxy-configuration/</link><pubDate>Sat, 31 May 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/accessing-personal-websites-from-the-public-network-2-traefik-reverse-proxy-configuration/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I previously used Nginx as a reverse proxy to access websites on my private server. At that time, Nginx was installed directly on the computer without containerization, which meant that when I wanted to migrate these services to other computers later, I had to reconfigure Nginx and reconfigure SSL certificates, etc.&lt;/p&gt;
&lt;p&gt;So I decided to containerize the reverse proxy service as well, to facilitate future management and migration. I saw many examples of using Traefik in Docker online, so I decided to migrate from Nginx to Traefik.&lt;/p&gt;</description></item><item><title>Container (6): Docker Issues and Bad Habits</title><link>https://blog.jinli.io/en/p/container-6-docker-issues-and-bad-habits/</link><pubDate>Wed, 21 May 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container-6-docker-issues-and-bad-habits/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the sixth article about Docker containers. The links to other articles in this series are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./" &gt;Container (1): Introduction to Container-Related Knowledge - Containerization, Docker, Docker Compose, Kubernetes / K8s, etc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-2-the-best-practice-guide-for-dockerdocker-compose-and-portainer/" &gt;Container (2): Docker Best Practices Guide - Docker Compose and Portainer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-3-the-best-practice-guide-for-dockermanaging-data-volumes/" &gt;Container (3): Docker Best Practices Guide - Managing Data Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-4-docker-best-practices-guide-container-update-upgrade-and-migration/" &gt;Container (4): Docker Best Practices Guide - Container Updates, Upgrades, and Migrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-5-docker-best-practices-guide-container-update-monitoring-tool-wud-whats-up-docker/" &gt;Container (5): Docker Best Practices Guide - Container Update Monitoring Tool WUD (What&amp;rsquo;s Up Docker)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After using Docker for a while, through discussions with ChatGPT, I gradually realized some misconceptions and bad habits I had regarding Docker&amp;rsquo;s operation logic. To prevent others from making the same mistakes, I decided to document these misconceptions and bad habits for reference. I will continue to update this article whenever I encounter new issues.&lt;/p&gt;</description></item><item><title>Authentication: Deploying Authelia for Private Identity Service</title><link>https://blog.jinli.io/en/p/authentication-deploying-authelia-for-private-identity-service/</link><pubDate>Sat, 17 May 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/authentication-deploying-authelia-for-private-identity-service/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I previously thought it was unnecessary to set up my own identity authentication service, as I could simply create users and passwords in the services I deployed. However, while preparing to set up a HeadScale (self-hosted version of Tailscale) server, I found that the available UI options for HeadScale do not support direct user and password creation.&lt;/p&gt;</description></item><item><title>Private Virtual Network VPN (2): Basic Concepts and Tailscale Setup Guide</title><link>https://blog.jinli.io/en/p/private-virtual-network-vpn-2-basic-concepts-and-tailscale-setup-guide/</link><pubDate>Sun, 04 May 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/private-virtual-network-vpn-2-basic-concepts-and-tailscale-setup-guide/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the second article in the &amp;ldquo;Private Virtual Network VPN&amp;rdquo; series. In the first article, I introduced how to set up a Shadowsocks service on a cloud server to achieve secure internet access from abroad based on my own needs. This article will cover the basic concepts of VPNs and focus on how to use Tailscale to set up a private virtual network. The other articles in this series are as follows:&lt;/p&gt;</description></item><item><title>Obsidian (1): All-platform Notes Management Software</title><link>https://blog.jinli.io/en/p/obsidian-1-all-platform-notes-management-software/</link><pubDate>Thu, 01 May 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/obsidian-1-all-platform-notes-management-software/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I used to manage my notes with Microsoft&amp;rsquo;s OneNote. OneNote is powerful, capable of tracking note revision history, and can sync notes using OneDrive. However, it has many drawbacks. The most unbearable one for me is its default font, Calibri, which cannot be changed (or even if changed, it never takes effect). I really don&amp;rsquo;t understand why such a simple thing as changing the default font has not been resolved for so many years. I have to tedious change the font to Times New Roman every time.&lt;/p&gt;</description></item><item><title>Container (5): Docker Best Practices Guide - Container Update Monitoring Tool WUD (What's Up Docker)</title><link>https://blog.jinli.io/en/p/container-5-docker-best-practices-guide-container-update-monitoring-tool-wud-whats-up-docker/</link><pubDate>Sat, 26 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container-5-docker-best-practices-guide-container-update-monitoring-tool-wud-whats-up-docker/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the fifth article introducing Docker containers. Links to other articles in this series are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./" &gt;Container (1): Introduction to Container-related Knowledge - Containerization, Docker, Docker Compose, Kubernetes / K8s, etc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-2-the-best-practice-guide-for-dockerdocker-compose-and-portainer/" &gt;Container (2): Docker Best Practices Guide - Docker Compose and Portainer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-3-the-best-practice-guide-for-dockermanaging-data-volumes/" &gt;Container (3): Docker Best Practices Guide - Volume Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-4-docker-best-practices-guide-container-update-upgrade-and-migration/" &gt;Container (4): Docker Best Practices Guide - Container Update, Upgrade, and Migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-6-docker-issues-and-bad-habits/" &gt;Container (6): Misconceptions, Bad Habits, and Issues When Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The previous article mentioned how to update or upgrade containers. When I was updating Docker containers, I found that many of them had not been updated for two or three years, and the version gap was too large, which led to some containers being unable to update directly. Some containers, on the other hand, had not been updated much and could be updated directly. Since the update frequency of each container is different, and there are many containers created, I don&amp;rsquo;t want to manually check whether the container has updates available every few days. So I thought of a question: Is there a tool that can automatically monitor container updates?&lt;/p&gt;</description></item><item><title>Container (4): Docker Best Practices Guide - Container Update, Upgrade, and Migration</title><link>https://blog.jinli.io/en/p/container-4-docker-best-practices-guide-container-update-upgrade-and-migration/</link><pubDate>Thu, 24 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container-4-docker-best-practices-guide-container-update-upgrade-and-migration/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the fourth article introducing Docker containers. Links to other articles in this series are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./" &gt;Container (1): Introduction to Container-related Knowledge - Containerization, Docker, Docker Compose, Kubernetes / K8s, etc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-2-the-best-practice-guide-for-dockerdocker-compose-and-portainer/" &gt;Container (2): Docker Best Practices Guide - Docker Compose and Portainer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-3-the-best-practice-guide-for-dockermanaging-data-volumes/" &gt;Container (3): Docker Best Practices Guide - Volume Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-5-docker-best-practices-guide-container-update-monitoring-tool-wud-whats-up-docker/" &gt;Container (5): Docker Best Practices Guide - Container Update Monitoring Tool WUD (What&amp;rsquo;s Up Docker)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-6-docker-issues-and-bad-habits/" &gt;Container (6): Misconceptions, Bad Habits, and Issues When Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After creating a container, we may need to update or upgrade it to use new features or fix bugs. If we change servers or upgrade the hardware of our computer, we may need to migrate the container to the new server or to a new hard drive.&lt;/p&gt;</description></item><item><title>Container (3): The Best Practice Guide for Docker——Managing Data Volumes</title><link>https://blog.jinli.io/en/p/container-3-the-best-practice-guide-for-dockermanaging-data-volumes/</link><pubDate>Wed, 23 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container-3-the-best-practice-guide-for-dockermanaging-data-volumes/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the third article in the Docker series. The links to the other articles in this series are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./" &gt;Container (1): Introduction to Container-related Knowledge——Containerization, Docker, Docker-compose, Kubernetes / K8s, etc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-2-the-best-practice-guide-for-dockerdocker-compose-and-portainer/" &gt;Container (2): The Best Practice Guide for Docker——docker-compose and Portainer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-4-docker-best-practices-guide-container-update-upgrade-and-migration/" &gt;Container (4): The Best Practice Guide for Docker——Container Update, Upgrade, and Migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-5-docker-best-practices-guide-container-update-monitoring-tool-wud-whats-up-docker/" &gt;Container (5): The Best Practice Guide for Docker——Container Update Monitoring Tool WUD (What&amp;rsquo;s Up Docker)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-6-docker-issues-and-bad-habits/" &gt;Container (6): Misconceptions, Bad Habits, and Issues When Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the previous two articles, we introduced the basic concepts of containers and how to use them, as well as the best practices for using containers.&lt;/p&gt;</description></item><item><title>Dynamic Domain Name System -- Cloudflare</title><link>https://blog.jinli.io/en/p/dynamic-domain-name-system--cloudflare/</link><pubDate>Thu, 10 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/dynamic-domain-name-system--cloudflare/</guid><description>&lt;p&gt;Previously, I wrote an article about Dynamic Domain Name System using Alibaba Cloud&amp;rsquo;s API. Recently, I transferred the domain to Cloudflare and recorded how to use Cloudflare&amp;rsquo;s API for Dynamic Domain Name System.&lt;/p&gt;
&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;&lt;strong&gt;Motivation&lt;/strong&gt;
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In previous articles, I mentioned that due to work reasons, I often need to use &lt;code&gt;ssh&lt;/code&gt; to log into personal computers at home and in the office. However, these computers generally do not have a fixed IP address, so when the IP address changes, it is often impossible to connect to the computer in time. Therefore, I considered using a domain name instead of an IP address to access these computers and purchased one or two inexpensive domains. For a long time, I used Alibaba Cloud&amp;rsquo;s domain resolution service. You can refer to the article &lt;a href="https://blog.jinli.io/en/p/how-this-website-was-built-1--purchase-and-configure-a-personal-domain-name/" &gt;“Establishing a Personal Website (Part 1): Purchasing a Personal Domain and Configuring Dynamic Domain Name System”&lt;/a&gt; for more information on dynamic domain name resolution on Alibaba Cloud.&lt;/p&gt;</description></item><item><title>Remote Desktop (II): VNC Configuration</title><link>https://blog.jinli.io/en/p/remote-desktop-ii-vnc-configuration/</link><pubDate>Tue, 08 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/remote-desktop-ii-vnc-configuration/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Previously, I was using AnyDesk as my remote desktop software, but recently the IT department at my school mentioned that AnyDesk has security vulnerabilities and can no longer be used. On Linux, the only allowed remote desktop software are VNC and XRDP. Both VNC and RDP are remote desktop protocols, but VNC is an open-source protocol, while RDP is a proprietary protocol by Microsoft. The advantage of VNC is its cross-platform support, including Linux, Windows, macOS, etc.; although RDP is proprietary to Microsoft, there are open-source implementations available on Linux, such as XRDP.&lt;/p&gt;</description></item><item><title>Nvidia GPU (2): Accelerate Video Editing and Transcoding for FFmpeg Using GPU</title><link>https://blog.jinli.io/en/p/nvidia-gpu-2-accelerate-video-editing-and-transcoding-for-ffmpeg-using-gpu/</link><pubDate>Thu, 05 Dec 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/nvidia-gpu-2-accelerate-video-editing-and-transcoding-for-ffmpeg-using-gpu/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;FFmpeg is a very powerful audio and video processing tool that can be used for editing, transcoding, merging, splitting, extracting video and audio, etc. FFmpeg is a free and open-source software, initially initiated by French programmer Fabrice Bellard and now maintained by Michael Niedermayer. Many players, video editing software, transcoding software on the market, such as Blender, Kodi, Plex, Shotcut, VLC media player, YouTube, etc., are based on FFmpeg. Of course, there are also many software that use FFmpeg&amp;rsquo;s code but do not comply with FFmpeg&amp;rsquo;s open-source agreement, and are nailed to the &lt;a href="https://scilxurkel001.github.io/archive/ffmpeg-shame/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;FFmpeg Pillory&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (7): Language Model (II) - Implement Word-Level Language Model with Transformer</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-7-language-model-ii-implement-word-level-language-model-with-transformer/</link><pubDate>Mon, 23 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-7-language-model-ii-implement-word-level-language-model-with-transformer/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the 7th article in the &lt;a href="https://jinli.io/categories/machine-learning/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;Learn PyTorch by Examples&amp;rdquo;&lt;/a&gt; series. In the 6th article &lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-6-language-model-i--implementing-a-word-level-language-model-with-lstm/" &gt;&amp;ldquo;Learn PyTorch by Examples (6): Language Model (I) &amp;ndash; Implementing a Word-Level Language Model with LSTM&amp;rdquo;&lt;/a&gt;, we briefly introduced how to implement a word-level language model using LSTM.&lt;/p&gt;
&lt;p&gt;LSTM and other models based on Recurrent Neural Networks (RNN) have been widely used in natural language processing, but these models have some problems when dealing with long-distance dependency problems, such as vanishing gradients and exploding gradients. To solve these problems, researchers proposed the Transformer model, which uses the attention mechanism to better handle long-distance dependency problems. In this article, we will briefly introduce the Transformer model and use the Transformer to implement a simple word-level language model. This article refers to the &lt;code&gt;word_language_model&lt;/code&gt; example in the official PyTorch examples.&lt;/p&gt;</description></item><item><title>Linux System: Share Steam Games Among Multiple Users (Ubuntu as an Example)</title><link>https://blog.jinli.io/en/p/linux-system-share-steam-games-among-multiple-users-ubuntu-as-an-example/</link><pubDate>Thu, 19 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/linux-system-share-steam-games-among-multiple-users-ubuntu-as-an-example/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I installed the Steam game platform and Proton compatibility layer on my Ubuntu computer before, which allows running Windows games on Linux. However, I didn&amp;rsquo;t play games much, so I didn&amp;rsquo;t study it carefully. I just knew that the Proton compatibility layer is quite powerful, and most games run without any problems, even if the &amp;ldquo;system requirements&amp;rdquo; of the game only show support for Windows systems.&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (6): Language Model (I) -- Implementing a Word-Level Language Model with LSTM</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-6-language-model-i--implementing-a-word-level-language-model-with-lstm/</link><pubDate>Mon, 09 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-6-language-model-i--implementing-a-word-level-language-model-with-lstm/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the sixth article in the &lt;a href="https://jinli.io/en/categories/machine-learning/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;Learning PyTorch by Examples&amp;rdquo;&lt;/a&gt; series. In the fourth and fifth articles, we introduced the sequence prediction problem and implemented the prediction of the sine function with RNN, GRU, and LSTM.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-4-sequence-prediction-i--recurrent-neural-networks-rnn/" &gt;&amp;ldquo;Learn PyTorch by Examples (4): Sequence Prediction (I) &amp;ndash; Recurrent Neural Networks (RNN)&amp;rdquo; &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-5-sequence-prediction-ii--gated-recurrent-unit-gru-and-long-short-term-memory-lstm/" &gt;&amp;ldquo;Learn PyTorch by Examples (5): Sequence Prediction (II) &amp;ndash; Gated Recurrent Unit (GRU) and Long Short-Term Memory (LSTM)&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the fourth article, we mentioned that in addition to time series like the sine function, sequence data can also be word sequences in language models. In this article, we will introduce how to implement a word-level language model with LSTM.&lt;/p&gt;</description></item><item><title>Local Large Language Model (1): Deploy on Local or Server with ollama and LobeChat</title><link>https://blog.jinli.io/en/p/local-large-language-model-1-deploy-on-local-or-server-with-ollama-and-lobechat/</link><pubDate>Tue, 13 Aug 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/local-large-language-model-1-deploy-on-local-or-server-with-ollama-and-lobechat/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After installing a graphics card on my server, I want to make full use of this graphics card, so I thought of deploying a large language model. In this way, I don&amp;rsquo;t need to subscribe to ChatGPT every month. After all, I don&amp;rsquo;t use ChatGPT very often, and the 20 USD monthly subscription fee is a bit expensive. If I can deploy a private large language model, I can use various large language models, not limited to ChatGPT. Even if the open-source large language model is not as good as the paid version of ChatGTP, I can use OpenAI&amp;rsquo;s API to call ChatGPT&amp;rsquo;s interface, which can achieve almost the same effect as using the paid version of ChatGPT, but the monthly fee should be less than 20 USD.&lt;/p&gt;</description></item><item><title>Container (2): The Best Practice Guide for Docker——docker-compose and Portainer</title><link>https://blog.jinli.io/en/p/container-2-the-best-practice-guide-for-dockerdocker-compose-and-portainer/</link><pubDate>Mon, 12 Aug 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container-2-the-best-practice-guide-for-dockerdocker-compose-and-portainer/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the second article in the series introducing Docker containers. The links to other articles in this series are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./" &gt;Container(1): Introduction to Container-related Knowledge——Containerization, Docker, Docker-compose, Kubernetes / K8s, etc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-3-the-best-practice-guide-for-dockermanaging-data-volumes/" &gt;Container(3): Docker Best Practices Guide——Volume Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-4-docker-best-practices-guide-container-update-upgrade-and-migration/" &gt;Container(4): Docker Best Practices Guide——Container Update, Upgrade, and Migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-5-docker-best-practices-guide-container-update-monitoring-tool-wud-whats-up-docker/" &gt;Container(5): Docker Best Practices Guide——Container Update Monitoring Tool WUD (What&amp;rsquo;s Up Docker)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/container-6-docker-issues-and-bad-habits/" &gt;Container(6): Misconceptions, Bad Habits, and Issues When Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;a href="https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./" &gt;&amp;ldquo;Container(1): Introduction to Container-related Knowledge——Containerization, Docker, Docker-compose, Kubernetes / K8s, etc.&amp;rdquo;&lt;/a&gt;, we introduced the concept of containerization and how to use Docker for containerization. When using Docker in practice, we may encounter some problems, such as:&lt;/p&gt;</description></item><item><title>Nvidia GPU (1): Games, CUDA Programming, Deep Learning, Docker Containers, etc. on Ubuntu</title><link>https://blog.jinli.io/en/p/nvidia-gpu-1-games-cuda-programming-deep-learning-docker-containers-etc.-on-ubuntu/</link><pubDate>Mon, 12 Aug 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/nvidia-gpu-1-games-cuda-programming-deep-learning-docker-containers-etc.-on-ubuntu/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Recently, I bought an Nvidia RTX 4060 Ti (8GB) graphics card. To make full use of it, I want to use this graphics card on Ubuntu for games, CUDA programming, deep learning, etc. However, using Nvidia graphics cards on Ubuntu is not an easy task and requires some settings. Here I record the settings I use Nvidia graphics cards on Ubuntu.&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (5): Sequence Prediction (II) -- Gated Recurrent Unit (GRU) and Long Short-Term Memory (LSTM)</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-5-sequence-prediction-ii--gated-recurrent-unit-gru-and-long-short-term-memory-lstm/</link><pubDate>Sun, 04 Aug 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-5-sequence-prediction-ii--gated-recurrent-unit-gru-and-long-short-term-memory-lstm/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the fifth article in the &lt;a href="https://jinli.io/en/categories/machine-learning/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;Learn PyTorch by Examples&amp;rdquo;&lt;/a&gt; series. In the fourth article &lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-4-sequence-prediction-i--recurrent-neural-networks-rnn/" &gt;&amp;ldquo;Learn PyTorch by Examples (4): Sequence Prediction (I) &amp;ndash; Recurrent Neural Networks (RNN)&amp;rdquo;&lt;/a&gt;, we introduced the sequence prediction problem and how to use a simple Recurrent Neural Network (RNN) to predict the sine function. In this article, we will go further and introduce two other commonly used neural networks for sequence prediction: Gated Recurrent Unit (GRU) and Long Short-Term Memory (LSTM).&lt;/p&gt;</description></item><item><title>Python Environment Management with venv/conda/mamba</title><link>https://blog.jinli.io/en/p/python-environment-management-with-venv/conda/mamba/</link><pubDate>Sun, 21 Jul 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/python-environment-management-with-venv/conda/mamba/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When developing with Python, I encountered many situations where I needed to configure the environment. Sometimes I need to install different versions of Python, sometimes I need to install different Python packages, and sometimes I need to install different versions of the same Python package.&lt;/p&gt;
&lt;p&gt;At the beginning, I basically followed the tutorials on the Internet. Different Python projects may use different environment management tools, and I have used &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;conda&lt;/code&gt;, &lt;code&gt;mamba&lt;/code&gt;, &lt;code&gt;virtualenv&lt;/code&gt;, &lt;code&gt;venv&lt;/code&gt;, etc. These tools have their own advantages and disadvantages. Sometimes I also mix them, which leads to confusion of environment variables and conflicts.&lt;/p&gt;</description></item><item><title>Remote Desktop (1): Install and Use AnyDesk on All Platforms</title><link>https://blog.jinli.io/en/p/remote-desktop-1-install-and-use-anydesk-on-all-platforms/</link><pubDate>Sun, 14 Jul 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/remote-desktop-1-install-and-use-anydesk-on-all-platforms/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I have several computers at home and in the office, running operating systems including Windows, macOS, and Linux.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;There are many remote desktop software on the market, such as &lt;a href="https://www.teamviewer.com/en-us/?utm_source=google&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=us%7Cb%7Cpr%7C22%7Caug%7Ctv-core-brand-only-exact-sn%7Cnew%7Ct0%7C0&amp;amp;utm_content=Exact&amp;amp;utm_term=teamviewer" target="_blank" rel="noreferrer"&gt;&lt;em&gt;Teamviewer&lt;/em&gt;&lt;/a&gt;, &lt;a href="https://remotedesktop.google.com/" target="_blank" rel="noreferrer"&gt;&lt;em&gt;Chrome Remote Desktop&lt;/em&gt;&lt;/a&gt;, &lt;a href="https://www.todesk.com/" target="_blank" rel="noreferrer"&gt;&lt;em&gt;ToDesk&lt;/em&gt;&lt;/a&gt;, &lt;a href="https://rustdesk.com/" target="_blank" rel="noreferrer"&gt;RustDesk&lt;/a&gt;, etc. I used &lt;em&gt;Teamviewer&lt;/em&gt; before, but the free version of &lt;em&gt;Teamviewer&lt;/em&gt; has a time limit. I used it for a while and then I don&amp;rsquo;t know why my free use qualification was canceled, so I started using AnyDesk.&lt;/p&gt;</description></item><item><title>Installing and Configuring Arch Linux</title><link>https://blog.jinli.io/en/p/installing-and-configuring-arch-linux/</link><pubDate>Sun, 30 Jun 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/installing-and-configuring-arch-linux/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I have an old Surface Pro 6 from 2018, which is now a bit outdated in performance, but still usable for playing around. So I decided to install one or two lightweight Linux systems to familiarize myself with different Linux distributions and prepare for updating the Linux system on my main machine.&lt;/p&gt;
&lt;p&gt;I have always heard that Arch Linux is the &amp;ldquo;cult&amp;rdquo; of Linux distributions, known for its minimalist, highly customizable, and rolling update features, so I decided to give it a try and see how &amp;ldquo;cult&amp;rdquo; Arch Linux really is.&lt;/p&gt;</description></item><item><title>Multi-System Boot Loader Configuration</title><link>https://blog.jinli.io/en/p/multi-system-boot-loader-configuration/</link><pubDate>Fri, 24 May 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/multi-system-boot-loader-configuration/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I have installed dual or multiple systems on my computer before, but I have always been confused about the boot entries of multiple systems, often encountering problems such as missing boot entries and duplicate boot entries. This time I plan to study the configuration of multi-system boot entries in depth, including the settings of boot loaders, EFI/Grub/rEFInd, and how to customize the theme of multi-system boot loaders.&lt;/p&gt;</description></item><item><title>Access Personal Website from Public Network——Nginx Reverse Proxy Configuration</title><link>https://blog.jinli.io/en/p/access-personal-website-from-public-networknginx-reverse-proxy-configuration/</link><pubDate>Wed, 08 May 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/access-personal-website-from-public-networknginx-reverse-proxy-configuration/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After deciding to build a personal server on my own computer, I bought a domain name and configured dynamic domain name resolution, so I could access my server through the domain name. Later, I built a lot of websites on this server and used Nginx to configure reverse proxy to access these websites from the public network. Here I record how I configured Nginx reverse proxy.&lt;/p&gt;</description></item><item><title>Self-hosted Online LaTeX Compilation and Preview Service: Overleaf Community Edition</title><link>https://blog.jinli.io/en/p/self-hosted-online-latex-compilation-and-preview-service-overleaf-community-edition/</link><pubDate>Wed, 24 Apr 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/self-hosted-online-latex-compilation-and-preview-service-overleaf-community-edition/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I have been using &lt;a href="https://www.overleaf.com/" target="_blank" rel="noreferrer"&gt;Overleaf&lt;/a&gt; to collaborate on LaTeX documents with others when working on assignments or papers. Although it is not as customizable as local editors (such as VS Code), it is still very convenient to collaborate with others. When writing my doctoral dissertation, I purchased a one-year student subscription for Git synchronization. Due to the reduced frequency of use after graduation, I did not renew it. Recently, I needed to recompile my doctoral dissertation, only to find that the compilation time for free users of Overleaf is limited. Due to the large size of the doctoral dissertation, the compilation time exceeded the limit, which prevented me from compiling successfully.&lt;/p&gt;</description></item><item><title>Project Collaboration Development Process on GitHub/GitLab</title><link>https://blog.jinli.io/en/p/project-collaboration-development-process-on-github/gitlab/</link><pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/project-collaboration-development-process-on-github/gitlab/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;If you see an interesting project on GitHub and want to participate in its development, you generally need to follow a certain process. Here&amp;rsquo;s a general project collaboration development process.&lt;/p&gt;
&lt;p&gt;Of course, this process is not only applicable to GitHub, but also to other code hosting platforms such as GitLab.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Git is installed&lt;/li&gt;
&lt;li&gt;GitHub account is registered&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Git settings
 &lt;div id="git-settings" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#git-settings" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set username and email&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (4): Sequence Prediction (I) -- Recurrent Neural Networks (RNN)</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-4-sequence-prediction-i--recurrent-neural-networks-rnn/</link><pubDate>Sat, 27 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-4-sequence-prediction-i--recurrent-neural-networks-rnn/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the fourth article in the &lt;a href="https://jinli.io/en/categories/machine-learning/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;Learn PyTorch by Examples&amp;rdquo;&lt;/a&gt; series. In the previous three articles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-1-mnist-handwritten-digit-recognition-i--pytorch-basics-and-neural-network-basics/" &gt;&amp;ldquo;Learn PyTorch by Examples (1): MNIST Handwritten Digit Recognition (I) &amp;ndash; PyTorch Basics and Neural Network Basics&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-2-mnist-handwritten-digit-recognition-ii--parameter-selection-in-neural-network/" &gt;&amp;ldquo;Learn PyTorch by Examples (2): MNIST Handwritten Digit Recognition (II) &amp;ndash; Parameter Selection in Neural Network&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-3-mnist-handwritten-digit-recognition-iii--convolutional-neural-networks/" &gt;&amp;ldquo;Learn PyTorch by Examples (3): MNIST Handwritten Digit Recognition (III) &amp;ndash; Convolutional Neural Networks&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the articles, we introduced how to solve image classification problems using PyTorch. Another important problem in machine learning is sequence prediction. Unlike image classification, sequence prediction requires considering the correlation between data. Recurrent Neural Network (RNN) is a neural network that can handle sequence data, as it saves the previous data information at each time step. In this article, we will use a simple RNN to predict the sine function.&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (3): MNIST Handwritten Digit Recognition (III) -- Convolutional Neural Networks</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-3-mnist-handwritten-digit-recognition-iii--convolutional-neural-networks/</link><pubDate>Tue, 23 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-3-mnist-handwritten-digit-recognition-iii--convolutional-neural-networks/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the third article in the &lt;a href="https://jinli.io/en/categories/machine-learning/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;Learn PyTorch by Examples&amp;rdquo;&lt;/a&gt; series. In the previous two articles &lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-1-mnist-handwritten-digit-recognition-i--pytorch-basics-and-neural-network-basics/" &gt;&amp;ldquo;Learn PyTorch by Examples (1): MNIST Handwritten Digit Recognition (I) &amp;ndash; PyTorch Basics and Neural Network Basics&amp;rdquo;&lt;/a&gt; and &lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-2-mnist-handwritten-digit-recognition-ii--parameter-selection-in-neural-network/" &gt;&amp;ldquo;Learn PyTorch by Examples (2): MNIST Handwritten Digit Recognition (II) &amp;ndash; Parameter Selection in Neural Network&amp;rdquo;&lt;/a&gt;, we introduced the basic concepts and usage of PyTorch, and implemented MNIST handwritten digit recognition using a simple three-layer fully connected neural network. In this article, we will use a convolutional neural network to implement MNIST handwritten digit recognition, which is an extension of the previous two articles.&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (2): MNIST Handwritten Digit Recognition (II) -- Parameter Selection in Neural Network</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-2-mnist-handwritten-digit-recognition-ii--parameter-selection-in-neural-network/</link><pubDate>Sat, 20 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-2-mnist-handwritten-digit-recognition-ii--parameter-selection-in-neural-network/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the second article in the &lt;a href="https://jinli.io/en/categories/machine-learning/" target="_blank" rel="noreferrer"&gt;&amp;ldquo;Learn PyTorch by Examples&amp;rdquo;&lt;/a&gt; series. In the previous article &lt;a href="https://blog.jinli.io/en/p/learn-pytorch-by-examples-1-mnist-handwritten-digit-recognition-i--pytorch-basics-and-neural-network-basics/" &gt;&amp;ldquo;Learn PyTorch by Examples (1): PyTorch Basics and MNIST Handwritten Digit Recognition (1)&amp;rdquo;&lt;/a&gt;, we introduced the basic concepts and usage of PyTorch, and implemented MNIST handwritten digit recognition using a simple three-layer fully connected neural network, which is the &amp;ldquo;Hello World&amp;rdquo; in the field of deep learning. In this article, we will discuss the selection of parameters in this simple three-layer neural network and compare the impact of different parameter choices on the model performance.&lt;/p&gt;</description></item><item><title>Container(1): About Containerization -- Containerization, Docker, Docker-Compose, Kubernetes / K8s, etc.</title><link>https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./</link><pubDate>Thu, 18 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/container1-about-containerization--containerization-docker-docker-compose-kubernetes-/-k8s-etc./</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I have almost all my websites deployed using Docker. When I talked to my friends about how I built these websites, I found that many people said they had heard of Docker or containers, but didn&amp;rsquo;t know what they were.&lt;/p&gt;
&lt;p&gt;In fact, when I first started using Docker, I came into contact with many container-related concepts, but because I had not practiced them, I was also at a loss about these concepts. Now that I have been using container technology for a long time, I want to summarize the related knowledge and hope to help others.&lt;/p&gt;</description></item><item><title>Python Web Development Learning (5): Deploying Website on AWS</title><link>https://blog.jinli.io/en/p/python-web-development-learning-5-deploying-website-on-aws/</link><pubDate>Wed, 17 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/python-web-development-learning-5-deploying-website-on-aws/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In the previous four articles of this series, we developed a simple weather forecast website using the Flask framework of Python, and deployed this website to a private server using Docker, so that our website can be accessed on the public network.&lt;/p&gt;
&lt;p&gt;However, not everyone has their own server. To make the deployment of the website easier, we can use cloud servers provided by cloud service providers such as AWS or Google Cloud to deploy our website.&lt;/p&gt;</description></item><item><title>Learn PyTorch by Examples (1): MNIST Handwritten Digit Recognition (I) -- PyTorch Basics and Neural Network Basics</title><link>https://blog.jinli.io/en/p/learn-pytorch-by-examples-1-mnist-handwritten-digit-recognition-i--pytorch-basics-and-neural-network-basics/</link><pubDate>Mon, 15 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-pytorch-by-examples-1-mnist-handwritten-digit-recognition-i--pytorch-basics-and-neural-network-basics/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I used TensorFlow when I took a machine learning course many years ago, but my understanding of deep learning was not deep enough at that time, so I only used it briefly. Later, I did not take any machine learning courses, but I still used some machine learning knowledge in my research work, so I learned some machine learning knowledge intermittently.&lt;/p&gt;</description></item><item><title>Private Virtual Network VPN (1): Setting Up a VPN with Shadowsocks on a Cloud Server</title><link>https://blog.jinli.io/en/p/private-virtual-network-vpn-1-setting-up-a-vpn-with-shadowsocks-on-a-cloud-server/</link><pubDate>Sat, 09 Dec 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/private-virtual-network-vpn-1-setting-up-a-vpn-with-shadowsocks-on-a-cloud-server/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Due to copyright issues, many video and music resources are unavailable abroad. Therefore, I wanted to set up a VPN to access these resources from abroad. I rented a server from a cloud service provider in China and set up a Shadowsocks service on it to achieve this goal. I encountered several problems during this process, and I am documenting how I solved them.&lt;/p&gt;</description></item><item><title>Build a Private Email Server with mailcow and Docker (2) - Use Email Relay and Reduce the Probability of being Blocked</title><link>https://blog.jinli.io/en/p/build-a-private-email-server-with-mailcow-and-docker-2-use-email-relay-and-reduce-the-probability-of-being-blocked/</link><pubDate>Sun, 03 Dec 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/build-a-private-email-server-with-mailcow-and-docker-2-use-email-relay-and-reduce-the-probability-of-being-blocked/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In the first article of this series &lt;a href="https://blog.jinli.io/en/p/building-a-private-mail-server-using-mailcow-and-docker/" &gt;&amp;ldquo;Building a Private Mail Server using mailcow and Docker&amp;rdquo;&lt;/a&gt;, we built a private email server with mailcow and docker on our own computer or server. Since many operators will block port 25, causing emails to not be sent from the server, we used email relay as an alternative.&lt;/p&gt;</description></item><item><title>Learn Web Development with Python (4): Deploy Website with Docker, Gunicorn and Nginx</title><link>https://blog.jinli.io/en/p/learn-web-development-with-python-4-deploy-website-with-docker-gunicorn-and-nginx/</link><pubDate>Tue, 21 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-web-development-with-python-4-deploy-website-with-docker-gunicorn-and-nginx/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In the previous three articles of this series, we used the Flask framework of Python to develop a simple weather forecast website. So far, our website is still limited to access on our own computer. In this article, we will use Docker, Gunicorn and Nginx to deploy this website, so that our website can be accessed on the public network.&lt;/p&gt;</description></item><item><title>Learn Web Development with Python (3): Use Input and API</title><link>https://blog.jinli.io/en/p/learn-web-development-with-python-3-use-input-and-api/</link><pubDate>Sun, 19 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-web-development-with-python-3-use-input-and-api/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;This is the third article in this series, which mainly introduces how to use the input box to get user input, and how to use the API to get information on the Internet.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Already know how to develop a simple web application using the Flask framework (see &lt;a href="https://blog.jinli.io/en/p/learn-web-development-with-python-1use-flask-framework/" &gt;&amp;ldquo;Learn Web Development with Python (1): Use Flask Framework&amp;rdquo;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Already installed PostgreSQL database and know how to use SQLAlchemy to operate the database (see &lt;a href="https://blog.jinli.io/en/p/learn-web-development-with-python-2-use-postgresql-and-sqlalchemy/" &gt;&amp;ldquo;Learn Web Development with Python (2): Use PostgreSQL and SQLAlchemy&amp;rdquo;&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Get User Input
 &lt;div id="get-user-input" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#get-user-input" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;Add Input Box
 &lt;div id="add-input-box" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#add-input-box" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;First, we can use the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag in the HTML page to create an input box. For example, we can add a form in &lt;code&gt;templates/index.html&lt;/code&gt; to let users enter a city:&lt;/p&gt;</description></item><item><title>Learn Web Development with Python (2): Use PostgreSQL and SQLAlchemy</title><link>https://blog.jinli.io/en/p/learn-web-development-with-python-2-use-postgresql-and-sqlalchemy/</link><pubDate>Sat, 18 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-web-development-with-python-2-use-postgresql-and-sqlalchemy/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;In the previous article &lt;a href="https://blog.jinli.io/en/p/learn-web-development-with-python-1use-flask-framework/" &gt;&amp;ldquo;Learn Web Development with Python (1): Use Flask Framework&amp;rdquo;&lt;/a&gt;, we used the Flask framework to develop a simple web application to display weather information for some cities. But these weather information are hard-coded in the code. If we have a lot of weather information, it is not convenient to hard-code them in the code. Therefore, we need a database to store these weather information, and then read these weather information from the database and display them on the web page.&lt;/p&gt;</description></item><item><title>Learn Web Development with Python (1)：Use Flask Framework</title><link>https://blog.jinli.io/en/p/learn-web-development-with-python-1use-flask-framework/</link><pubDate>Fri, 17 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/learn-web-development-with-python-1use-flask-framework/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;There are many popular web development languages, such as Java, PHP, Python, Ruby, etc. I know Python best, so I want to use Python to develop web applications. There are many web frameworks in Python, such as Django, Flask, Tornado, etc. These frameworks have their own characteristics. Among them, Flask is a lightweight web framework, so I choose to start learning web development with Flask framework.&lt;/p&gt;</description></item><item><title>Configuring SQL Development and Testing Environment (MySQL+VSCode) on Ubuntu 22</title><link>https://blog.jinli.io/en/p/configuring-sql-development-and-testing-environment-mysql-vscode-on-ubuntu-22/</link><pubDate>Thu, 12 Oct 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/configuring-sql-development-and-testing-environment-mysql-vscode-on-ubuntu-22/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background
 &lt;div id="background" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Recently, I have been learning to use SQL language, mainly to do LeetCode problems. But since I am a beginner, I am not very familiar with SQL databases, so I often need to debug the SQL statements I write, which requires a MySQL database that I can connect to. Most of the tutorials online are about installing MySQL on Windows, but my usual development environment is to connect to a remote Ubuntu server using VSCode on my MacBook, so I want to install MySQL on Ubuntu and be able to connect to it using VSCode remote.&lt;/p&gt;</description></item><item><title>Migrate the Domain Name Service Provider from Hostinger to Cloudflare</title><link>https://blog.jinli.io/en/p/migrate-the-domain-name-service-provider-from-hostinger-to-cloudflare/</link><pubDate>Sat, 16 Sep 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/migrate-the-domain-name-service-provider-from-hostinger-to-cloudflare/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Hostinger is a network custody service provider, providing services such as domain name registration, virtual hosting, VPS and other services.
Recently, a domain name was started on &lt;a href="https://www.hostinger.com/" target="_blank" rel="noreferrer"&gt;Hostinger&lt;/a&gt;, and intended to migrate the previous website to the new domain name. I have been using &lt;a href="https://github.com/acmesh-official/acme.sh" target="_blank" rel="noreferrer"&gt;acme.sh&lt;/a&gt; to generate an SSL certificate for my website. But hostinger does not provide APIs that can be retrieved by acme.sh, so it is impossible to use acme.sh to generate SSL certificates for domain names on hostinger. &lt;a href="https://cloudflare.com/" target="_blank" rel="noreferrer"&gt;Cloudflare&lt;/a&gt; is a service provider with content distribution network based on reverse agents, also provides domain name analysis services, and provides API available in acme.sh. So I want to migrate the domain name service provider from Hostinger to Cloudflare.&lt;/p&gt;</description></item><item><title>Use Gitlab and docker to Build a Personal Code Repository</title><link>https://blog.jinli.io/en/p/use-gitlab-and-docker-to-build-a-personal-code-repository/</link><pubDate>Sat, 16 Sep 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/use-gitlab-and-docker-to-build-a-personal-code-repository/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The previous code was basically placed on GitHub, but because some codes involve some scientific research projects, even if they are placed in the private repository, there may be potential security issues, so I want to build a private code repository and put them on my own computer or server.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;docker和docker compose&lt;/li&gt;
&lt;li&gt;Domain name (second-level domain name is sufficient)&lt;/li&gt;
&lt;li&gt;acme.sh (Generate SSL certificate)&lt;/li&gt;
&lt;li&gt;nginx (Reverse proxy)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;Preparation
 &lt;div id="preparation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#preparation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;Domain Name and SSL Certificate
 &lt;div id="domain-name-and-ssl-certificate" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#domain-name-and-ssl-certificate" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;For the installation and preparation of the above software and tools, please refer to &lt;a href="https://blog.jinli.io/en/p/building-a-personal-cloud-network-disk-using-nextcloud-and-docker/" &gt;&amp;ldquo;Building a Personal Cloud Network Disk using Nextcloud and Docker&amp;rdquo;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Merge Two Hugo Themes: Use the Resume Template of almeida-CV Theme in hugo-theme-Stack</title><link>https://blog.jinli.io/en/p/merge-two-hugo-themes-use-the-resume-template-of-almeida-cv-theme-in-hugo-theme-stack/</link><pubDate>Sat, 02 Sep 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/merge-two-hugo-themes-use-the-resume-template-of-almeida-cv-theme-in-hugo-theme-stack/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When setting up this website, I used the hugo theme [hugo-theme-stack] (&lt;a href="https://github.com/caijimmy/hugo-theme-stack%29" target="_blank" rel="noreferrer"&gt;https://github.com/caijimmy/hugo-theme-stack)&lt;/a&gt;, you can add personal resumes on the `page.However, the style of this page is not the style of the traditional resume, but the style of a blog post, which is not in line with my requirements.
My requirements for the resume template are:&lt;/p&gt;</description></item><item><title>Use Jellyfin and docker to Build a Personal Online Media Library</title><link>https://blog.jinli.io/en/p/use-jellyfin-and-docker-to-build-a-personal-online-media-library/</link><pubDate>Thu, 31 Aug 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/use-jellyfin-and-docker-to-build-a-personal-online-media-library/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I have downloaded a lot of film and television resources before it is placed in the hard disk of the host at home, but it is not convenient to watch it on other places or other equipment.So think of building an online film and television library, you can watch your film and television resources through the Internet anywhere.
I saw a lot of methods to build online film and television libraries on the Internet, such as using &lt;a href="https://www.plex.tv/" target="_blank" rel="noreferrer"&gt;plex&lt;/a&gt;, &lt;a href="https://emby.media/" target="_blank" rel="noreferrer"&gt;emby&lt;/a&gt;, &lt;a href="https://jellyfin.org/" target="_blank" rel="noreferrer"&gt;jellyfin&lt;/a&gt; etc. These software are open source and can be built on your own computer or server, and then watch your film and television resources through web or clients.&lt;/p&gt;</description></item><item><title>Build a Private Digital Library with calibre-web and docker</title><link>https://blog.jinli.io/en/p/build-a-private-digital-library-with-calibre-web-and-docker/</link><pubDate>Sat, 05 Aug 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/build-a-private-digital-library-with-calibre-web-and-docker/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve previously downloaded some eBooks, all of which are stored on the cloud drive. However, every time I want to read them on different devices, I need to download them first (even though they can be previewed on the cloud drive, I still find it better to download them and use a dedicated e-reader for a better experience). Moreover, with a growing number of eBooks, managing them on the cloud drive becomes quite chaotic. Recently, I came across the tool called &amp;ldquo;calibre-web,&amp;rdquo; which allows you to set up your own eBook library. I feel that the results are quite promising.&lt;/p&gt;</description></item><item><title>Building a Private Mail Server using Mailcow and Docker</title><link>https://blog.jinli.io/en/p/building-a-private-mail-server-using-mailcow-and-docker/</link><pubDate>Sat, 17 Jun 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/building-a-private-mail-server-using-mailcow-and-docker/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Now that you have a private domain name, you can make full use of it and build a private mail server, so that you can create your own mailbox, and all the information in the mail can be completely controlled by yourself, which is more secure.&lt;/p&gt;
&lt;p&gt;There are multiple deployment methods for private mail servers, because I have installed docker on the server before, and other software tools on the server also use docker for containerized deployment and operation, so the mail server here is also chosen to be more convenient for containerizationtools to deploy.&lt;/p&gt;</description></item><item><title>Slurm: How to Change Job's Priority without Admin Privilege</title><link>https://blog.jinli.io/en/p/slurm-how-to-change-jobs-priority-without-admin-privilege/</link><pubDate>Sat, 15 Apr 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/slurm-how-to-change-jobs-priority-without-admin-privilege/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Slurm is a widely used workload manager and job scheduler for Linux and Unix systems. It allows users to submit and manage jobs on a cluster environment.&lt;/p&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="low"
 alt="Slurm"
 src="https://img.jinli.io/images/2023/04/15/slurm.md.jpg"
 &gt;&lt;/figure&gt;
&lt;p&gt;One important aspect of managing jobs on a cluster is job priority control.
In this post, we will discuss how to use the &amp;ldquo;&amp;ndash;nice&amp;rdquo; option in Slurm to set the priority of a job.&lt;/p&gt;</description></item><item><title>Google Photo Alternative: Using Nextcloud to Create a Personal Cloud Photo Album That Can Be Synchronized Across Multiple Devices</title><link>https://blog.jinli.io/en/p/google-photo-alternative-using-nextcloud-to-create-a-personal-cloud-photo-album-that-can-be-synchronized-across-multiple-devices/</link><pubDate>Tue, 21 Feb 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/google-photo-alternative-using-nextcloud-to-create-a-personal-cloud-photo-album-that-can-be-synchronized-across-multiple-devices/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Background and Motivation
 &lt;div id="background-and-motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#background-and-motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Previously, I used Nextcloud to build a personal cloud drive on my own server (see &lt;a href="https://blog.jinli.io/en/p/building-a-personal-cloud-network-disk-using-nextcloud-and-docker/" &gt;&amp;ldquo;Building a Personal Cloud Drive with Nextcloud and Docker&amp;rdquo;&lt;/a&gt;) and backed up my photos from various devices to the cloud drive. Later, I found that the Nextcloud app on mobile devices has an option for automatic uploading, which gave me the idea of using it to replace Google Photos and building a personal cloud photo album.&lt;/p&gt;</description></item><item><title>Use Chevereto-free to Build a Private Image Bed</title><link>https://blog.jinli.io/en/p/use-chevereto-free-to-build-a-private-image-bed/</link><pubDate>Tue, 21 Feb 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/use-chevereto-free-to-build-a-private-image-bed/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When blogging online, it is possible that the same article needs to be uploaded to different platforms. For example, some articles will be placed on this website as well as in the README of the project’s GitHub repository.
At this time, if the pictures in the article use local pictures, you need to put a copy on different platforms, which is not easy to update and manage in a unified manner.Hence the idea of building a personal drawing bed
To unify the idea of managing these pictures.&lt;/p&gt;</description></item><item><title>Installation and Use of Free Keyboard and Mouse Sharing Software Barrier/InputLeap for All Platforms</title><link>https://blog.jinli.io/en/p/installation-and-use-of-free-keyboard-and-mouse-sharing-software-barrier/inputleap-for-all-platforms/</link><pubDate>Mon, 23 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/installation-and-use-of-free-keyboard-and-mouse-sharing-software-barrier/inputleap-for-all-platforms/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;It is often necessary to use more than one computer at work, for example, there is a desktop computer with Linux system in the office, and another laptop computer with macOS
For classes or meetings.Sometimes it is necessary to use these two computers at the same time to complete a certain task. At this time, switching back and forth with two sets of mice and keyboards will become a problem.
It is very troublesome, &lt;a href="https://github.com/debauchee/barrier" target="_blank" rel="noreferrer"&gt;&lt;em&gt;Barrier&lt;/em&gt;&lt;/a&gt; is a free software that can share mouse and keyboard across multiple computers.&lt;/p&gt;</description></item><item><title>Building a Personal Cloud Network Disk using Nextcloud and Docker</title><link>https://blog.jinli.io/en/p/building-a-personal-cloud-network-disk-using-nextcloud-and-docker/</link><pubDate>Fri, 23 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/building-a-personal-cloud-network-disk-using-nextcloud-and-docker/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Introduction
 &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Nextcloud is an open-source network disk tool that allows users to build their own cloud network disk on their private server.&lt;/p&gt;
&lt;p&gt;Nextcloud provides both server-side and client-side software. It supports desktop-level operating systems such as Windows, Linux, and macOS, as well as mobile-level operating systems such as Android and iOS. Therefore, personal users can easily use their private cloud network disk after building it.&lt;/p&gt;</description></item><item><title>Use Environment Module to Manage Software Packages and Environment Variables in Linux</title><link>https://blog.jinli.io/en/p/use-environment-module-to-manage-software-packages-and-environment-variables-in-linux/</link><pubDate>Thu, 22 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/use-environment-module-to-manage-software-packages-and-environment-variables-in-linux/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;When using the university&amp;rsquo;s computing cluster, it is very convenient to use the &lt;code&gt;module load&lt;/code&gt; command to load software packages such as the Intel compiler and Python Anaconda. These packages can also be easily discarded when they are not needed, which makes it convenient to select and enable certain environment variables, and prevent certain environment variables from contaminating the compilation environment of other software.&lt;/p&gt;</description></item><item><title>Build Dakota from Source</title><link>https://blog.jinli.io/en/p/build-dakota-from-source/</link><pubDate>Tue, 20 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/build-dakota-from-source/</guid><description>&lt;!-- more --&gt;

&lt;h1 class="relative group"&gt;Build Dakota
 &lt;div id="build-dakota" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#build-dakota" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h1&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Dakota relies on some other tools and libraries. Please refer to the &lt;a href="https://dakota.sandia.gov/content/install-required-tools-and-libraries" target="_blank" rel="noreferrer"&gt;Dakota&amp;rsquo;s official website&lt;/a&gt;. Most of the tools (such as CMake, Python) are already installed. The ones that need to take care of are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linear Algebra libraries: BLAS and LAPACK&lt;/li&gt;
&lt;li&gt;Boost&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;System information of my case:&lt;/p&gt;</description></item><item><title>Build SAM from Source</title><link>https://blog.jinli.io/en/p/build-sam-from-source/</link><pubDate>Fri, 09 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/build-sam-from-source/</guid><description>&lt;!-- more --&gt;

&lt;h1 class="relative group"&gt;Build SAM
 &lt;div id="build-sam" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#build-sam" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h1&gt;

&lt;h2 class="relative group"&gt;Prerequisites
 &lt;div id="prerequisites" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;SAM relies on the MOOSE framework. We build MOOSE by following the instructions on the &lt;a href="https://mooseframework.inl.gov/getting_started/installation/index.html" target="_blank" rel="noreferrer"&gt;MOOSE website&lt;/a&gt; first.&lt;/p&gt;

&lt;h3 class="relative group"&gt;Install Mambaforge3
 &lt;div id="install-mambaforge3" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#install-mambaforge3" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;For Linux users:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash Mambaforge-Linux-x86_64.sh -b -p ~/mambaforge3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After installing, put Mambaforge&amp;rsquo;s path to system environment &lt;code&gt;PATH&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Compile and Install zsh from Source without sudo Permission</title><link>https://blog.jinli.io/en/p/compile-and-install-zsh-from-source-without-sudo-permission/</link><pubDate>Fri, 26 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/compile-and-install-zsh-from-source-without-sudo-permission/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The default shell on the school&amp;rsquo;s computing cluster is bash, and my commonly used zsh is not available. It feels very uncomfortable without auto-completion and syntax highlighting. Moreover, ordinary accounts do not have administrative privileges and cannot use &lt;code&gt;sudo&lt;/code&gt; to install zsh directly through package management tools. Therefore, it is necessary to compile and install zsh from source.&lt;/p&gt;</description></item><item><title>Customizable MatLab Color Library jlcolor</title><link>https://blog.jinli.io/en/p/customizable-matlab-color-library-jlcolor/</link><pubDate>Tue, 02 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/customizable-matlab-color-library-jlcolor/</guid><description>&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Sometimes the default MatLab colors for plottings are not satisfactory and I would like to define and use my own color schemes. When I see a beautiful color scheme, I also would like to save it to my color scheme library. But when I want to use a certain color scheme, it might be difficult to find it in my library. So here I created this project to save, preview and use customized color schemes in MatLab.&lt;/p&gt;</description></item><item><title>oh-my-zsh Shell and Neovim Configuration for Commandline Users</title><link>https://blog.jinli.io/en/p/oh-my-zsh-shell-and-neovim-configuration-for-commandline-users/</link><pubDate>Tue, 02 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/oh-my-zsh-shell-and-neovim-configuration-for-commandline-users/</guid><description>&lt;!-- more --&gt;

&lt;h1 class="relative group"&gt;Shell Configuration
 &lt;div id="shell-configuration" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#shell-configuration" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h1&gt;
&lt;p&gt;Configurations for Linux shell and &lt;em&gt;Neovim&lt;/em&gt;&lt;/p&gt;

&lt;h2 class="relative group"&gt;Linux Shell Configuration
 &lt;div id="linux-shell-configuration" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#linux-shell-configuration" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="low"
 alt="Shell Appearence"
 src="https://img.jinli.io/images/2024/05/19/shell_appearence.md.jpg"
 &gt;&lt;/figure&gt;

&lt;h3 class="relative group"&gt;Features
 &lt;div id="features" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#features" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Shell: &lt;a href="https://ohmyz.sh/" target="_blank" rel="noreferrer"&gt;oh-my-zsh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Theme: &lt;a href="https://github.com/romkatv/powerlevel10k" target="_blank" rel="noreferrer"&gt;powerlevel10k&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Plugins: &lt;a href="https://github.com/zsh-users/zsh-autosuggestions" target="_blank" rel="noreferrer"&gt;zsh-autosuggestions&lt;/a&gt;, &lt;a href="https://github.com/zsh-users/zsh-syntax-highlighting" target="_blank" rel="noreferrer"&gt;zsh-syntax-highlighting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;Notice
 &lt;div id="notice" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notice" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;The powerlevel10k theme is no longer maintained as of May 2024, but it should still work fine. The author, romkatv, believes that powerlevel10k is mature and feature-complete. Most issues are either personalized requests or involve underlying changes that are unnecessary for 99% of users. If you are not in that 99%, you need to be able to modify the code to meet your needs. Therefore, romkatv has decided to stop maintaining the powerlevel10k theme. Here are the relevant discussions:&lt;/p&gt;</description></item><item><title>How This Website Was Built 4 -- Search Engine Optimization (SEO)</title><link>https://blog.jinli.io/en/p/how-this-website-was-built-4--search-engine-optimization-seo/</link><pubDate>Thu, 24 Feb 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/how-this-website-was-built-4--search-engine-optimization-seo/</guid><description>&lt;p&gt;This website was built with Hugo framework. The theme &amp;ldquo;stack&amp;rdquo; used by this website supports to generate labels based on the Open Graph Protocol (OG). Here is how to do the Search Engine Optimization (SEO) for a website built with Hugo framework.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Intro
 &lt;div id="intro" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#intro" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;By the &lt;a href="https://blog.jinli.io/en/p/how-this-website-was-built-3--usage-and-customization-of-hugo-theme-stack/" &gt;3rd article of this series&lt;/a&gt;, we have built a bi-lingual website that can be visited via domain name and HTTPS protocol. However, if we want to search our website on a search engine (such as Google/Bing/Baidu), we will find nothing related to our website.&lt;/p&gt;</description></item><item><title>How This Website Was Built 3 -- Usage and Customization of Hugo Theme Stack</title><link>https://blog.jinli.io/en/p/how-this-website-was-built-3--usage-and-customization-of-hugo-theme-stack/</link><pubDate>Tue, 22 Feb 2022 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/how-this-website-was-built-3--usage-and-customization-of-hugo-theme-stack/</guid><description>&lt;p&gt;This website uses Hugo theme &amp;ldquo;stack&amp;rdquo;. This post shows how to apply different Hugo themes, introduces the features of Hugo theme &amp;ldquo;stack&amp;rdquo; and some customization of &amp;ldquo;stack&amp;rdquo;.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Motivation
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;Initially when I built a personal website, I tried &lt;a href="https://hexo.io" target="_blank" rel="noreferrer"&gt;Hexo Framework&lt;/a&gt;. I used several Hexo themes, including &lt;a href="https://github.com/litten/hexo-theme-yilia" target="_blank" rel="noreferrer"&gt;hexo-theme-yilia&lt;/a&gt;, &lt;a href="https://github.com/JoeyBling/hexo-theme-yilia-plus" target="_blank" rel="noreferrer"&gt;hexo-theme-yilia-plus&lt;/a&gt; and &lt;a href="https://github.com/theme-next/hexo-theme-next" target="_blank" rel="noreferrer"&gt;hexo-theme-next&lt;/a&gt;. I also tried a theme &lt;a href="https://leirock.github.io/blog/" target="_blank" rel="noreferrer"&gt;https://leirock.github.io/blog/&lt;/a&gt;, which is a theme based on hexo-theme-next and was created by a GitHub user called &amp;ldquo;leirock&amp;rdquo;. This theme was my favorate and its GitHub repo is &lt;a href="https://github.com/leirock/blog" target="_blank" rel="noreferrer"&gt;https://github.com/leirock/blog&lt;/a&gt;. And it looks like this:&lt;/p&gt;</description></item><item><title>How This Website Was Built 2 -- Hugo Framework for Personal Blog Website</title><link>https://blog.jinli.io/en/p/how-this-website-was-built-2--hugo-framework-for-personal-blog-website/</link><pubDate>Fri, 17 Dec 2021 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/how-this-website-was-built-2--hugo-framework-for-personal-blog-website/</guid><description>&lt;p&gt;This website is running on my personal computer. Here is how this website was built.&lt;/p&gt;
&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;Motivations
 &lt;div id="motivations" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivations" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After purchasing a domain name, I was considering to build a personal website using the domain name. At first I tried using &lt;a href="https://hexo.io" target="_blank" rel="noreferrer"&gt;Hexo&lt;/a&gt; as a static website generator. I would like to build a bilingual website (Chinese and English). However, Hexo does support multi-lingual natively. I have to use some extensions such as &lt;code&gt;hexo-generator-i18n&lt;/code&gt;, etc. And I met tons of issues when building the bilingual website. Therefore I gave up and turned to &lt;a href="https://gohugo.io" target="_blank" rel="noreferrer"&gt;Hugo&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>How This Website Was Built 1 -- Purchase and Configure a Personal Domain Name</title><link>https://blog.jinli.io/en/p/how-this-website-was-built-1--purchase-and-configure-a-personal-domain-name/</link><pubDate>Sun, 15 Aug 2021 00:00:00 +0000</pubDate><guid>https://blog.jinli.io/en/p/how-this-website-was-built-1--purchase-and-configure-a-personal-domain-name/</guid><description>&lt;p&gt;This website uses my personal domain name. Here is how the domain name was purchased and the configurations of the domain name, including setting up a dynamically domain name system (DDNS).&lt;/p&gt;
&lt;!-- more --&gt;

&lt;h2 class="relative group"&gt;&lt;strong&gt;Motivation&lt;/strong&gt;
 &lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;I need to use &lt;code&gt;ssh&lt;/code&gt; to login to the computers in my home and office frequently for some working reasons. However, there&amp;rsquo;s no fixed IP addresses for those computers. After the IP addresses changed, I lost the connection to the computers and could not re-connect immediately (because I don&amp;rsquo;t know the new IP address).&lt;/p&gt;</description></item></channel></rss>