<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Meta | JiyuuLife | Automate Your Way to Freedom</title>
	<atom:link href="https://www.jiyuulife.net/category/meta/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.jiyuulife.net</link>
	<description>Tech guides, DIYs, and helpful information for expats living in Japan from just a regular guy.</description>
	<lastBuildDate>Thu, 24 Apr 2025 01:32:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>

<image>
	<url>https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/cropped-Ziyou.png?fit=32%2C32&#038;ssl=1</url>
	<title>Meta | JiyuuLife | Automate Your Way to Freedom</title>
	<link>https://www.jiyuulife.net</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">148850804</site>	<item>
		<title>Unlocking Peak Performance: Migrating from Apache2 to FrankenPHP with Docker</title>
		<link>https://www.jiyuulife.net/dockering-and-migrating-from-apache2-to-frankenphp-caddy/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 20 Apr 2025 10:21:44 +0000</pubDate>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Site]]></category>
		<category><![CDATA[caddy]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[frankenphp]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[phpmyadmin]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=704</guid>

					<description><![CDATA[<p>Foreword Up until today (April 20, 2025) I&#8217;ve hosted this WordPress site using a variety of services and software. This site originally started out on Google Cloud Platform but then slowly transitioned to self-hosting via Raspberry Pi 4. For reasons that I do not remember, when migrating over to rpi4 I set up the site ... <a title="Unlocking Peak Performance: Migrating from Apache2 to FrankenPHP with Docker" class="read-more" href="https://www.jiyuulife.net/dockering-and-migrating-from-apache2-to-frankenphp-caddy/" aria-label="Read more about Unlocking Peak Performance: Migrating from Apache2 to FrankenPHP with Docker">Read more</a></p>
The post <a href="https://www.jiyuulife.net/dockering-and-migrating-from-apache2-to-frankenphp-caddy/">Unlocking Peak Performance: Migrating from Apache2 to FrankenPHP with Docker</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Foreword</h2>



<p>Up until today (April 20, 2025) I&#8217;ve hosted this WordPress site using a variety of services and software. This site originally started out on Google Cloud Platform but then slowly transitioned to self-hosting via Raspberry Pi 4. For reasons that I do not remember, when migrating over to rpi4 I set up the site and all its components directly in the host server, without using any containerization software such as Docker. Retroactively speaking, I likely did it to brush up on my linux knowledge and make sure that I understood everything that was happening under the hood of my server and website. I&#8217;ve created and documented my journey through the various migrations in this site but finally realized recently that it is time to move on to using new tools and services. To &#8220;catch up with the times&#8221; or so people say. Now that I spent enough time building code repos from source, manually orchestrating the deployments and upgrades of WordPress and MariaDB, and manually updating PHP versions by hand, I will now leave that to the community and embrace the wonderfulness that is waiting for new software versions to arrive in docker containers 😉</p>



<h2 class="wp-block-heading">About Caddy and FrankenPHP</h2>



<p>Apache2 was (and likely still is) the go-to webserver for WordPress deployments. For WordPress users, transitioning from the traditional Apache2 setup to a more modern and efficient architecture can yield significant benefits. Caddy, with its V2 released in 2020, is a new webserver that, though young, promises high performance with an easier to use configuration. FrankenPHP is a cutting-edge PHP application server built on the Caddy web server. It consolidates the web server and PHP runtime into a single service, eliminating the need for separate PHP-FPM and Apache processes. This integration simplifies deployment and enhances performance. Notably, benchmarks have shown that FrankenPHP can process requests significantly faster than traditional setups .​</p>



<h2 class="wp-block-heading">Current System Setup</h2>



<ul class="wp-block-list">
<li>WordPress v6.7</li>



<li>Apache/2.4.62</li>



<li>FPM-PHP (PHP v8.2.28)</li>



<li>MariaDB 10.5.26</li>
</ul>



<h2 class="wp-block-heading">Prerequisites</h2>



<ul class="wp-block-list">
<li>Backup the site using your WP site migration tool of choice (I used UpdraftPlus&#8217;s Free Version)</li>



<li>Backup your MySQL/MariaDB as well &#8211; if you decide to upgrade your DB version then you may potentially come across compatibility issues, and your database tables may need to be repaired in order for it to be useable</li>



<li>Docker and Docker-Compose. Below is the version I&#8217;m using at the time of writing this post:<br><em><code>Docker version 28.0.4, build b8034c0</code><br><code>Docker Compose version v2.34.0</code></em></li>



<li>You will need to retrieve all of the username/passwords for the following
<ul class="wp-block-list">
<li>WordPress DB name</li>



<li>WordPress DB username/password</li>



<li>MariaDB root password</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">How to Migrate</h2>



<p><strong>Note: There will be site downtime while you perform this migration using this manual</strong>.</p>



<h3 class="wp-block-heading">Creating the Docker Compose Configuration File</h3>



<p>I will be using FrankenPHP&#8217;s officially (yet not official at the same time&#8230;) sponsored WordPress images created from the <a href="https://github.com/StephenMiracle/frankenwp" title="FrankenWP">FrankenWP</a> project. The list of latest images can be found <a href="https://hub.docker.com/r/wpeverywhere/frankenwp/tags" target="_blank" rel="noopener" title="">here</a>. For MySQL/MariaDB, choose the version that is closest if not equal to the version you are currently using &#8211; if you perform too big of a version jump the built-in upgrade feature may not work for your existing data. Lastly, if you use PHPMyAdmin, also grab and configure the details for that. Long story short, Caddy nor FrankenWP official pages had anything close to a work-able <code>compose.yaml</code>, and a lot of trial-and-error and extra configurations were necessary in order to at least properly serve the site in Production.</p>



<p>Below is the  <code>compose.yaml</code> file I finally ended up with that made the whole thing work, though I&#8217;m still giving most credit to FrankenWP&#8217;s creator since I took the template from the project&#8217;s <a href="https://github.com/StephenMiracle/frankenwp/blob/main/examples/basic/compose.yaml" target="_blank" rel="noopener" title="">examples</a> section. Note that the below example has sample data (denoted by <code>##</code>) which will need to be replaced with info from your current WP site and DB info:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
services:
  wordpress:
    image: wpeverywhere/frankenwp:latest-php8.3
    restart: always
    ports:
      - &quot;80:80&quot; # HTTP
      - &quot;443:443&quot; # HTTPS
    environment:
      SERVER_NAME: ${SERVER_NAME:-:80}
      WORDPRESS_DB_HOST: ${DB_HOST:-db}
      WORDPRESS_DB_USER: ${DB_USER:-wordpress}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:-##YOUR_WP_DB_PASSWORD##}
      WORDPRESS_DB_NAME: ${DB_NAME:-wordpress}
      # Currently WP_DEBUG turns on even if below is set false. To turn debug off, remove it entirely.
      # See:  https://github.com/docker-library/wordpress/issues/496
      #WORDPRESS_DEBUG: false
      WORDPRESS_TABLE_PREFIX: ${DB_TABLE_PREFIX:-wp_}
      CACHE_LOC: ${CACHE_LOC:-/var/www/html/wp-content/cache}
      TTL: ${TTL:-80000}
      PURGE_PATH: ${PURGE_PATH:-/__cache/purge}
      PURGE_KEY: ${PURGE_KEY:-}
      BYPASS_HOME: ${BYPASS_HOME:-false}
      BYPASS_PATH_PREFIXES: ${BYPASS_PATH_PREFIXES:-/wp-admin,/wp-content,/wp-includes,/wp-json,/feed}
      CACHE_RESPONSE_CODES: ${CACHE_RESPONSE_CODES:-000}
        # Enable debug to check for Caddy issues (Certificate renewal error, config error, etc)
      #CADDY_GLOBAL_OPTIONS: |
        #email ##EMAIL_ADDRESS##
        #auto_https disable_redirects
        #debug
      WORDPRESS_CONFIG_EXTRA: |
        # Add extra configs here as necessary
        define(&#039;WP_SITEURL&#039;, &#039;##SITEURL##&#039;);
        define(&#039;WP_HOME&#039;, &#039;##WP_HOME##&#039;);

    volumes:
      # Mount your WordPress content directory if needed
      - /var/www/html/wp-content:/var/www/html/wp-content
      # Load your own Caddyfile to configure site
      - ./Caddyfile:/etc/caddy/Caddyfile
      # Store SSL Certs so that it can be reused when containers are recreated
      # (and do avoid exceeding cert issue rate limits when debugging containers)
      - ./caddy_data:/data
      # Other root files, such as ads.txt
      - /var/www/html/ads.txt:/var/www/html/ads.txt

    depends_on:
      - db
    tty: true
    networks:
      wpnet:
        ipv4_address: 172.28.0.3

    # Below only if necessary
    #extra_hosts:
    #  - ##TLD##:172.28.0.3
    #  - www.##TLD##:172.28.0.3

  db:
    # Be careful of making too big of a version jump...
    # Slowly update db version to reduce chance of data corruption
    image: mariadb:11.7.2
    restart: always
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: ${DB_NAME:-wordpress}
      MYSQL_USER: ${DB_USER:-wordpress}
      MYSQL_PASSWORD: ${DB_PASSWORD:-##YOUR_WP_DB_PASSWORD##}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-##YOUR_ROOT_PASSWORD##}
    volumes:
      - /var/lib/mysql:/var/lib/mysql
      - /etc/mysql/mariadb.conf.d:/etc/mysql/mariadb.conf.d
    networks:
      wpnet:
        ipv4_address: 172.28.0.4

  phpmyadmin:
    # using arm64 version since I am on raspberry pi
    image: arm64v8/phpmyadmin:latest
    restart: always
    ports:
      - ${LOCAL_PHPMYADMIN_PORT:-8086}:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-##YOUR_ROOT_PASSWORD##}
    depends_on:
      - db
    networks:
      wpnet:
        ipv4_address: 172.28.0.5
    volumes:
      # Use existing phpmyadmin data
      - /var/www/html/phpmyadmin:/var/www/html/phpmyadmin

networks:
  wpnet:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

</pre></div>


<p>Mix and match whatever you need from the above to get your own site working. Below is a list of some configurations which can be made differently based on your unique situation:</p>



<ul class="wp-block-list">
<li>Remove PHPMyAdmin if you don&#8217;t use it.</li>



<li>Above config uses a bridge network. This allows for multiple sites to be hosted on the same host device via reverse proxy. Also, as you will see later, if your PHPMyAdmin also uses standard HTTP/S ports then it is not possible to run both your site (WordPress) and PHPMyAdmin on the same port in the <code>host</code> network configuration.</li>



<li>Static addresses can be used to grant read/write privileges for the DB which is hosted in another instance and by default only allows for <code>localhost</code> connection. Static IP addresses can be omitted if you configure your MySQL/MariaDB to allow connections from the entire IP address range in your bridge network (example further below). It can also be omitted if you decide to host your containers using the <code>host</code> network configuration.</li>



<li>Static IP address of PHPMyAdmin is also used in the below Caddyfile to set up reverse proxy. There&#8217;s probably a better way to do this without static IP addresses&#8230; will update later&#8230;</li>
</ul>



<h3 class="wp-block-heading">Creating the Caddyfile</h3>



<p>Now that our docker configurations are set up, we need to configure <code>Caddyfile</code>. This <code>Caddyfile</code> should be placed in the same folder as your <code>compose.yaml</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
{
        # Uncomment below when experiencing redirect loops from reverse proxy/cloud load balancer/etc
        #auto_https disable_redirects
        {$CADDY_GLOBAL_OPTIONS}

        frankenphp {
                #worker /path/to/your/worker.php
                {$FRANKENPHP_CONFIG}
        }

        # https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm
        order php_server before file_server
        order php before file_server
        order wp_cache before rewrite
        order request_header before wp_cache
}

{$CADDY_EXTRA_CONFIG}

##WWW_DOMAIN## {

        tls ##EMAIL_ADDRESS##

        @phpmyadmin path /phpmyadmin*
        reverse_proxy @phpmyadmin 172.28.0.5:80

        @static {
                file
                path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.txt
        }

        root * /var/www/html/
        encode br zstd gzip

        wp_cache {
                loc {$CACHE_LOC:/var/www/html/wp-content/cache}
                cache_response_codes {$CACHE_RESPONSE_CODES:2XX,404,405}
                ttl {$TTL:6000}
                purge_path {$PURGE_PATH:/__cache/purge}
                purge_key {$PURGE_KEY}
                bypass_home {$BYPASS_HOME:false}
                bypass_path_prefixes {$BYPASS_PATH_PREFIXES:/wp-admin,/wp-json}
        }

        {$CADDY_SERVER_EXTRA_DIRECTIVES}
        php_server
}

# For www redirects
###DOMAIN## {
#        redir https://www.{host}{uri} permanent
#}
</pre></div>


<p>Replace the <code>##ITEM##</code> with configurations for your own site. At the very bottom is a redirection bit in case you want <code>www</code> to be redirected to your TLD+1, or vice versa. The PHPMyAdmin reverse proxy is also configured inside this Caddyfile.</p>



<h3 class="wp-block-heading">Execute the Migration</h3>



<p>Now it&#8217;s time to make the transition. Bring your webserver and DB down from your host server and start your docker configurations. If at any point in this step something goes wrong, you can revert to your existing host server setup by reversing the commands below (and in the reverse execution order):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
# FYI if you do not stop Apache, you will get the following error:
#Error response from daemon: failed to set up container networking: driver failed programming external
#connectivity on endpoint frankenphp-wordpress-1
#(931a4e79170c448d3aca76617cc7be9847f227138f70a4ef085efea09e19eeb3): failed to bind host port for
#0.0.0.0:80:172.18.0.2:80/tcp: address already in use

# Also need to stop MariaDB, or else you may get corrupt data from multiple live services at the same time.
sudo systemctl stop apache2
sudo systemctl stop mariadb
docker compose up
</pre></div>


<p>Once the instances have started up fully, let&#8217;s go and make the change in MariaDB to allow both wordpress and phpmyadmin instance access. Below settings incorporate some wildcards in the docker network which can set both wp and phpmyadmin at the same time, but if you don&#8217;t use phpmyadmin you can just limit to the WP ip address only:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
docker exec -it ##DIR##-db-1 bash
mariadb -u root -p
# enter your root password

# replace each of the data with the items you configured in the compose.yaml
# 172.28.%.% is a wildcard match to all IP addresses in your docker bridge network.
GRANT ALL PRIVILEGES ON ##WORDPRESS_DB##.* TO &#039;##WORDPRESS_USER##&#039;@&#039;172.28.%.%&#039; IDENTIFIED BY &#039;##WORDPRESS_DB_PASSWORD##&#039;;
FLUSH PRIVILEGES;
</pre></div>


<p>Now your WordPress and PHPMyAdmin should be able to access your DB normally. However, you may need to wait a few minutes for Caddy to use LetsEncrypt to fetch a new certificate for you. You can use <code>docker logs ##DIR##-db-1 -f</code> to live tail your wordpress log to check on SSH certification creation/renewal progress. After a while you should be able to access your site from the public as normal.</p>



<h2 class="wp-block-heading">Other Notes</h2>



<p>Under the above setup, if you use <code>Site Kit by Google</code>, it will need to be reconfigured every time you create a new docker container for wp. This means there&#8217;s data used by Site Kit which resides outside of the <code>wp-content</code> directory which we bind to. Will update this guide once I figure out what else is necessary to bind to the docker containers.</p>



<h2 class="wp-block-heading">Additional Troubleshooting</h2>



<h3 class="wp-block-heading">PHPMyAdmin &#8211; mysqli_real_connect(): (HY000/2002): No such file or directory</h3>



<p>Change <code>$cfg['Servers'][$i]['host']</code> value to <code>127.0.0.1</code></p>



<h3 class="wp-block-heading">Unable to Access MySQL or MariaDB</h3>



<p>In <code>/etc/mysql/mariadb.conf.d/50-server.cnf</code>, change <code>bind-address</code> to <code>0.0.0.0</code></p>



<p></p>The post <a href="https://www.jiyuulife.net/dockering-and-migrating-from-apache2-to-frankenphp-caddy/">Unlocking Peak Performance: Migrating from Apache2 to FrankenPHP with Docker</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">704</post-id>	</item>
		<item>
		<title>Google Cloud CDN for GCP WordPress</title>
		<link>https://www.jiyuulife.net/google-cloud-cdn-for-gcp-wordpress/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 18 Oct 2020 06:44:41 +0000</pubDate>
				<category><![CDATA[Site]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Google Cloud CDN]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[Load Balancer]]></category>
		<category><![CDATA[VM Instance]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=508</guid>

					<description><![CDATA[<p>The more (concurrent) traffic a website receives, the more important it is for its contents to be hosted on a content delivery network (CDN). By having your site resources spread out across many servers across many regions around the world, it will take much less time (in terms of &#8220;hops&#8221;, or jumps from server to ... <a title="Google Cloud CDN for GCP WordPress" class="read-more" href="https://www.jiyuulife.net/google-cloud-cdn-for-gcp-wordpress/" aria-label="Read more about Google Cloud CDN for GCP WordPress">Read more</a></p>
The post <a href="https://www.jiyuulife.net/google-cloud-cdn-for-gcp-wordpress/">Google Cloud CDN for GCP WordPress</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<p>The more (concurrent) traffic a website receives, the more important it is for its contents to be hosted on a content delivery network (CDN). By having your site resources spread out across many servers across many regions around the world, it will take much less time (in terms of &#8220;hops&#8221;, or jumps from server to server a request needs to make) to fetch the site&#8217;s contents. </p>



<p>One of Google Cloud&#8217;s less-known features is its <a href="https://cloud.google.com/cdn" target="_blank" rel="noreferrer noopener">Cloud CDN</a> which leverages Google&#8217;s global network of data centers, servers, and ISP integration to deliver content to the end user in a quick manner. Its efficiency is further increased when coupled or used with other services in Google and Google Cloud, such as Google Domains, Google DNS, and Google Compute Instances. Since 2018, this site is hosted using Google&#8217;s Click-to-Deploy WordPress deployment (<a href="https://www.jiyuulife.net/click-to-deploy-wordpress-google-cloud/" target="_blank" rel="noreferrer noopener" title="How To Deploy WordPress Using Google Cloud Click-to-Deploy">tutorial</a>) using Google Domains (<a href="https://www.jiyuulife.net/registering-google-domains-to-google-cloud-wordpress/" target="_blank" rel="noreferrer noopener" title="Registering Google Domains to Google Cloud WordPress">tutorial</a>) with SSL encryption (<a href="https://www.jiyuulife.net/secure-wordpress-https/" target="_blank" rel="noreferrer noopener" title="Secure Your WordPress Using HTTPS">tutorial</a>) and maintenance via SSH to instance VMs (such as <a href="https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/" target="_blank" rel="noreferrer noopener" title="Update PHP Version For WordPress On Debian 9">updating PHP version</a> in Google Cloud VM Instance). Thus it is natural to leverage Google Cloud CDN, with the added benefit that it won&#8217;t break with updates to WordPress since the CDN configuration happens server-side and not WordPress-side.</p>



<p>Follow along with me as we explore how to activate Google CDN for your Google Cloud-hosted service.</p>



<span id="more-508"></span>



<h2 class="wp-block-heading">Assumptions</h2>



<p>This guide assumes the following:</p>



<ul class="wp-block-list">
<li>Your website uses Google Cloud VM instance(s) in an unmanaged <a href="https://cloud.google.com/compute/docs/instance-groups" target="_blank" rel="noreferrer noopener">instance group</a>.</li>



<li>You have access to Google Cloud Console and SSH privileges into your VM instance(s).</li>



<li>Your website is HTTPS with a valid SSL Certificate.</li>



<li>Access to DNS settings (whether Google Cloud DNS or otherwise).</li>
</ul>



<h2 class="wp-block-heading">Before We Begin</h2>



<p>Your site should experience almost no downtime (with the exception of resolving DNS to the new load balancer global IP) if everything is configured and works correctly. This guide piggybacks off of Google Cloud&#8217;s official documentation on <a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig" target="_blank" rel="noreferrer noopener">Setting up Cloud CDN with a managed instance group</a>, but there are quite a few changes we need to make to align with the assumptions above, namely:</p>



<ul class="wp-block-list">
<li>In addition to HTTP/80, configuration for HTTPS/443 is also required.</li>



<li>We are applying CDN to an UNmanaged instance group.</li>



<li>Slightly different Health Check procedure.</li>
</ul>



<p>Don&#8217;t worry, there will be reminders throughout this guide if we deviate from the official tutorial from Google Cloud.</p>



<h2 class="wp-block-heading">Setup</h2>



<h3 class="wp-block-heading">Add Health Check Tag to Instance VM</h3>



<p>The health check and firewall rules need to know which instances to apply the health check to, which can be accomplished easily by applying tags to the instance VM. Add <strong>allow-health-check</strong> as a tag to all instance VMs for your service:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" fetchpriority="high" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_vm_tag.png?resize=432%2C428&#038;ssl=1" alt="" class="wp-image-515" width="432" height="428" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_vm_tag.png?w=942&amp;ssl=1 942w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_vm_tag.png?resize=300%2C297&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_vm_tag.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_vm_tag.png?resize=768%2C761&amp;ssl=1 768w" sizes="(max-width: 432px) 100vw, 432px" /><figcaption class="wp-element-caption">Figure 1-1: Add <strong>allow-health-check</strong> tag to instance VM. This does not require you to restart the VM.</figcaption></figure></div>


<h3 class="wp-block-heading">Instance Group Settings</h3>



<figure class="wp-block-image size-large is-resized"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_summary.png?resize=619%2C176&#038;ssl=1" alt="" class="wp-image-513" width="619" height="176" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_summary.png?resize=1024%2C292&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_summary.png?resize=300%2C86&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_summary.png?resize=768%2C219&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_summary.png?resize=1536%2C439&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_summary.png?w=1632&amp;ssl=1 1632w" sizes="(max-width: 619px) 100vw, 619px" /><figcaption class="wp-element-caption">Figure 1-2: Unmanaged instance group summary page.</figcaption></figure>



<p>If not done so already, you will need to add your VM instances into an instance group. This tutorial assumes you already have a VM instance NOT created via an instance template and therefore can only be added into an UNmanaged instance group. </p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_setting.png?resize=606%2C487&#038;ssl=1" alt="" class="wp-image-512" width="606" height="487" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_setting.png?resize=1024%2C823&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_setting.png?resize=300%2C241&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_setting.png?resize=768%2C617&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_setting.png?resize=1536%2C1235&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_setting.png?w=1786&amp;ssl=1 1786w" sizes="(max-width: 606px) 100vw, 606px" /><figcaption class="wp-element-caption">Figure 1-3: Sample setting for adding existing VM Instance to unmanaged instance group. Note region and zone needs to be the same with all the VM instances to be added to the group.</figcaption></figure></div>


<p>One extra setting you will need to do is to add named ports for HTTP/80 and HTTPS/443 to the instance group. Follow the section <a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig#named-port" target="_blank" rel="noreferrer noopener">here</a>, but don&#8217;t forget to also add HTTPS/443 as well.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_named_port.png?resize=382%2C405&#038;ssl=1" alt="" class="wp-image-514" width="382" height="405" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_named_port.png?resize=965%2C1024&amp;ssl=1 965w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_named_port.png?resize=283%2C300&amp;ssl=1 283w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_named_port.png?resize=768%2C815&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_instance_group_named_port.png?w=976&amp;ssl=1 976w" sizes="auto, (max-width: 382px) 100vw, 382px" /><figcaption class="wp-element-caption">Figure 1-4: Sample settings for specifying named ports in an instance group.</figcaption></figure></div>


<h3 class="wp-block-heading">Set Up Firewall</h3>



<p>Follow the official guide section <a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig#firewall" target="_blank" rel="noreferrer noopener">here</a> to configure firewall rules for your health check. Note that our health check will use only HTTP/80 and so it is <strong>NOT</strong> necessary to add HTTPS/443. You are free to modify the name of the firewall rule but keep all other values (IP ranges and tag name) the same.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_firewall_setting.png?resize=426%2C519&#038;ssl=1" alt="" class="wp-image-516" width="426" height="519" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_firewall_setting.png?resize=840%2C1024&amp;ssl=1 840w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_firewall_setting.png?resize=246%2C300&amp;ssl=1 246w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_firewall_setting.png?resize=768%2C937&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_firewall_setting.png?w=1202&amp;ssl=1 1202w" sizes="auto, (max-width: 426px) 100vw, 426px" /><figcaption class="wp-element-caption">Figure 1-5: Firewall rule setting. Only HTTP/80 is configured,</figcaption></figure></div>


<h3 class="wp-block-heading">Set Up Load Balancer</h3>



<p>Google Cloud CDN operates alongside a <strong>load balancer</strong> with <strong>forwarding rule</strong> applied to a <strong>global IP address</strong>. All three settings are initialized and configured at the same time. This is the hardest part of the tutorial, but don&#8217;t fret! I will walk you through the steps as detailed as I can.</p>



<h4 class="wp-block-heading"><strong>Create a Health Check Page</strong></h4>



<p>The default settings for a health check as indicated in the official guide has a Request path of &#8220;/&#8221; which generally points to the main page of your website. The main page contains many content and is overkill to be used for a simple ping, so it is highly advised to create a separate page with a few words of text to minimize the overhead. We can actually use the sample code in Step 11 <a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig#mig" target="_blank" rel="noreferrer noopener">here</a> to create a simple page. SSH into your instance VM and execute the following code:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
vm_hostname=&quot;$(curl -H &quot;Metadata-Flavor:Google&quot; \
http://169.254.169.254/computeMetadata/v1/instance/name)&quot;
echo &quot;Page served from: $vm_hostname&quot; | \
sudo tee /var/www/html/healthcheck.html
</pre></div>


<p>This will create a page called &#8220;<strong>healthcheck.html</strong>&#8221; on your root site directory containing the name of the VM instance. Note this page name as you will use it when configuring health check in just a moment.</p>



<h4 class="wp-block-heading"><strong>Retrieve SSL Certificate Public and Private Keys</strong></h4>



<p>Because we are allowing HTTPS connection through the load balancer, at some point in the below guide you will be asked to provide the SSL certificate for your website. If you have configured your SSL certificate via Certbot (the same way I have as outlined in my other <a href="https://www.jiyuulife.net/secure-wordpress-https/" title="Secure Your WordPress Using HTTPS">post</a>), then SSH into your VM instance (using a separate browser tab) and execute the following commands to retrieve your public and private SSL certificate keys:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
sudo certbot certificates
</pre></div>


<p>The output should give you something similar to the following, in which you can just view its contents to find all the certificate keys you need:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
# Replace ##DOMAIN## with whatever is output in the above command
sudo cat /etc/letsencrypt/live/##DOMAIN##/fullchain.pem
sudo cat /etc/letsencrypt/live/##DOMAIN##/privkey.pem
</pre></div>

<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_SSL_Cert.png?resize=587%2C179&#038;ssl=1" alt="" class="wp-image-517" width="587" height="179" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_SSL_Cert.png?resize=1024%2C313&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_SSL_Cert.png?resize=300%2C92&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_SSL_Cert.png?resize=768%2C235&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_SSL_Cert.png?w=1480&amp;ssl=1 1480w" sizes="auto, (max-width: 587px) 100vw, 587px" /><figcaption class="wp-element-caption">Figure 2-1: Sample certbot output. &#8220;fullchain.pem&#8221; gives the public keys (include certificate chains). &#8220;privkey.pem&#8221; yields the private key. Ignore the &#8220;^C&#8221; at the end of the sudo cat commands.</figcaption></figure></div>


<p>Hold onto these outputs as you will need to copy-paste them later.</p>



<h4 class="wp-block-heading"><strong>Configure the Backend Service</strong></h4>



<p>Follow the &#8220;<a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig#load-balancer" target="_blank" rel="noreferrer noopener">Setting up the load balancer</a>&#8221; section up until you finish Step 6 in its entirety. However, note that step 6c should be changed to <strong>HTTPS</strong>, 6d to &#8220;<strong>https</strong>&#8220;, and 6f to &#8220;<strong>443</strong>&#8220;. Refer to below figure for an example.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_1.png?resize=408%2C687&#038;ssl=1" alt="" class="wp-image-518" width="408" height="687" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_1.png?resize=608%2C1024&amp;ssl=1 608w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_1.png?resize=178%2C300&amp;ssl=1 178w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_1.png?resize=768%2C1293&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_1.png?resize=912%2C1536&amp;ssl=1 912w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_1.png?w=962&amp;ssl=1 962w" sizes="auto, (max-width: 408px) 100vw, 408px" /><figcaption class="wp-element-caption">Figure 2-2: Sample configuration for HTTPS backend service (first half)</figcaption></figure></div>


<p>Check &#8220;Enable Cloud CDN&#8221; so that the system will automatically configure the Cloud CDN for you. For Health Check, since we haven&#8217;t created one yet, go ahead and follow the prompt to create new. Change the protocol to HTTP and use port 80 (remember our health check uses HTTP/80 and not HTTPS). Most importantly, the &#8220;Request path&#8221; should be configured to the health check page you created above (/healthcheck.html), relative to the root of the site directory.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_backend_health_check_setting.png?resize=479%2C566&#038;ssl=1" alt="" class="wp-image-523" width="479" height="566" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_backend_health_check_setting.png?resize=867%2C1024&amp;ssl=1 867w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_backend_health_check_setting.png?resize=254%2C300&amp;ssl=1 254w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_backend_health_check_setting.png?resize=768%2C907&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_backend_health_check_setting.png?w=962&amp;ssl=1 962w" sizes="auto, (max-width: 479px) 100vw, 479px" /><figcaption class="wp-element-caption">Figure 2-3: Sample health check setting. Note the &#8220;Request path&#8221; should be configured to a page on your site. This page can be manually created via SSH into your server.</figcaption></figure></div>


<p>Return to the backend settings and finish the rest of the configuration.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_2.png?resize=454%2C332&#038;ssl=1" alt="" class="wp-image-519" width="454" height="332" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_2.png?w=974&amp;ssl=1 974w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_2.png?resize=300%2C219&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_backend_2.png?resize=768%2C561&amp;ssl=1 768w" sizes="auto, (max-width: 454px) 100vw, 454px" /><figcaption class="wp-element-caption">Figure 2-4: Sample configuration for HTTPS backend service (second half)</figcaption></figure></div>


<h4 class="wp-block-heading"><strong>Configure the Frontend Service</strong></h4>



<p>Step 8 of the official <a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig#load-balancer" target="_blank" rel="noreferrer noopener">guide</a> assumes we already have an external IP address reserved, but I left it out until now because we can configure it here. You will need to configure TWO protocols &#8211; one for HTTP and HTTPS. When needing to specify the IP address, select &#8220;Create IP address&#8221; to create one on-the-spot.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_http.png?resize=493%2C481&#038;ssl=1" alt="" class="wp-image-520" width="493" height="481" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_http.png?w=948&amp;ssl=1 948w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_http.png?resize=300%2C292&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_http.png?resize=768%2C749&amp;ssl=1 768w" sizes="auto, (max-width: 493px) 100vw, 493px" /><figcaption class="wp-element-caption">Figure 2-5: HTTP port forwarding configuration</figcaption></figure></div>


<p>For configuring the forwarding rule for HTTPS, a few additional steps are required, namely providing the SSL certificate keys. For certificate section, click on &#8220;Create a new certificate&#8221; to reach the UI below.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_cert_setting.png?resize=408%2C527&#038;ssl=1" alt="" class="wp-image-521" width="408" height="527" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_cert_setting.png?resize=794%2C1024&amp;ssl=1 794w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_cert_setting.png?resize=233%2C300&amp;ssl=1 233w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_cert_setting.png?resize=768%2C990&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_cert_setting.png?w=940&amp;ssl=1 940w" sizes="auto, (max-width: 408px) 100vw, 408px" /><figcaption class="wp-element-caption">Figure 2-6: Port Forwarding HTTPS cert configuration.</figcaption></figure></div>


<p>Here is where you take the outputs from &#8220;Retrieve SSL Certificate Public and Private Keys&#8221; section above and paste them here. Note that your &#8220;fullchain.pem&#8221; should actually contain TWO certificate sections, the first one should be copy pasted into the &#8220;Public key certificate&#8221; field and the second one into the &#8220;Certificate chain&#8221; field. &#8220;privkey.pem&#8221; only has one key which you can just copy the entire file contents and paste into &#8220;Private key&#8221;.</p>



<p>Below is a sample frontend configuration for HTTPS.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_https.png?resize=363%2C536&#038;ssl=1" alt="" class="wp-image-522" width="363" height="536" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_https.png?resize=693%2C1024&amp;ssl=1 693w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_https.png?resize=203%2C300&amp;ssl=1 203w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_https.png?resize=768%2C1135&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_frontend_https.png?w=966&amp;ssl=1 966w" sizes="auto, (max-width: 363px) 100vw, 363px" /><figcaption class="wp-element-caption">Figure 2-7: HTTPS port forwarding configuration.</figcaption></figure></div>


<p>Follow the rest of the official guide until you finish setting up the load balancer.</p>



<h3 class="wp-block-heading">Testing Load Balancer Configurations</h3>



<p>Take several moments break for the load balancer to finish initialization. It should look like the below figure once finished. Note that the green check mark indicates the backend is configured correctly and that the health check is working as intended. If it is NOT green then revisit the above steps (and also using the <a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig" target="_blank" rel="noreferrer noopener">official guide</a> as reference) to diagnose the issue. For more concrete evidence, following &#8220;<a href="https://cloud.google.com/cdn/docs/setting-up-cdn-with-mig#send-traffic" target="_blank" rel="noreferrer noopener">Testing traffic sent to your instance</a>&#8221; section should direct you to the homepage of your website (<em>ignore</em> what step 5 says).</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_summary.png?resize=558%2C228&#038;ssl=1" alt="" class="wp-image-524" width="558" height="228" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_summary.png?resize=1024%2C420&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_summary.png?resize=300%2C123&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_summary.png?resize=768%2C315&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_lb_summary.png?w=1478&amp;ssl=1 1478w" sizes="auto, (max-width: 558px) 100vw, 558px" /><figcaption class="wp-element-caption">Figure 3-1: A normal, working load balancer setting</figcaption></figure></div>


<h3 class="wp-block-heading">Modify DNS Settings</h3>



<p>If the above load balancer test is successful, it is time to change the DNS settings &#8220;A&#8221; record from your previous single VM instance IP address to the load balancer global IP address. The global IP address can be found by clicking on the name of your load balancer in the load balancer settings page (Refer to Figure 3-1). </p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_DNS_setting.png?resize=589%2C322&#038;ssl=1" alt="" class="wp-image-525" width="589" height="322" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_DNS_setting.png?resize=1024%2C561&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_DNS_setting.png?resize=300%2C164&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_DNS_setting.png?resize=768%2C421&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_DNS_setting.png?resize=1536%2C841&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/10/CDN_DNS_setting.png?resize=2048%2C1121&amp;ssl=1 2048w" sizes="auto, (max-width: 589px) 100vw, 589px" /><figcaption class="wp-element-caption">Figure 3-2: (Google Cloud DNS) Change &#8220;A&#8221; record to load balancer global IP.</figcaption></figure></div>


<p>Enter your hostname into <a href="https://dnschecker.org/" target="_blank" rel="noreferrer noopener">DNS Checker</a> and verify that the global DNS servers return your load balancer&#8217;s IP address as the result. It may take a few moments for propagation. Once propagated, do a final check by accessing your site using your hostname (recommended to use incognito or private browser to test).</p>



<p>Congratulations! Your site is now configured for Google Cloud DNS! However, there are a few additional checks to make sure Google Cloud DNS is actually cacheing your website resources&#8230;</p>



<h3 class="wp-block-heading">Test Caching Settings</h3>



<p>Google Cloud DNS actually has a few rules on what resources can be cached, which can be found in detail <a href="https://cloud.google.com/cdn/docs/caching#cacheability" target="_blank" rel="noreferrer noopener">here</a>. After understanding the rules, use a caching checker such as <a href="https://www.giftofspeed.com/cache-checker/" target="_blank" rel="noreferrer noopener">this</a> one, fill in your site, and look at the results. Your cached resources are listed in the &#8220;Cached Files&#8221; section, but there is a catch. Google Cloud DNS does NOT cache resources when cached via ETAG. Alternatively speaking, if you see a &#8220;<strong>Type: Cache-Control&#8221;</strong> tag with another tag specifying the expiry duration for a resources hosted on your domain, then that means your resource is properly cached using a CDN.</p>



<p>If you find your domain resources are not being cached, then check your <a href="https://wordpress.org/support/article/optimization-caching/" target="_blank" rel="noreferrer noopener">WordPress Cache Settings</a> and verify that caching settings are turned on. If the problem is still not resolved then follow the server-side guide <a href="https://www.giftofspeed.com/leverage-browser-caching/" target="_blank" rel="noreferrer noopener">here</a> as well. For this site the WordPress cache settings were fine and my VM instance just did not have the <em>mod_expires</em> module enabled.</p>The post <a href="https://www.jiyuulife.net/google-cloud-cdn-for-gcp-wordpress/">Google Cloud CDN for GCP WordPress</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">508</post-id>	</item>
		<item>
		<title>Tips For Building A Python Web Scraper</title>
		<link>https://www.jiyuulife.net/building-a-python-web-scraper/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sat, 23 May 2020 10:22:22 +0000</pubDate>
				<category><![CDATA[Site]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[requests]]></category>
		<category><![CDATA[scraper]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[sikuli]]></category>
		<category><![CDATA[web crawler]]></category>
		<category><![CDATA[webdriver]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=369</guid>

					<description><![CDATA[<p>Automation is my hobby. Admittedly I never thought that I would be interested in it when I studied computer science and engineering back in my university days (my father said my personality befits a software engineer, and I blindly followed his advice). However, during my journey to become a competent software developer I invested much ... <a title="Tips For Building A Python Web Scraper" class="read-more" href="https://www.jiyuulife.net/building-a-python-web-scraper/" aria-label="Read more about Tips For Building A Python Web Scraper">Read more</a></p>
The post <a href="https://www.jiyuulife.net/building-a-python-web-scraper/">Tips For Building A Python Web Scraper</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/imgs.xkcd.com/comics/is_it_worth_the_time.png?w=1050&#038;ssl=1" alt=""/></figure></div>


<p>Automation is my hobby. Admittedly I never thought that I would be interested in it when I studied computer science and engineering back in my university days (my father said my personality befits a software engineer, and I blindly followed his advice). However, during my journey to become a competent software developer I invested much time in simple scripts to do repetitive work for me. While most of the above examples involve automating games (via something like <a href="http://sikulix.com/" class="aioseop-link">Sikuli</a> which can control your screen), lately I have been turning my attention to scraping websites and integrating APIs for data aggregation. This post contains some of the tips and tricks I have used in order to make your web crawler quicker and more robust.<br><br></p>



<span id="more-369"></span>



<hr class="wp-block-separator has-css-opacity"/>



<h2 class="wp-block-heading">Before We Start &#8211; Requests vs Webdrivers</h2>



<p>Many who write programs to crawl webpages often use Webdrivers such as <a href="https://www.selenium.dev/" class="aioseop-link">Selenium</a> to retrieve HTML contents. However, it can be a bit of an overkill if the pages you want to crawl are more static. For webpages with little to no dynamic content, using simple CURL libraries (such as <a href="https://requests.readthedocs.io/en/master/" class="aioseop-link">Requests</a> for python) for GET/POSTS will be sufficient for your needs. </p>



<p>Webdrivers are recommended for times when it is infeasible to purely use CURL for driving dynamic sites and content. This is especially true for users who aren&#8217;t scraping for information but merely wish to automate a series of actions on a website. </p>



<p>The remaining sections below contain advice for both CURL-based and Webdriver-based solutions. Parts that can be better explained with examples will contain sample code for reference &#8211; though <em>a word of caution</em>: Browsers and Webdriver API specs change frequently so they are not guaranteed to work in the future.</p>



<h2 class="wp-block-heading">Tips and Advices</h2>



<h3 class="wp-block-heading">Python Libraries for Parsing HTML Documents</h3>



<p>My goto libraries for processing HTML documents are a combination of <a href="https://pypi.org/project/html5lib/" class="aioseop-link">html5lib</a>, <a href="https://lxml.de/" class="aioseop-link">lxml</a>, and <a href="https://docs.python.org/3/library/xml.etree.elementtree.html" class="aioseop-link">xml.etree.ElementTree</a>.</p>



<p>The following code&#8217;s &#8220;buildHtmlTree()&#8221; retrieves the HTML document from a URL and converts it into a tree ready for element traversal:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
import xml.etree.ElementTree
from lxml import etree
from lxml import html
import html5lib
import requests

class RequestTooManyTimesException(Exception):
    pass

class Html5Scraper(object):
    def __init__(self):
        self.current_url = &quot;&quot;
        self.session = requests.Session()

    def buildHtmlTree(self, url, encoding=&#039;UTF-8&#039;):
        self.current_url = url
        html_elements = self.parseHtmlContent(self.getResponseText(url, encoding))
        html_tree = etree.ElementTree(html_elements)
        return html_elements

    def parseHtmlContent(self, content_string):
        # html5lib supports tags that are not closed, so parse twice to
        # convert from html5lib&#039;s xml.etree.ElementTree to lxml&#039;s
        # lxml.html.HtmlElement.
        html5_etree = html5lib.parse(content_string)
        html5_string = xml.etree.ElementTree.tostring(html5_etree, encoding=&#039;UTF-8&#039;)
        return html.fromstring(html5_string, parser=html.HTMLParser(encoding=&#039;UTF-8&#039;))

    def getResponseText(self, url, encoding=&#039;UTF-8&#039;):
        response = None
        retries = 0
        while not response:
            try:
                response = self.session.get(url)
            except requests.exceptions.SSLError:
                retries += 1
                if retries &gt; 10:
                    raise RequestTooManyTimesException(&quot;Max connection exceeded when accessing: %s&quot; % url)
                time.sleep(60)
        response.encoding = encoding
        return response.text

</pre></div>


<p>Once you have the HTML document parsed into a tree, finding elements on the page becomes simple as follows, using xpath:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
scraper = Html5Scraper()
tree = scraper.buildHtmlTree(&#039;https://www.google.com&#039;)
element = tree.xpath(&quot;//div&#x5B;@id=&#039;mngb&#039;]&quot;)
</pre></div>


<h3 class="wp-block-heading">[WebDrivers] Run in Headless or Disable Images</h3>



<p><a href="https://www.selenium.dev/selenium/docs/api/dotnet/html/T_OpenQA_Selenium_PhantomJS_PhantomJSDriver.htm" class="aioseop-link">PhantomJSDriver</a> is a selenium module which will emulate a headless (ie no Window) browser. It is particular useful in cases where only a terminal can be used (and no screen emulator software is installed). Because it is headless there is no overhead with regards to graphics and loading images, so unless you are doing UI testing and need to take screenshots of what webpages look like, it is not likely that you absolutely need to have a visual browser.</p>



<p>However, that said, PhantomJSDriver is not without its faults. This particular webdriver is not of the IE/FireFox/Chrome type, and therefore there may be compatibility issues when visiting some sites. When PhantomJSDriver couldn&#8217;t parse a website correctly or otherwise just doesn&#8217;t do the trick, more common browsers such as Chrome (via <a href="https://chromedriver.chromium.org/" class="aioseop-link">ChromeDriver</a>) may handle that site well. Chrome is non-headless, but you may still turn a few things off &#8211; image loading included &#8211; to increase its performance. Below is a sample Python code of how to set up Chromedriver without image loading, plus a few other settings turned off:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
preferences = {&quot;profile.managed_default_content_settings.images&quot;: 2}
chrome_options.add_experimental_option(&quot;prefs&quot;, preferences)
chrome_options.add_argument(&quot;--ignore-certificate-errors&quot;);
chrome_options.add_argument(&quot;--disable-logging&quot;);
chrome_options.add_argument(&quot;--no-proxy-server&quot;);
chrome_options.add_argument(&quot;--disable-client-side-phishing-detection&quot;);
chrome_options.add_argument(&quot;--disable-sync&quot;);
chrome_options.add_argument(&quot;--disable-component-update&quot;);
chrome_options.add_argument(&quot;--disable-default-apps&quot;);
chrome_options.add_argument(&quot;--disable-infobars&quot;);
chrome_options.add_argument(&quot;--disable-web-security&quot;);
chrome_options.add_argument(&quot;--safebrowsing-disable-auto-update&quot;);
driver = webdriver.Chrome(chrome_options=chrome_options)
</pre></div>


<p>Refer to this <a href="https://peter.sh/experiments/chromium-command-line-switches/" class="aioseop-link">page</a> for information about each of the above arguments.</p>



<h3 class="wp-block-heading">Search For Elements in ID -&gt; Name -&gt; Class -&gt; CSS/XPath Order</h3>



<p>A well-structured website should have most of its important elements tagged with a unique ID &#8211; thus it is most optimal to scan an element using its ID, followed by its name, followed by class, and lastly its other attributes. The further away from ID you search for an element the more brittle your program gets, and can lead to much time debugging whether the element you picked is what you are actually looking for. In addition, even a small change in the website UI can cause your program to fail to find the correct element.</p>



<p>Assuming &#8220;driver&#8221; is the object holding your webdriver, elements may be searched using the following sample methods:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
driver.find_element_by_id(&quot;id&quot;)
driver.find_element_by_name(&quot;user&quot;)
driver.find_element_by_class_name(&quot;class&quot;)
driver.find_element_by_css_selector(&quot;#root &gt; div &gt; div.css&quot;)
driver.find_element_by_xpath(&quot;//div&#x5B;@style=&#039;color: red&#039;]&quot;)
</pre></div>


<p>Refer to this <a href="https://selenium-python.readthedocs.io/locating-elements.html" class="aioseop-link">page</a> for information about locating elements. There are other methods to search for elements and I encourage you to learn and figure out which method is best for you. Also, there are separate methods for selecting multiple elements fitting a certain criteria &#8211; this is useful for parsing information from tabular structures such as tables and lists.</p>



<h3 class="wp-block-heading">Don&#8217;t Click if You can &#8220;GET&#8221;</h3>



<p>Webdriver users may get into the habit of clicking a link to move between pages. The advantage of clicking is that one does not have to worry about how to build the GET or POST request, which can save a lot of time when wanting to create a quick-and-easy solution. However, clicking an element increases risk and overhead because changes to the element may cause the program to fail to find it, and there may be unnecessary Javascript or other tasks the browser may run upon clicking a link.</p>



<p>If it is the simple matter of moving to another page and not having to worry about anything else, then GET-ing the URL is quicker and less prone to error. For POST, an inspection of the network when submitting the form can give you an idea of what to include in the form parameters, as illustrated in the below figure:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="930" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/05/Screen-Shot-2020-05-23-at-6.12.28-PM-1.png?resize=1024%2C930&#038;ssl=1" alt="" class="wp-image-392" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/05/Screen-Shot-2020-05-23-at-6.12.28-PM-1.png?resize=1024%2C930&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/05/Screen-Shot-2020-05-23-at-6.12.28-PM-1.png?resize=300%2C272&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/05/Screen-Shot-2020-05-23-at-6.12.28-PM-1.png?resize=768%2C698&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/05/Screen-Shot-2020-05-23-at-6.12.28-PM-1.png?resize=1536%2C1395&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/05/Screen-Shot-2020-05-23-at-6.12.28-PM-1.png?w=2048&amp;ssl=1 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Figure 1-1 : Form data &#8220;View Source&#8221; can give you a Query Parameter representation, useful for crafting your own POST request without having to click the form submit. </figcaption></figure></div>


<h3 class="wp-block-heading">requests.session() to Store Cookies</h3>



<p>Python&#8217;s requests API, in its simplest use case, can be thought of as a wrapper for CURL. Each call of requests.get() simply retrieves the source of the HTML document but ignores any session variables and cookies in the response. Fortunately requests also allows for sessions which can be used for exactly this purpose! The following is a simpler code of what was provided in the &#8220;Python Libraries for Parsing HTML Documents&#8221; to illustrate the simplicity of how sessions work &#8211; this is especially useful when parsing sites which require users to login:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
import requests

session = requests.Session()
r = session.get(&#039;https://www.google.com&#039;)
</pre></div>The post <a href="https://www.jiyuulife.net/building-a-python-web-scraper/">Tips For Building A Python Web Scraper</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">369</post-id>	</item>
		<item>
		<title>Update PHP Version For WordPress On Debian 9</title>
		<link>https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/</link>
					<comments>https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 30 Apr 2020 13:46:52 +0000</pubDate>
				<category><![CDATA[Site]]></category>
		<category><![CDATA[Apache2]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP7]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[UpdraftPlus]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=339</guid>

					<description><![CDATA[<p>As of April 30, 2020, the current version of Google Cloud Platform&#8217;s WordPress Click-to-Deploy deploys WordPress 5.2.3 using PHP version 7.0.33. PHP 7.0.33 was released in January 10, 2019 and since then the PHP developers have released the most recent and stable 7.4.5 version. As a site administrator it is highly essential to update system ... <a title="Update PHP Version For WordPress On Debian 9" class="read-more" href="https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/" aria-label="Read more about Update PHP Version For WordPress On Debian 9">Read more</a></p>
The post <a href="https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/">Update PHP Version For WordPress On Debian 9</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<p>As of April 30, 2020, the current version of <a href="https://console.cloud.google.com/marketplace/details/click-to-deploy-images/wordpress" class="aioseop-link">Google Cloud Platform&#8217;s WordPress Click-to-Deploy</a> deploys WordPress 5.2.3 using PHP version 7.0.33. <a href="https://www.php.net/releases/index.php" class="aioseop-link">PHP 7.0.33</a> was released in January 10, 2019 and since then the PHP developers have released the most recent and <a href="https://www.php.net/ChangeLog-7.php#7.4.5" class="aioseop-link">stable 7.4.5 version</a>. As a site administrator it is highly essential to update system versions in order to improve both security and performance.</p>



<p>There are many blogs &#8211; especially <a href="https://wordpress.org/support/update-php/" class="aioseop-link">the article from WordPress</a> themselves &#8211; which go into details about why updating PHP is important. Since I would be spitting out the exact same details I will not write about it here. However, pages I have visited would simply ask WordPress administrators to contact their webmaster/sysadmins to update the PHP version, which will not fly for an amateur such as myself. In addition, building from source often results in faster performance, so I took on that challenge as well. To serve as future reference, I have created a manual in the process of updating this site from PHP7.0 to PHP7.4.5. Continue on for steps on how to do it yourself!<br></p>



<span id="more-339"></span>



<hr class="wp-block-separator has-css-opacity"/>



<h2 class="wp-block-heading">Environment</h2>



<p>This article uses the following environment from the Google Cloud Platform:</p>



<ul class="wp-block-list">
<li>Debian 9 (Stretch)</li>



<li>WordPress 5.4.1 (/var/www/html/)</li>



<li>Apache 2.4.25 (/etc/apache2)</li>



<li>PHP 7.0.33 &#8211;&gt; PHP 7.4.5 (/etc/php/)</li>



<li>phpmyadmin 4.6.6 (just FYI)</li>
</ul>



<p>Make sure to check the above and make the necessary changes to directories or versioning before beginning the below manual.</p>



<h2 class="wp-block-heading">Before You Start</h2>



<h3 class="wp-block-heading">DISCLAIMER</h3>



<p><strong><span class="has-inline-color has-vivid-red-color">I can NOT guarantee there are no issues with this manual!</span></strong></p>



<p>It is imperative that you make all of the necessary backups to both WordPress and the server before you begin (Even though the previous version of PHP will not be removed from the server). For WordPress database and settings backup I use the free <a href="https://updraftplus.com/" class="aioseop-link">UpdraftPlus</a> (which saved this site for me, as I have noted in my other <a href="https://www.jiyuulife.net/jiyuulife-lives/" class="aioseop-link">post</a>). For the VM part, if using GCP, follow the manual <a href="https://cloud.google.com/compute/docs/disks/create-snapshots" class="aioseop-link">here</a> to create a disk snapshot you can use to restore if things go kaput. The last section in this post, &#8220;Rollback&#8221;, details the steps to switch back to the previous version of PHP in the Apache environment without re-loading the disk &#8211; in case somebody needs to look at it in the future.</p>



<h3 class="wp-block-heading">Server RAM Requirements</h3>



<p>Because we are building PHP from scratch there needs to be sufficient RAM in your server for &#8220;make&#8221;-ing the source:</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img data-recalc-dims="1" loading="lazy" decoding="async" width="300" height="210" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-4.51.42-PM.png?resize=300%2C210&#038;ssl=1" alt="" class="wp-image-341" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-4.51.42-PM.png?resize=300%2C210&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-4.51.42-PM.png?resize=768%2C539&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-4.51.42-PM.png?w=924&amp;ssl=1 924w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption class="wp-element-caption">Figure 1-1 : GCP&#8217;s &#8220;n1-standard-1&#8221; Compute VM with 3.75GB RAM</figcaption></figure></div>


<p>Some website sources mention that at least 2GB of RAM is necessary to compile and build PHP 7.4.5, so do make sure that your resources are secured at least for the &#8220;Build/Install PHP7.4.5 From Source&#8221; of this guide. For those who have less traffic or otherwise normally doesn&#8217;t require so much resource, it is alright to increase the RAM temporarily and then revert to original settings once upgrading of PHP is complete.</p>



<h2 class="wp-block-heading">Manual</h2>



<h3 class="wp-block-heading">Updating Repositories</h3>



<p>Open up terminal or SSH into your WordPress server. Type the following to get a list of currently installed PHP extensions:</p>



<pre class="wp-block-preformatted">php -m</pre>



<p>Note all of the extensions in the output &#8211; you will need to install them on the fresh version of PHP later. Some extensions &#8211; especially mysql and mbscript, are absolutely required to operate WordPress and phpmyadmin.</p>



<p>Once all noted down, proceed with setting up repositories and installing some initial packages:</p>



<pre class="wp-block-preformatted">sudo apt install apt-transport-https lsb-release
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg # Download the signing key
sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" &gt; /etc/apt/sources.list.d/php.list'
sudo apt update
sudo apt install -y build-essential pkg-config libxml2-dev sqlite3 libsqlite3-dev libapache2-mod-php7.4</pre>



<h3 class="wp-block-heading">Build/Install PHP7.4.5 From Source</h3>



<p>Proceed with downloading and extracting the new PHP version from the <a href="https://www.php.net/downloads" class="aioseop-link">official site</a>.</p>



<pre class="wp-block-preformatted">wget https://www.php.net/distributions/php-7.4.5.tar.gz
tar xf php-7.4.5.tar.gz
cd php-7.4.5
./configure
make
sudo make install</pre>



<p>The &#8220;make&#8221; command above will take some time, so grab a coffee or stretch for 5-10 minutes as a break! When everything above is finished invoking PHP from command line should now show the new version:</p>



<pre class="wp-block-preformatted">php -v</pre>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="846" height="154" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.11.41-PM-1.png?resize=846%2C154&#038;ssl=1" alt="" class="wp-image-344" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.11.41-PM-1.png?w=846&amp;ssl=1 846w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.11.41-PM-1.png?resize=300%2C55&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.11.41-PM-1.png?resize=768%2C140&amp;ssl=1 768w" sizes="auto, (max-width: 846px) 100vw, 846px" /><figcaption class="wp-element-caption">Figure 1-2 : Confirming PHP 7.4.5, built from scratch.</figcaption></figure></div>


<h3 class="wp-block-heading">Install PHP Extensions</h3>



<p>Remember when I asked you to note all of the extensions in the previous PHP? Now is the time to install them in your new PHP version. Some extensions may have either been removed or combined with each other into a new extension &#8211; the prompt will tell you so if you ever come into this situation. The command containing the extensions I installed is as follows:</p>



<pre class="wp-block-preformatted">sudo apt install -y php7.4-common php7.4-xml php7.4-mysql php7.4-pdo php7.4-phar php7.4-simplexml php7.4-curl php7.4-mbstring php7.4-imagick php7.4-zip php7.4-gd</pre>



<h3 class="wp-block-heading">Activating New PHP Version in Apache</h3>



<p>Since you didn&#8217;t remove the old PHP, Apache is still using the old PHP version. Update and restart Apache configurations with the following code:</p>



<pre class="wp-block-preformatted">sudo a2dismod php7.0
sudo a2enmod php7.4
sudo service apache2 restart</pre>



<p>&#8230; And done! Your WordPress should now be using the new PHP version, and can be confirmed by going to Admin Settings -&gt; Tools -&gt; Site Health -&gt; Info.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img data-recalc-dims="1" loading="lazy" decoding="async" width="300" height="293" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.25.49-PM.png?resize=300%2C293&#038;ssl=1" alt="" class="wp-image-345" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.25.49-PM.png?resize=300%2C293&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.25.49-PM.png?resize=1024%2C1000&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.25.49-PM.png?resize=768%2C750&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.25.49-PM.png?resize=1536%2C1500&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-30-at-7.25.49-PM.png?w=1642&amp;ssl=1 1642w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption class="wp-element-caption">Figure 1-3 : &#8220;Site Health&#8221; info page, showing newly installed PHP version.</figcaption></figure></div>


<h2 class="wp-block-heading">Rollback</h2>



<p>Rollback is simple &#8211; it is just the &#8220;Activating New PHP Version in Apache&#8221; section&#8217;s code with the two PHP versions switched:</p>



<pre class="wp-block-preformatted">sudo a2dismod php7.4
sudo a2enmod php7.0
sudo service apache2 restart</pre>The post <a href="https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/">Update PHP Version For WordPress On Debian 9</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
					<wfw:commentRss>https://www.jiyuulife.net/update-php-version-for-wordpress-on-debian-9/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">339</post-id>	</item>
		<item>
		<title>Guide To Fade-In Effect On Scroll Into View</title>
		<link>https://www.jiyuulife.net/fade-in-effect-on-scroll-into-view/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 29 Apr 2020 06:58:24 +0000</pubDate>
				<category><![CDATA[Site]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Fade-In]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[scroll]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[viewport]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=309</guid>

					<description><![CDATA[<p>Did you notice this fade-in?? Many of the UI we see today, whether it&#8217;s on TV, slideshow presentations, mobile apps and many other kinds of visuals, all incorporate some form of transition to keep the user engaged. A few days ago I was designing a mock e-commerce website for a local business and spent quite ... <a title="Guide To Fade-In Effect On Scroll Into View" class="read-more" href="https://www.jiyuulife.net/fade-in-effect-on-scroll-into-view/" aria-label="Read more about Guide To Fade-In Effect On Scroll Into View">Read more</a></p>
The post <a href="https://www.jiyuulife.net/fade-in-effect-on-scroll-into-view/">Guide To Fade-In Effect On Scroll Into View</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="384" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=1024%2C384&#038;ssl=1" alt="" class="wp-image-310" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=1024%2C384&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=300%2C112&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=768%2C288&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=1536%2C576&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?w=1766&amp;ssl=1 1766w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>


<p class="fade-in"><strong>Did you notice this fade-in??</strong><br><br>Many of the UI we see today, whether it&#8217;s on TV, slideshow presentations, mobile apps and many other kinds of visuals, all incorporate some form of transition to keep the user engaged. A few days ago I was designing a mock e-commerce website for a local business and spent quite some time stuck on how to implement this fade-in effect. While there are a lot of ways to incorporate fade-in effects and there are many webpages showing you how to do so, I&#8217;ve found that there are no articles which matched the exact effect I was looking for, and thus I&#8217;m putting it here for the sake of documentation and knowledge sharing.<br><br>Read on to learn more about how to incorporate fade-in of elements the moment it is <strong>partly</strong> visible in the viewport.<br></p>



<span id="more-309"></span>



<hr class="wp-block-separator has-css-opacity"/>



<h2 class="wp-block-heading">Why Incorporate Transition Effects??</h2>



<p>Before we go into the actual implementation details, readers may be inclined to understand why fade-in and other transition effects are important in keeping users engaged. The following are some of my observations.</p>



<h3 class="wp-block-heading">As a form of guidance</h3>



<p>Have you ever sat in a meeting with slideshow presentations and the presenter changes into the next slide with so much information scattered around that you have no idea where to look?? It happens very often for me and if the presenter does not use a laser pointer device it would require much more of my attention to simultaneously listen to the presenter and follow the material. </p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="710" height="391" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/transition_effect.gif?resize=710%2C391&#038;ssl=1" alt="" class="wp-image-317"/><figcaption class="wp-element-caption">Figure 1-1 : A crude example of fade-in effect to guide the reader through a workflow.</figcaption></figure></div>


<p>Incorporating some transition effects throughout the UI serves to prevent the user from being distracted by other content and keeps them focused on the current topic.</p>



<h3 class="wp-block-heading">More natural feel</h3>


	<div class="wp-block-jetpack-gif">
		<figure>
							<div class="wp-block-jetpack-gif-wrapper" style="padding-top:55%">
					<iframe src="https://giphy.com/embed/dXFh5Rzb2dYuhC3yLX" title="https://giphy.com/gifs/silversunpickups-silversun-pickups-sspu-widows-weeds-dXFh5Rzb2dYuhC3yLX"></iframe>
				</div>
										<figcaption class="wp-block-jetpack-gif-caption gallery-caption">Figure 1-2 : Flipping to a new page is an example of a smooth transitioning</figcaption>
					</figure>
	</div>
	


<p>Flipping pages of a book, swiping right on a smartphone app, scrolling down a webpage&#8230; all of these smooth movements ease and prepare the user for new content. Everything in the perceivable real world takes time to execute &#8211; nothing switches from 0 to 1 in an instant. While incorporating transition effects DO have impact on performance (Windows&#8217;s UI is a prime example&#8230; <a href="https://www.pcworld.com/article/2991508/how-to-disable-window-animations-in-windows-10.html" class="aioseop-link">disabling Windows animations</a> reduces CPU load and enables a faster UI), sacrificing some performance or resources to engage the visitor is a small price worth paying.</p>



<h3 class="wp-block-heading">Better than static</h3>


	<div class="wp-block-jetpack-gif aligncenter">
		<figure>
							<div class="wp-block-jetpack-gif-wrapper" style="padding-top:56%">
					<iframe src="https://giphy.com/embed/TjRsA8xSrN24T4vBaC" title="pixel 4"></iframe>
				</div>
										<figcaption class="wp-block-jetpack-gif-caption gallery-caption">Figure 1-3 : The new Pixel 4&#8217;s touchless swipe feature demo</figcaption>
					</figure>
	</div>
	


<p>The official <a href="https://store.google.com/product/pixel_4" class="aioseop-link">Google Pixel 4</a> product page is a prime, one-of-a-kind example (although possibly overkill for most) of different effects to wow the user. I would never have imagined such a webpage could exist, and the amount of effort that went into developing this page must have been substantial. In the context of adding transitions to a webpage or other form of UI, I strongly believe in a form of the <a href="https://en.wikipedia.org/wiki/Pareto_principle" class="aioseop-link">Pareto Principle</a>, where twenty percent of your effort equates to eighty percent of the result. In other words, there is no need to spent so much energy to make your webpage look extravagant like <a href="https://store.google.com/product/pixel_4" class="aioseop-link">Google Pixel&#8217;s</a> or <a href="https://www.apple.com/iphone-11-pro/" class="aioseop-link">Apple IPhone&#8217;s</a> product page, but small transition elements definitely do breathe life into your UI.</p>



<h2 class="wp-block-heading">Implementing Fade-In On Scroll Into Viewport</h2>



<h3 class="wp-block-heading">CSS</h3>



<p>Let&#8217;s start with the CSS:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="384" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=1024%2C384&#038;ssl=1" alt="" class="wp-image-310" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=1024%2C384&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=300%2C112&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=768%2C288&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?resize=1536%2C576&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-11.33.26-AM.png?w=1766&amp;ssl=1 1766w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Figure 2-1 : CSS settings for a class and it&#8217;s subclass. Elements with classname &#8220;fade-in&#8221; will appear hidden by default, with the &#8220;is-visible&#8221; subclass triggering the animation.</figcaption></figure></div>


<p>The following code initiates settings for a class and subclass to perform the fade-in effect:</p>



<pre class="wp-block-preformatted">.fade-in {
  opacity: 0;
  transform: translateY(20vh);
  visibility: hidden;
  transition: opacity 0.6s ease-out, transform 1.2s ease-out;
  will-change: opacity, visibility;
}
.fade-in.is-visible {
  opacity: 1;
  transform: none;
  visibility: visible;
}</pre>



<p>The combination of 0 opacity and hidden visibility causes all elements with class &#8220;fade-in&#8221; to appear invisible by default. The <strong><span class="has-inline-color has-vivid-red-color">transform: translateY(20vh)</span></strong> provides the upwards movement associated with an element fading into view. Those who don&#8217;t want the upwards movement can remove the transform parts in the class. Lastly, the <strong><span class="has-inline-color has-vivid-red-color">transition</span></strong> line sets the parameters for how fast the fade-in should occur &#8211; feel free to adjust and experiment accordingly.</p>



<p>Next, the &#8220;is-visible&#8221; subclass provides the mechanism for the dynamic fade-in effect. In essence, when conditions for the animation are met the &#8220;is-visible&#8221; classname is appended to element with the &#8220;fade-in&#8221; class which will then cause the animation to begin. Adding &#8220;is-visible&#8221; to an element withOUT the &#8220;fade-in&#8221; class will do nothing. The appending of the subclass is done via JQuery, thus every event compatible with JQuery can be used to trigger the appending of &#8220;is-visible&#8221; (scrolling, button click, element change, etc).</p>



<h3 class="wp-block-heading">JavaScript/JQuery</h3>



<p>The next part deals with the JQuery. Here&#8217;s the code:</p>



<pre class="wp-block-preformatted"><script>
$(window).scroll(function() {
    $('.fade-in').each(function() {
        var top_of_element = $(this).offset().top;
        var bottom_of_element = $(this).offset().top + $(this).outerHeight();
        var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
        var top_of_screen = $(window).scrollTop();

        if ((bottom_of_screen > top_of_element) &amp;amp;amp;&amp;amp;amp; (top_of_screen &amp;amp;lt; bottom_of_element) &amp;amp;amp;&amp;amp;amp; !$(this).hasClass('is-visible')) {
            $(this).addClass('is-visible');
        }
    });
});
</script>&lt;script&gt;
$(window).scroll(function() {
    $('.fade-in').each(function() {
        var top_of_element = $(this).offset().top;
        var bottom_of_element = $(this).offset().top + $(this).outerHeight();
        var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
        var top_of_screen = $(window).scrollTop();

        if ((bottom_of_screen &gt; top_of_element) &amp;&amp; (top_of_screen &lt; bottom_of_element) &amp;&amp; !$(this).hasClass('is-visible')) {
            $(this).addClass('is-visible');
        }
    });
});
&lt;/script&gt;</pre>



<p>At the top is where the &#8220;event&#8221; is designated. In this situation we are detecting all scrolling of the page, but it can be modified to another event such as button click or detecting changes in some other element. Next, the <strong><span class="has-inline-color has-vivid-red-color">$(&#8216;.fade-in&#8217;).each(function() {</span></strong> checks for all elements with the &#8220;fade-in&#8221; class and runs the code afterwards accordingly. This is especially important to control fade-in effects for individual elements, because without this code all elements will fade-in if a single one is partially visible in the viewport.</p>



<p>The rest of the code is based off of a wonderful <a href="https://stackoverflow.com/questions/487073/how-to-check-if-element-is-visible-after-scrolling" class="aioseop-link">StackOverflow answer</a> in which the element position and viewport dimensions are scanned and then compared to see if the element exists in the viewport. A <strong><span class="has-inline-color has-vivid-red-color">!$(this).hasClass(&#8216;is-visible&#8217;)</span></strong> is added as an additional condition to prevent the element from fading in twice.</p>



<p>This jQuery code can be added anywhere in the code, but do make sure that the jQuery library has already been imported and that the code itself has finished loading before the user can scroll. In a faster, optimized website this shouldn&#8217;t be such an issue, but otherwise it is suggested to place the code at the end of the &#8220;head&#8221; element.</p>



<h3 class="wp-block-heading">HTML</h3>



<p>The HTML part is easy &#8211; just add the &#8220;fade-in&#8221; class to all elements you wish to animate. For example, the following shows the class for the top paragraph of this webpage which has the fade-in animation:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="118" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.37.08-PM.png?resize=1024%2C118&#038;ssl=1" alt="" class="wp-image-327" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.37.08-PM.png?resize=1024%2C118&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.37.08-PM.png?resize=300%2C35&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.37.08-PM.png?resize=768%2C89&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.37.08-PM.png?resize=1536%2C178&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.37.08-PM.png?resize=2048%2C237&amp;ssl=1 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Figure 2-2 : HTML demonstrating the class &#8220;fade-in&#8221;.</figcaption></figure>



<p>Note that the JQuery code triggers for EACH element with the fade-in class, thus performance may be significantly impacted for a huge amount of elements. Consider grouping elements under a single parent element and setting the class for that top-level element to simulate fade-in effect for multiple elements at the same time.</p>



<h2 class="wp-block-heading">Note to WordPress Users</h2>



<h3 class="wp-block-heading">Careful of the jQuery code!</h3>



<p>For WordPress users, note that &#8220;$&#8221; is substituted for &#8220;jQuery&#8221; because <a href="https://wordpress.stackexchange.com/questions/59539/jquery-in-wordpress-why-is-it-not-working" class="aioseop-link">WordPress runs jQuery in safe mode</a> and therefore uses a different syntax to avoid conflict with other potential libraries which also use &#8220;$&#8221;. Refer to the below code block for an updated version for WordPress users:</p>



<pre class="wp-block-preformatted"><script>
$(window).scroll(function() {
    $('.fade-in').each(function() {
        var top_of_element = $(this).offset().top;
        var bottom_of_element = $(this).offset().top + $(this).outerHeight();
        var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
        var top_of_screen = $(window).scrollTop();

        if ((bottom_of_screen > top_of_element) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; (top_of_screen &amp;amp;amp;amp;lt; bottom_of_element) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; !$(this).hasClass('is-visible')) {
            $(this).addClass('is-visible');
        }
    });
});
</script>&lt;script&gt;
jQuery(window).scroll(function() {
    jQuery('.fade-in').each(function() {
        var top_of_element = jQuery(this).offset().top;
        var bottom_of_element = jQuery(this).offset().top + jQuery(this).outerHeight();
        var bottom_of_screen = jQuery(window).scrollTop() + jQuery(window).innerHeight();
        var top_of_screen = jQuery(window).scrollTop();

        if ((bottom_of_screen &gt; top_of_element) &amp;&amp; (top_of_screen &lt; bottom_of_element) &amp;&amp; !jQuery(this).hasClass('is-visible')) {
            jQuery(this).addClass('is-visible');
        }
    });
});
&lt;/script&gt;</pre>



<h3 class="wp-block-heading">Make Settings via the WordPress UI</h3>



<p>For the CSS portion of the code, all WordPress themes have a UI setting for &#8220;Additional CSS&#8221;. If you don&#8217;t feel like fiddling with the theme code, setting it via the UI is absolutely painless:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="590" height="808" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.23-PM.png?resize=590%2C808&#038;ssl=1" alt="" class="wp-image-330" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.23-PM.png?w=590&amp;ssl=1 590w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.23-PM.png?resize=219%2C300&amp;ssl=1 219w" sizes="auto, (max-width: 590px) 100vw, 590px" /><figcaption class="wp-element-caption">Figure 3-1 : The &#8220;Additional CSS&#8221; section of WordPress theme customization</figcaption></figure></div>


<p>Next is the jQuery code. While there is the option to paste the code via the Theme code editor, there is a separate WordPress add-on called <a href="https://wordpress.org/plugins/header-and-footer-scripts/" class="aioseop-link">Header and Footer Scripts</a> which allows you to set header and footer code via the admin console (<strong><span class="has-inline-color has-vivid-red-color">Settings -&gt; Header and Footer Scripts</span></strong>):</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="720" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?resize=1024%2C720&#038;ssl=1" alt="" class="wp-image-331" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?resize=1024%2C720&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?resize=300%2C211&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?resize=768%2C540&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?resize=1536%2C1080&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?resize=2048%2C1440&amp;ssl=1 2048w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.40.51-PM.png?w=2100&amp;ssl=1 2100w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Figure 3-2 : jQuery code in the footer section. It is also OK to paste the code in the header section as well.</figcaption></figure></div>


<p>Lastly, for the HTML itself, the new &#8220;Block&#8221; interface of WordPress posts has an advanced section for Additional CSS classes. Just throw the &#8220;fade-in&#8221; class to that setting as shown below:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="421" height="1024" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.10-PM.png?resize=421%2C1024&#038;ssl=1" alt="" class="wp-image-332" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.10-PM.png?resize=421%2C1024&amp;ssl=1 421w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.10-PM.png?resize=123%2C300&amp;ssl=1 123w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-29-at-2.41.10-PM.png?w=554&amp;ssl=1 554w" sizes="auto, (max-width: 421px) 100vw, 421px" /><figcaption class="wp-element-caption">Figure 3-3 : Advanced settings showing Additional CSS classes field. This UI can be found in WordPress post&#8217;s right side column &#8220;Block Settings&#8221;.</figcaption></figure></div>


<p></p>The post <a href="https://www.jiyuulife.net/fade-in-effect-on-scroll-into-view/">Guide To Fade-In Effect On Scroll Into View</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">309</post-id>	</item>
		<item>
		<title>Simple Guide to WordPress Permalink</title>
		<link>https://www.jiyuulife.net/guide-to-wordpress-permalink/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 24 Apr 2020 13:02:17 +0000</pubDate>
				<category><![CDATA[Site]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Permalinks]]></category>
		<category><![CDATA[Query Parameters]]></category>
		<category><![CDATA[URI]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=278</guid>

					<description><![CDATA[<p>Update 2023-02-11 : Added an additional check (modify &#8220;apache2.conf&#8221; file) at the end of the article in the case the existing method doesn&#8217;t work. As I was reviving this site after its two-year hiatus, I noticed that I neglected to post an article detailing how to set up WordPress permalinks. Since it requires some modifications ... <a title="Simple Guide to WordPress Permalink" class="read-more" href="https://www.jiyuulife.net/guide-to-wordpress-permalink/" aria-label="Read more about Simple Guide to WordPress Permalink">Read more</a></p>
The post <a href="https://www.jiyuulife.net/guide-to-wordpress-permalink/">Simple Guide to WordPress Permalink</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<p><img data-recalc-dims="1" loading="lazy" decoding="async" class="aligncenter wp-image-282 size-large" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-4.23.54-PM.png?resize=1024%2C452&#038;ssl=1" alt="" width="1024" height="452" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-4.23.54-PM.png?resize=1024%2C452&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-4.23.54-PM.png?resize=300%2C133&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-4.23.54-PM.png?resize=768%2C339&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-4.23.54-PM.png?w=1272&amp;ssl=1 1272w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>Update 2023-02-11 : Added an additional check (modify &#8220;apache2.conf&#8221; file) at the end of the article in the case the existing method doesn&#8217;t work.</p>
<p>As I was reviving this site after its two-year hiatus, I noticed that I neglected to post an article detailing how to set up WordPress permalinks. Since it requires some modifications on the server side it took a bit of trial-and-error to re-enable it. If even I could forget how to make the settings after two years, then it is definitely reason enough to make an article out of it (for my own sake!).</p>
<p>Read on to learn more about why and how to set WordPress permalinks.</p>
<p><span id="more-278"></span></p>
<hr>
<p>As this article serves as more of an appendix to the previous wordpress articles, I will NOT be linking this article to previous WordPress tutorials (for now&#8230; in the future I&#8217;m considering to link articles by keywords/hashtags). However, I will provide the previous tutorials for how to get a WordPress site up-and-running using Google Cloud below, so do check them out if you&#8217;re interested:</p>
<p></p>
<figure id="attachment_89" aria-describedby="caption-attachment-89" style="width: 231px" class="wp-caption alignleft"><a href="https://www.jiyuulife.net/click-to-deploy-wordpress-google-cloud/"><img data-recalc-dims="1" loading="lazy" decoding="async" class="wp-image-89" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/06/google-cloud-logo.jpg?resize=241%2C150&#038;ssl=1" alt="" width="241" height="150"></a><figcaption id="caption-attachment-89" class="wp-caption-text">How To Deploy WordPress Using Google Cloud Click-to-Deploy</figcaption></figure>
<figure id="attachment_61" aria-describedby="caption-attachment-61" style="width: 190px" class="wp-caption alignleft"><a href="https://www.jiyuulife.net/registering-google-domains-to-google-cloud-wordpress/"><img data-recalc-dims="1" loading="lazy" decoding="async" class="wp-image-61" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/06/google-domains.jpg?resize=200%2C151&#038;ssl=1" alt="" width="200" height="151" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/06/google-domains.jpg?w=400&amp;ssl=1 400w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/06/google-domains.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/06/google-domains.jpg?resize=290%2C220&amp;ssl=1 290w" sizes="auto, (max-width: 200px) 100vw, 200px" /></a><figcaption id="caption-attachment-61" class="wp-caption-text">Registering Google Domains to Google Cloud WordPress</figcaption></figure>
<figure id="attachment_62" aria-describedby="caption-attachment-62" style="width: 251px" class="wp-caption alignleft"><a href="https://www.jiyuulife.net/secure-wordpress-https/"><img data-recalc-dims="1" loading="lazy" decoding="async" class="wp-image-62" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/06/HTTPS_icon.png?resize=261%2C133&#038;ssl=1" alt="" width="261" height="133"></a><figcaption id="caption-attachment-62" class="wp-caption-text">Secure your WordPress Using HTTPS (Current Post)</figcaption></figure>
<hr>
<h2>Why Permalink?</h2>
<p>There are many pages scattered around the internet explaining why permalinks are so important &#8211; almost to the point where it should be necessary &#8211; so I will try not to repeat what others are saying and add my own spin to the importance of permalinks.</p>
<p>Everyone who has initialized a WordPress site knows that the default page linking is via the &#8220;p&#8221; query parameter which points to the row number in the WordPress database where the article exists. There are a number of problems with the second half of the previous sentence (other than the grammar issues&#8230; I know!), but below are some reasons why:</p>
<h3>&#8220;?p=123&#8221;</h3>
<p>What does the query parameter &#8220;p&#8221; stand for? &#8220;<span style="text-decoration: underline;">P</span>age&#8221;? &#8220;<span style="text-decoration: underline;">P</span>ost&#8221;? &#8220;<span style="text-decoration: underline;">P</span>arameter&#8221;? What significance does it have with the contents of the page (By the way, the answer is &#8220;None Whatsoever&#8221;).</p>
<p>This parameter naming is quite ambiguous and doesn&#8217;t leave any impact to the user. Nowadays browser bookmarks or URL autofill technologies are also searchable by Page Title which diminishes the issue, but a sole &#8220;p&#8221; parameter doesn&#8217;t tell the reader anything about the category nor the contents of the page.&nbsp;</p>
<h3>Query Parameters Are Growing Weaker</h3>
<p>Query parameters are becoming the subject of growing debate over the past few years. Some sites pass tokens or keys as query parameters which cause bloating and cluttering of the URL. SEO performance also takes a hit when you are using the default permalink structure WordPress provides (&#8220;p&#8221; parameter above). Apple&#8217;s mission to protect Safari users&#8217; privacy included a <a href="https://webkit.org/blog/9521/intelligent-tracking-prevention-2-3/">release</a> which strips query parameters when navigating from a site flagged by ITP&#8217;s model used for detecting whether the site tracks users in an invasive manner. Lastly, analytics tools such as Google Analytics may strip query parameters in order to make reports cleaner &#8211; this means that if you control your page content via query parameters such as &#8220;p&#8221;, then they may all be analyzed and clumped together as one single entity.</p>
<h3>URL Path vs Query Parameters</h3>
<p>There is a common best practice (at least for <a href="https://programmerspub.com/blog/general/uri-parameter-vs-query-parameter">developing REST APIs</a>) that the URL should contain the resource to be accessed while the query parameter be used to filter its results. If you consider the WordPress database as a collection of articles, then it would seem alright to use query parameters to filter the relevant articles. However, WordPress by default has no easy way to implement this since, AFAIK, there are no other parameters other than &#8220;p&#8221; for filtering posts from the WordPress database. Thus, as an alternative, it would make more sense to use URL paths structure the URL to something like &#8220;<em>www.example.com</em>/<strong>post</strong>/<strong>category/topic</strong>&#8220;.</p>
<h2>Setting Up WordPress Permalinks</h2>
<p>In the case of GCP&#8217;s WordPress Click-To-Deploy feature, WordPress is hosted using Apache, and therefore Apache needs to be reconfigured to allow rules for WordPress permalinks. The guide below breaks down the process into two parts &#8211; server and client (WordPress Admin) side. But before we get started, this post is made as of April 24, 2020, with the GCP Compute VM instantiated the day before (April 23, 2020). Thus the VM will have the following configurations, and you will need to adjust accordingly for any future changes in VM configuration:</p>
<ul>
<li><strong>Debian 9</strong>.11 (&#8220;Stretch&#8221;)</li>
<li><strong>Apache 2</strong>.4.25</li>
<li><strong>WordPress 5.2.3</strong></li>
</ul>
<h3>Server-Side : Modify Apache Configurations</h3>
<p>SSH into your VM instance.<br>The following screenshots are all taken from GCP&#8217;s SSH interface.</p>
<p>For GCP&#8217;s click-to-deploy instance, there should be a &#8220;wordpress.conf&#8221; in apache2 subdirectory. Check that it exists with the following command:</p>
<p><code><strong>ls -al /etc/apache2/sites-available/wordpress.conf</strong></code></p>
<p>If it exists, then this is the file you will need to modify. Go ahead and open it up with vim (or whatever editor you prefer):</p>
<p><code><strong>sudo vim /etc/apache2/sites-available/wordpress.conf</strong></code></p>
<p>If it the above DOESN&#8217;T exist, it&#8217;s okay, the above command will create a new file for you so just paste in the &#8220;final result&#8221; section just down below and save.</p>
<p>You will need to add the following parameters under the &#8220;Directory&#8221; section:</p>
<p><span style="color: #ff0000;"><strong>Options FollowSymLinks</strong></span><br><span style="color: #ff0000;"><strong>AllowOverride All</strong></span></p>
<p>Your final result for the file contents should look something like as follows:</p>
<p><strong>&lt;Directory /var/www/html&gt;</strong><br><strong>&nbsp; <span style="color: #0000ff;">Options FollowSymLinks</span></strong><br><strong>&nbsp; Options -Indexes</strong><br><strong>&nbsp; <span style="color: #0000ff;">AllowOverride All</span></strong><br><strong>&lt;/Directory&gt;</strong></p>
<p>Save and exit (using &#8220;:x&#8221; for vim). Afterwards, run the following command to restart Apache:</p>
<p><strong><code>sudo&nbsp;service apache2 restart</code></strong></p>
<h3>WordPress Admin : Change Permalink Settings</h3>
<p>Admin settings are very easy: head on over to the Permalinks settings using the following link (replace hostname with the hostname of your site):</p>
<p><strong>${{HOSTNAME}}/wp-admin/options-permalink.php</strong></p>
<figure id="attachment_300" aria-describedby="caption-attachment-300" style="width: 1014px" class="wp-caption alignnone"><img data-recalc-dims="1" loading="lazy" decoding="async" class="wp-image-300 size-large" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?resize=1024%2C502&#038;ssl=1" alt="" width="1024" height="502" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?resize=1024%2C502&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?resize=300%2C147&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?resize=768%2C377&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?resize=1536%2C754&amp;ssl=1 1536w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?resize=2048%2C1005&amp;ssl=1 2048w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?w=2100&amp;ssl=1 2100w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2020/04/Screen-Shot-2020-04-24-at-8.52.42-PM.png?w=3150&amp;ssl=1 3150w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption id="caption-attachment-300" class="wp-caption-text">Figure 1-1 : WordPress Permalinks Settings Page</figcaption></figure>
<p>I prefer to use &#8220;Post name&#8221; as it is the most simple and gets the point across. Whatever change you decide to make, make sure to hit &#8220;Save Changes&#8221; at the bottom to reflect the changes.</p>
<h3>If it doesn&#8217;t work, check apache2.conf</h3>
<p>Some folks may have another setup or use updated versions of some software to run their WordPress site. If the above guide doesn&#8217;t work, then you may be able to fix it by modifying the <strong>/etc/apache2/apache2.conf</strong> configuration. If this file exists, change the AllowOverride setting inside of the &#8220;<em><strong>&lt;Directory /var/www/&gt;</strong></em>&#8221; to <strong>AllowOverride All</strong>. Below is what I have for my apache2.conf:</p>
<p><strong>&lt;Directory /var/www/&gt;<br>&nbsp; AddType application/x-httpd-php .htm<br>&nbsp; Options Indexes FollowSymLinks<br>&nbsp; <span style="color: #0000ff;">AllowOverride All</span><br>&nbsp; Require all granted<br>&lt;/Directory&gt;<br></strong></p>
<h2>Done!</h2>
<p>Your permalinks settings should now be active and all of your pages should now reflect its permalinked version. There are multiple ways to test whether it&#8217;s working, such as simply clicking on a post on your website, or checking &#8220;preview mode&#8221; of a post you are currently editing. If it is not to your liking, you can always just change it at any time via the Permalinks setting. However, a <span style="color: #ff0000;"><strong>word of warning</strong></span>: changing your permalink will require all your pages to be re-indexed, and as a consequence your SEO performance will fall <strong>considerably</strong>. It is wise to consider and set your permalink preferences in stone so that you will not have to change it in the future and risk your site performance.</p>


<p></p>The post <a href="https://www.jiyuulife.net/guide-to-wordpress-permalink/">Simple Guide to WordPress Permalink</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">278</post-id>	</item>
		<item>
		<title>JiyuuLife is Live Again!</title>
		<link>https://www.jiyuulife.net/jiyuulife-lives/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 24 Apr 2020 10:23:49 +0000</pubDate>
				<category><![CDATA[Meta]]></category>
		<category><![CDATA[Site]]></category>
		<category><![CDATA[COVID-19]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[UpdraftPlus]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=283</guid>

					<description><![CDATA[<p>  Wow, it&#8217;s been a while! While neglecting to publish some new posts due to being busy with work, I also overlooked the fact that after the GCP trial period ends, there is only a 30-day grace period for you to update to non-free status before they TERMINATE your compute VM. This means that while ... <a title="JiyuuLife is Live Again!" class="read-more" href="https://www.jiyuulife.net/jiyuulife-lives/" aria-label="Read more about JiyuuLife is Live Again!">Read more</a></p>
The post <a href="https://www.jiyuulife.net/jiyuulife-lives/">JiyuuLife is Live Again!</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<p> </p>
<p>Wow, it&#8217;s been a while!</p>
<p>While neglecting to publish some new posts due to being busy with work, I also overlooked the fact that after the <a href="https://cloud.google.com/free">GCP trial period</a> ends, there is only a <a href="https://cloud.google.com/free/docs/gcp-free-tier#end">30-day grace period</a> for you to update to non-free status before they TERMINATE your compute VM. This means that while your deployment history and GCP project will still be kept, everything else &#8211; including the things you installed/changed on your VM &#8211; will be wiped.</p>
<p><span id="more-283"></span></p>
<p>Lately I have been speaking to some friends and relatives about the Covid-19 situation and whether there is anything I can do to help my family or the local community. Especially in these times when there is little freedom for people to go outside and enjoy brick-and-mortar establishments, it suddenly became ever-so-important to have an online presence in order to maintain connection to your customer base. Many companies&#8217; research concludes that the average user is spending MUCH more time <a href="https://www.forbes.com/sites/johnkoetsier/2020/03/26/news-spend-up-over-1000-thanks-to-coronavirus-and-covid-19/#49436e634f14">shopping online, playing online games, and watching online videos</a>, which is a given.</p>
<p>In my resolve to offer my technical and digital assistance to potential local businesses I thought back to the time when I wrote a full tutorial on how to build a <a href="https://www.jiyuulife.net/click-to-deploy-wordpress-google-cloud/">self-hosted</a> WordPress site using your own <a href="https://www.jiyuulife.net/secure-wordpress-https/">secure</a> <a href="https://www.jiyuulife.net/registering-google-domains-to-google-cloud-wordpress/">domain</a>. However, upon my disappointment I found that my website was no longer operational and I had not taken the time to make a backup image of my VM before GCP pulled the plug.</p>
<p>When all seemed lost, yesterday I looked back on my Google Drive folders and noticed an <a href="https://updraftplus.com/">UpdraftPlus</a> directory inconspicuously sitting there, and it suddenly clicked to me that I actually installed and setup a WordPress backup add-on which saved all my posts, media, and WordPress admin settings. My entire site was saved!! All it took was three hours of my time to spin up a GCP instance with WordPress already deployed, access the admin console, re-install UpdraftPlus, and feed in the backup files in order to restore all the posts and settings I made two years prior. It was a excruciatingly painless task, and I have the developers at UpdraftPlus to thank for creating such a great FREE plugin which saved me several weeks of tinkering and fiddling with GCP + WordPress settings and writing articles.</p>
<p>For those who are reading this and are WordPress site owners, I strongly urge you to give <a href="https://updraftplus.com/">UpdraftPlus</a> a chance. While this site is still in its infancy and modest at best, I do plan to monetarily support UpdraftPlus in the future if this site takes off in viewer count or in the event that I will be building sites for local businesses. </p>
<p> </p>


<p></p>The post <a href="https://www.jiyuulife.net/jiyuulife-lives/">JiyuuLife is Live Again!</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">283</post-id>	</item>
		<item>
		<title>Introduction to JiyuuLife</title>
		<link>https://www.jiyuulife.net/intro-jiyuulife/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 28 Jun 2018 09:44:24 +0000</pubDate>
				<category><![CDATA[Site]]></category>
		<category><![CDATA[about]]></category>
		<category><![CDATA[intro]]></category>
		<category><![CDATA[JiyuuLife]]></category>
		<category><![CDATA[Ziyou Media]]></category>
		<category><![CDATA[自己紹介]]></category>
		<category><![CDATA[自由生活]]></category>
		<guid isPermaLink="false">https://www.jiyuulife.net/?p=48</guid>

					<description><![CDATA[<p>Greetings! If you&#8217;re seeing this post then you must have been referred to here by me personally, clicked on a link from my social accounts, or got really lucky and came here from organic search engine results (just kidding, you are a good samaritan and it had nothing to do with luck, but it might ... <a title="Introduction to JiyuuLife" class="read-more" href="https://www.jiyuulife.net/intro-jiyuulife/" aria-label="Read more about Introduction to JiyuuLife">Read more</a></p>
The post <a href="https://www.jiyuulife.net/intro-jiyuulife/">Introduction to JiyuuLife</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></description>
										<content:encoded><![CDATA[<h3>Greetings!</h3>
<p>If you&#8217;re seeing this post then you must have been referred to here by me personally, clicked on a link from my social accounts, or got really lucky and came here from organic search engine results (just kidding, you are a good samaritan and it had nothing to do with luck, but it might have some to do with my SEO skills 🙂 ).</p>
<p>This post is an introduction to this site and outlines some of the goals and motivations of this site. <span id="more-48"></span>Personally, this post serves as a guideline for me so that I don&#8217;t stray from the original plan for this blog. You can read my profile in a separate <a href="https://www.jiyuulife.net/index.php/about/">About</a> page, though I will likely go into small tangents about my personal life in the posts I will write. If you went and came back from that page you would notice that I am, in fact, a Taiwanese who grew up in the States and now work in Tokyo. While I can speak, read, and write in three languages, English is my strongest point (and, consequently, a strong selling point as a talent here in Japan), and thus posts in this blog will be largely written in English. While there may be times in which I will post in Japanese or Mandarin Chinese, my grasp of these two languages are not strong enough to produce a prose in which readers will find interesting &#8211; and to be honest, I wasn&#8217;t necessarily the top of my class in the English department, neither, so I hope to become more poetic at English first before engaging in others.</p>
<p>At the time of this post, I live in a somewhat small city in Tokyo called Jiyuugaoka (自由が丘) of the Meguro ward district. It is a place relatively known for youngsters and lavish dessert shops, but is also an important place for train transfers along the Toyoko and Oimachi lines. While not cheap, it is a very convenient area to live in and therefore many expats choose to live in or around this area. The name of this blog, &#8220;JiyuuLife,&#8221; bears semblance to the area I call home now. &#8220;Jiyuu,&#8221; or &#8220;自由&#8221; in Japanese and Mandarin Chinese, translates to &#8220;freedom,&#8221; which to me symbolizes the beginning of my journey to financial and spiritual freedom &#8211; roughly a month before the inception of this site I had quit my previous job as a technical solutions consultant in the finance industry to move back to the internet services industry which I currently work in now. Since this company also has housing assistance, I also opted in to move to a bigger and more vibrant area. But while I only moved two stations south (I have been to Jiyuugaoka many times before in my life) the day I decided on the apartment I will move into I was overcome with a sense of liberation and the determination that I will better myself, for myself, by finally breaking free of the financial and mental chains holding me back from being my best. To me, this blog serves as both a tracker &#8211; so that I not deviate from my path to personal greatness &#8211; but also a memento of such journey, so that in the years or decades to come I can come back to this public diary and reminisce about the wonderful memories I made.</p>
<hr />
<h6 style="text-align: center;"><img data-recalc-dims="1" loading="lazy" decoding="async" class="aligncenter size-large wp-image-19" src="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/05/IMG_20180426_184758.jpg?resize=1024%2C768&#038;ssl=1" alt="Jiyuugaoka Station" width="1024" height="768" srcset="https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/05/IMG_20180426_184758.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/05/IMG_20180426_184758.jpg?resize=600%2C450&amp;ssl=1 600w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/05/IMG_20180426_184758.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/05/IMG_20180426_184758.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/www.jiyuulife.net/wp-content/uploads/2018/05/IMG_20180426_184758.jpg?w=2100&amp;ssl=1 2100w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />Night picture of rotary outside of Jiyuugaoka Station</h6>
<hr />
<p>Alright, now let&#8217;s get on with some administrative topics. Since I&#8217;m new to blogging, I will take this time to try out some formatting features. I promise, I&#8217;ll get better at deciding what to use for which situations in the future 🙂</p>
<h2>Motivation</h2>
<p>In addition to self-development and the vague goals I outlined above, the following are what I hope to explore and try out in this blog to gain a better understanding of how it works and become more professional at:</p>
<p><strong>Advertising</strong> &#8211; Advertisement and marketing are major topics in the world today and it is said that no businesses can get by without some form of marketing. While I do apologize for displaying advertisements in this site, it is a necessary evil as I am hosting, publishing, and maintaining everything by myself. The main costs for maintaining this blog are the hosting fees (variable depending on site traffic) and well as domain hosting fees, and though it doesn&#8217;t amount to much in a year-on-year basis, I do hope to generate enough royalty for this site to be self-sustainable. In this way I can continue to provide more DIY and how-to guides for everyone to follow along in the future.</p>
<p><strong>Web Design</strong> &#8211; I&#8217;ve never been great at web design as I&#8217;ve always handled the backend in all the salaried positions I engaged in. Fortunately, self-hosting WP comes with many unique templates for me to use as a base, and adding small things on top of it is much simpler than starting from scratch. Expect this blog to become more and more lifelike as time goes by, and I hope it becomes beautiful enough that other sources will refer to this place as an example of a great blog.</p>
<p><strong>System Administration</strong> &#8211; Load balancing, seamlessly adding/subtracting virtual machines, error logging and monitoring&#8230; the list goes on. There are many ways to approach it and is utterly overwhelming as a result. While there are many tools which can be leveraged to assist in backend management, the orchestration and decisions ultimately come down to human intelligence. While not necessary now, it will be a delightful burden for me to have the opportunity to incorporate many of these concepts in the future.</p>
<p><strong>Linguistics</strong> &#8211; As stated above, I&#8217;m not the best at expressing myself in any language. I hope to fix that.</p>
<p><strong>Exploring New Concepts</strong> &#8211; This place serves as a log of sorts for me to remember what I have tried &#8211; what worked and what didn&#8217;t, how I could improve next time, et cetera. As engineers we tend to have do things in a methodical and scientific manner, and keeping track of our processes is a time-consuming but necessary part of organizing our achievements.</p>
<hr />
<p>Below is a bullet point list, just because 🙂</p>
<h2><strong>Posts will be mainly centered around:<br />
</strong></h2>
<ul>
<li>Data aggregation</li>
<li>DIY</li>
<li>Shop/Item Reviews</li>
<li>Other Know-Hows</li>
</ul>
<hr />
<p>&nbsp;</p>
<p>Aaaand, that&#8217;s it! I assume if you made it this far then you must either be very bored or very infatuated with me. Regardless of which, while this blog is not specific nor niche in content, I hope that every viewer will be able to take something away from here and use for their own self-betterment. It is an exciting time for me to start my own blogging &#8220;service,&#8221; and I do hope I have the strength and persistence to nurture this site for the years and decades to come. Thank you, and thank you in advance for your continuing support.</p>The post <a href="https://www.jiyuulife.net/intro-jiyuulife/">Introduction to JiyuuLife</a> first appeared on <a href="https://www.jiyuulife.net">JiyuuLife | Automate Your Way to Freedom</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">48</post-id>	</item>
	</channel>
</rss>
