<?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>Contents &#8211; xyze.co.uk</title>
	<atom:link href="https://www.xyze.co.uk/category/contents/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.xyze.co.uk</link>
	<description>Sysadmin stuff</description>
	<lastBuildDate>Sat, 07 Mar 2026 14:05:51 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Upgrading to Windows 11</title>
		<link>https://www.xyze.co.uk/upgrading-to-windows-11/</link>
					<comments>https://www.xyze.co.uk/upgrading-to-windows-11/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 15 Jan 2026 16:29:16 +0000</pubDate>
				<category><![CDATA[Contents]]></category>
		<guid isPermaLink="false">https://www.xyze.co.uk/?p=149</guid>

					<description><![CDATA[Updates to Windows 10 ceased late last year and I&#8217;ve been planning to upgrade to Windows 11 for a while. I mainly use Ubuntu on my machines but I like to keep my Windows skills up to date. Upgrading my virtual copy of Windows 10 on Proxmox was quite easy, but the Bitlocker install of ... <a title="Upgrading to Windows 11" class="read-more" href="https://www.xyze.co.uk/upgrading-to-windows-11/" aria-label="Read more about Upgrading to Windows 11">Read more</a>]]></description>
										<content:encoded><![CDATA[<p>Updates to Windows 10 ceased late last year and I&#8217;ve been planning to upgrade to Windows 11 for a while. I mainly use Ubuntu on my machines but I like to keep my Windows skills up to date. Upgrading my virtual copy of Windows 10 on Proxmox was quite easy, but the Bitlocker install of Windows 10 on my laptop failed to upgrade and then subsequently wouldn&#8217;t boot up either. I was worried about losing my activation key to Windows as there isn&#8217;t a sticker on my laptop as there used to be, but because I hadn&#8217;t linked the Windows install to a Microsoft account my Bitlocker key wasn&#8217;t saved and I had no choice but to install it again.</p>
<p>Windows 11 install kept failing at 77% despite Secure Boot and UEFI being enabled. I decided to try and install Windows 10 again but this also failed. Searching Google brought up a Reddit post which said that Windows installations couldn&#8217;t cope with another hard drive being present as when doing its many reboots it wouldn&#8217;t be able to tell which hard disk to boot from! It recommended disabling the SATA interface in the BIOS. I wanted to install it to the SATA drive, so disabled the NVMe interface instead. This time Windows 11 installed without hiccup despite taking 3 hours to install and do the updates, this compares with about 20 minutes for an Ubuntu install (including updates) on the same hardware. Why it needs to reboot several times is a mystery particularly when Ubuntu doesn&#8217;t need to reboot at all apart from into the newly installed system at the end of its installation.</p>
<p>I used a usb stick on which I&#8217;d installed an open source loader called Ventoy. It had its own UEFI key which needed to be installed into the BIOS where I discovered that the Windows license key was installed. Ventoy seems to have binary blobs in its source code tree on github but everyone seems to be using it, and it works very well.</p>
<p>Windows installed a new copy of the EFI partition so I had to copy its contents onto my original EFI partition on the NVMe drive and on rebooting it, loaded the normal Grub menu again. Unfortunately my wifi was no longer working in Ubuntu and another Google search revealed that the Windows 11 quick boot enabled the suspension of the wifi which is why Ubuntu no longer detected it. Disabling the quick boot in the power settings of the control panel in Windows 11 fixed it.</p>
<p>Another Google search revealed that the local account settings have been well hidden and Microsoft wants you to link it to an online login, but choosing to set it up for a college or workplace and choosing to add the install to a domain allows you to create a local account.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/upgrading-to-windows-11/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Snippets</title>
		<link>https://www.xyze.co.uk/snippets/</link>
					<comments>https://www.xyze.co.uk/snippets/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sat, 10 Jan 2026 14:08:27 +0000</pubDate>
				<category><![CDATA[Contents]]></category>
		<guid isPermaLink="false">https://www.xyze.co.uk/?p=147</guid>

					<description><![CDATA[Find excluding a path: sudo find / -not -path "/home/*" -size +10M Find files containing text in a particular path: grep -rnw '/path/to/somewhere/' -e 'pattern' sudo grep -rnw /etc -e james]]></description>
										<content:encoded><![CDATA[<p>Find excluding a path:</p>
<pre>sudo find / -not -path "/home/*" -size +10M</pre>
<p>Find files containing text in a particular path:</p>
<pre>grep -rnw '/path/to/somewhere/' -e 'pattern'
sudo grep -rnw /etc -e james</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/snippets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fuse using JuiceFS</title>
		<link>https://www.xyze.co.uk/fuse-using-juicefs/</link>
					<comments>https://www.xyze.co.uk/fuse-using-juicefs/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 26 May 2025 17:12:17 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[juicefs]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[s3fs]]></category>
		<guid isPermaLink="false">https://www.xyze.co.uk/?p=125</guid>

					<description><![CDATA[I set up website hosting for a friend &#8211; this time using nginx. This was set up in a similar fashion to Caddy except I installed nginx instead of Caddy. The challenge was to get it shoehorned into one of Google Cloud Engine&#8217;s e2-micros. Most of the site was static so could be served from ... <a title="Fuse using JuiceFS" class="read-more" href="https://www.xyze.co.uk/fuse-using-juicefs/" aria-label="Read more about Fuse using JuiceFS">Read more</a>]]></description>
										<content:encoded><![CDATA[<p>I set up website hosting for a friend &#8211; this time using nginx. This was set up in a similar fashion to Caddy except I installed nginx instead of Caddy.</p>
<p>The challenge was to get it shoehorned into one of Google Cloud Engine&#8217;s e2-micros. Most of the site was static so could be served from Cloudflare, but there were too many images so I decided to offload them onto an AWS bucket and mount using s3fs fuse. Unfortunately s3fs is very slow and searching for alternatives I happened upon JuiceFS.</p>
<p>In common with a lot of open source projects they offer a community edition which can be used for free and is extensively documented here: https://juicefs.com/docs/community/introduction/</p>
<p>Installation is detailed here: https://juicefs.com/docs/community/getting-started/installation and I installed via their PPA:</p>
<pre>sudo apt install software-properties-common
sudo add-apt-repository ppa:juicefs/ppa
sudo apt install juicefs
sudo ln -s /usr/bin/juicefs /usr/local/bin/
</pre>
<p>I then formatted my aws s3 storage using: https://juicefs.com/docs/community/getting-started/standalone#hands-on-practice-2</p>
<pre># Replace relevant options with the actual object storage being used
juicefs format --storage s3 \
    --bucket https://myjfs.s3.us-west-1.amazonaws.com \
    --access-key ABCDEFGHIJKLMNopqXYZ \
    --secret-key ZYXwvutsrqpoNMLkJiHgfeDCBA \
    sqlite3://myjfs.db myjfs
</pre>
<p>Unfortunately sqlite kept crashing so I installed redis for the metadata storage. Fortunately you can reconfigure your metadata storage without having to reformat s3: https://juicefs.com/docs/community/metadata_dump_load#recovery-and-migration</p>
<pre>
apt install redis-server
juicefs dump sqlite3://myjfs.db meta-dump
juicefs load redis://127.0.0.1:6379 meta-dump
juicefs config --storage s3 --bucket https://myjfs.s3.us-west-1.amazonaws.com --access-key ABCDEFGHIJKLMNopqXYZ --secret-key ZYXwvutsrqpoNMLkJiHgfeDCBA redis://127.0.0.1:6379
</pre>
<p>It can generate an fstab entry which is nice:</p>
<pre>juicefs mount --update-fstab --cache-size 2048 --cache-partial-only redis://127.0.0.1:6379 /var/www/html/wordpress/wp-content/uploads/
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/fuse-using-juicefs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Caddy</title>
		<link>https://www.xyze.co.uk/caddy/</link>
					<comments>https://www.xyze.co.uk/caddy/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sat, 24 May 2025 13:11:23 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[caddy]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.xyze.co.uk/?p=93</guid>

					<description><![CDATA[I&#8217;d wanted to try Caddy web server for a while and upgrading to the latest version of WordPress on my website broke the site. Something to do with their WP Super Cache but I couldn&#8217;t find anything via Google nor was opening a support ticket useful so I decided to replace it with a new ... <a title="Caddy" class="read-more" href="https://www.xyze.co.uk/caddy/" aria-label="Read more about Caddy">Read more</a>]]></description>
										<content:encoded><![CDATA[<p>I&#8217;d wanted to try Caddy web server for a while and upgrading to the latest version of WordPress on my website broke the site. Something to do with their WP Super Cache but I couldn&#8217;t find anything via Google nor was opening a support ticket useful so I decided to replace it with a new server.</p>
<p>As its a low traffic site I can do it on one of Google&#8217;s smallest servers, again using an e2-micro configured with Ubuntu 24.04 Minimal.</p>
<p>Caddy installation is detailed here: https://caddyserver.com/docs/install#debian-ubuntu-raspbian</p>
<pre>sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
</pre>
<p>I then installed the stuff that I need that&#8217;s missing from Ubuntu Minimal:</p>
<pre>sudo apt install bash-completion nano htop cron</pre>
<p>I always change the history size in the shell so it keeps more, changing HISTSIZE=100000<br />
HISTFILESIZE=20000:</p>
<pre>nano .bashrc</pre>
<p>With only 1GB ram, I always install zswap:</p>
<pre>sudo nano /etc/default/grub.d/50-cloudimg-settings.cfg
GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0,115200 zswap.enabled=1 zswap.shrinker_enabled=1 zswap.compressor=zstd zswap.zpool=zsmalloc"
sudo update-grub

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo nano /etc/fstab
/swapfile swap swap defaults 0 0

sudo crontab -e
@reboot echo zstd &gt; /sys/module/zswap/parameters/compressor
</pre>
<p>If using btrfs then this has to be used as it needs to be created without copy-on-write:<br />
sudo btrfs filesystem mkswapfile &#8211;size 1G /swapfile</p>
<p>Use swapon or reboot to activate. For some reason the zswap compressor isn&#8217;t enabled at boot time, so the kludge in a crontab activates it.<br />
It can be checked with:</p>
<pre>grep -R . /sys/module/zswap/parameters</pre>
<p>I normally configure swappiness which prevents kswapd kicking in and slowing everything down:</p>
<pre>sudo nano /etc/sysctl.conf
vm.swappiness = 1</pre>
<p>I got the latest WordPress and installed it in the usual place:</p>
<pre>wget https://wordpress.org/latest.tar.gz
tar zxvf latest.tar.gz
sudo mkdir -p /var/www/html
sudo mv wordpress/ /var/www/html/
sudo chown -R www-data: /var/www/html/wordpress/
</pre>
<p>I then installed mysql and php:</p>
<pre>sudo apt install mariadb-server php-apcu php-fpm php-mysql php-curl php-xml php-imagick php-mbstring php-zip php-gd php-intl
</pre>
<p>I then configured mysql:</p>
<pre>sudo mysql_secure_installation
sudo mysql

CREATE USER "USER"@"localhost" IDENTIFIED BY "PASSWORD";
CREATE DATABASE xyze;
GRANT ALL PRIVILEGES ON xyze.* TO "USER"@"localhost";
FLUSH PRIVILEGES;
</pre>
<p>This says that character set and collation are defaults so no need to specify explicitly: https://dev.mysql.com/doc/refman/8.0/en/charset-server.html</p>
<p>Caddy comes with a sample config: /etc/caddy/Caddyfile which will display a sample webpage when tested in the browser. Searching Google for a config brought up: https://caddy.community/t/setting-up-wordpress-with-caddy-on-ubuntu/18448 which I&#8217;ve altered slightly:</p>
<pre>xyze.co.uk {
	redir https://www.xyze.co.uk
}

www.xyze.co.uk {
    # good practice to signal on behalf of who 
    # are the certs getting issue
	tls james@xyze.co.uk

    # logs are optional
	log {
		output file /var/log/caddy/xyze.co.uk
		format console
	}

	root * /var/www/html/wordpress
	encode zstd gzip
	file_server
	php_fastcgi unix//run/php/php-fpm.sock

	@disallowed {
		path /xmlrpc.php
		path *.sql
		path /wp-content/uploads/*.php
	}

	rewrite @disallowed '/index.php'
}
</pre>
<p>Letsencrypt is configured by Caddy automatically so no Certbot configuration is necessary. I then set up WordPress via the browser using the mysql config from earlier.</p>
<p>I then dumped the previous db and loaded it into the new one:</p>
<pre>mysqldump -uUSER -pPASSWORD xyze &gt; /var/www/html/wordpress/sql/wp-backup.sql
mysql -uUSER -pPASSWORD xyze &lt; /var/www/html/wordpress/sql/wp-backup.sql
</pre>
<p>Logging into WordPress needed a db update and from there I configured the caching.<br />
I&#8217;ve found that apcu is faster than Redis so have installed this one which needs the php-apcu I installed earlier:<br />
https://wordpress.org/plugins/atec-cache-apcu/ This plugin gives opcache recommended settings: https://wordpress.org/plugins/atec-cache-info/ which are configured in:</p>
<pre>sudo nano /etc/php/8.3/fpm/php.ini
sudo systemctl restart php8.3-fpm caddy</pre>
<p>Unfortunately their page cache seems buggy and they&#8217;ve superseded it in one of their other plugins, so I&#8217;m using https://wordpress.org/plugins/powered-cache/ which I&#8217;ve used successfully before. The other plugin needed is the Cloudflare one which will update Cloudflare when a new post is made: https://wordpress.org/plugins/cloudflare/</p>
<p>I like to backup the db every night to make it ready for the external rsync backup:</p>
<pre>sudo crontab -l

# m h  dom mon dow   command
@reboot echo zstd &gt; /sys/module/zswap/parameters/compressor
35 0 * * * /usr/bin/mysqldump -uUSER -pPASSWORD xyze &gt; /var/www/html/wordpress/sql/wp-backup.sql
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/caddy/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ansible playbooks</title>
		<link>https://www.xyze.co.uk/ansible-playbooks/</link>
					<comments>https://www.xyze.co.uk/ansible-playbooks/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sat, 18 Feb 2023 15:27:20 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[ansible]]></category>
		<category><![CDATA[apt]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[patching]]></category>
		<category><![CDATA[playbook]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">https://xyze.co.uk/?p=76</guid>

					<description><![CDATA[I’ve been messing around with Ansible for some time now and have created simple playbooks to patch our servers. I use pip to install the latest Ansible: sudo apt install python3-pip python3-venv python3 -m venv env source env/bin/activate pip3 install ansible The first thing I created was a hosts.ini file: cat hosts.ini [xyze] backup.xyze ansible_ssh_extra_args="-Jxyze@bastion.xyze" ... <a title="Ansible playbooks" class="read-more" href="https://www.xyze.co.uk/ansible-playbooks/" aria-label="Read more about Ansible playbooks">Read more</a>]]></description>
										<content:encoded><![CDATA[<p>I’ve been messing around with Ansible for some time now and have created simple playbooks to patch our servers. I use pip to install the latest Ansible:</p>
<pre>sudo apt install python3-pip python3-venv
python3 -m venv env
source env/bin/activate
pip3 install ansible
</pre>
<p>The first thing I created was a hosts.ini file:</p>
<pre>cat hosts.ini

[xyze]
backup.xyze       ansible_ssh_extra_args="-Jxyze@bastion.xyze"
git.xyze          ansible_ssh_extra_args="-Jxyze@bastion.xyze"
icinga.xyze       ansible_ssh_extra_args="-Jxyze@bastion.xyze"
tickets.xyze      ansible_ssh_extra_args="-Jxyze@bastion.xyze"
bastion.xyze

[client1]
website.client1

[client2]
website.client2
.
.
.
</pre>
<p>Our DNS is on AWS’s Route 53 and I’ve created private zones for each of our clients and us, so when we’re logged into our VPN the addresses above can be resolved. Our machines can only be accessed via an intermediate bastion host so the jump host is included in the hosts file.</p>
<p>Then I created some apt playbooks:</p>
<pre>cat apt-safe-upgrade.yml 
---
- hosts: xyze, client1, client2
  remote_user: xyze
  become: true
  become_method: sudo
  gather_facts: false

  tasks:
    - name: apt-get dist-upgrade
      apt:
        update_cache: true
        upgrade: safe
</pre>
<pre>cat apt-reboot.yml 
---
- hosts: xyze, client1, client2
  remote_user: xyze
  become: yes
  become_method: sudo
  gather_facts: no

  tasks:
  - name: Check if a reboot is required
    register: reboot_required_file
    stat: path=/var/run/reboot-required get_md5=no

  - name: Reboot box if kernel/libs updated and requested by the system
    shell: sleep 10 &amp;&amp; /sbin/shutdown -r now 'Rebooting box to update system libs/kernel as needed'
    args:
        removes: /var/run/reboot-required
    async: 300
    poll: 0
    ignore_errors: true
    when: reboot_required_file.stat.exists == true
</pre>
<pre>cat apt-autoremove.yml 
---
- hosts: xyze, client1, client2
  remote_user: xyze
  become: true
  become_method: sudo
  gather_facts: false

  tasks:
    - name: apt autoremove
      apt:
        autoremove: true
</pre>
<p>Unfortunately some of my playbooks had errors which were found by the Ansible Lint tool. This can be installed via pip and installs yamllint which can be run first:</p>
<pre>pip3 install ansible-lint</pre>
<p>Playbooks are executed in the following manner:</p>
<pre>ansible-playbook -i hosts.ini -l xyze,client1,client2 apt-safe-upgrade.yml -f10</pre>
<p>Running ‘ansible-playbook’ on its own will give a list of all the options or passing ‘-h’ or’–help’ to it will display the same thing.</p>
<p>In our example above we are using hosts.ini as the inventory, and limiting the hosts it runs on to a subset. This can be a single host within the hosts.ini file or a group of hosts like xyze,client1 or it’ll run on all the hosts if you pass the limiting option ‘all’. Normally it’ll fork into 5 parallel processes but I’ve doubled that to 10 in this example.</p>
<p>A check or test run can be performed and this is useful for testing if a machine needs a reboot after patching. A machine or group of machines need rebooting if it shows ‘ok=2’:</p>
<pre>ansible-playbook --check -i hosts.ini -l xyze apt-reboot.yml</pre>
<p>To perform the actual reboots the playbook is run again without the ‘–check’.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/ansible-playbooks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPress, Lighttpd, and Cloudflare</title>
		<link>https://www.xyze.co.uk/wordpress-lighttpd-and-cloudflare/</link>
					<comments>https://www.xyze.co.uk/wordpress-lighttpd-and-cloudflare/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 03 Oct 2022 14:16:05 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[22.04]]></category>
		<category><![CDATA[certbot]]></category>
		<category><![CDATA[cloudflare]]></category>
		<category><![CDATA[letsencrypt]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[permalinks]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[rewrite]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://xyze.co.uk/?p=71</guid>

					<description><![CDATA[I’ve been meaning to try Lighttpd for ages as I wanted to downgrade my server to save money and it takes the least amount of memory compared with apache or nginx. Installed with the help of: https://www.how2shout.com/linux/install-wordpress-on-lighttpd-web-server-ubuntu/ https://www.howtoforge.com/how-to-install-lighttpd-with-php-and-mariadb-on-debian-10/ But had to make changes too. james@instance-1:~$ sudo mysql CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ... <a title="WordPress, Lighttpd, and Cloudflare" class="read-more" href="https://www.xyze.co.uk/wordpress-lighttpd-and-cloudflare/" aria-label="Read more about WordPress, Lighttpd, and Cloudflare">Read more</a>]]></description>
										<content:encoded><![CDATA[<div class="entry-content">
<p>I’ve been meaning to try Lighttpd for ages as I wanted to downgrade my server to save money and it takes the least amount of memory compared with apache or nginx.</p>
<p>Installed with the help of:<br />
<a href="https://web.archive.org/web/20240919030526/https://web.archive.org/web/20201102175615/https://www.how2shout.com/linux/install-wordpress-on-lighttpd-web-server-ubuntu/" rel="noopener">https://www.how2shout.com/linux/install-wordpress-on-lighttpd-web-server-ubuntu/</a><br />
<a href="https://web.archive.org/web/20240919030526/https://www.howtoforge.com/how-to-install-lighttpd-with-php-and-mariadb-on-debian-10/" rel="noopener">https://www.howtoforge.com/how-to-install-lighttpd-with-php-and-mariadb-on-debian-10/</a><br />
But had to make changes too.</p>
<pre>james@instance-1:~$ sudo mysql
CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
create user 'demoh2s'@'localhost' identified by 'password';
GRANT ALL PRIVILEGES ON `mydatabase`.* to `demoh2s`@localhost;
exit
</pre>
<pre>james@instance-1:~$ sudo apt install php php-cgi php-cli php-fpm php-curl php-gd php-mysql php-mbstring zip unzip php-zip php-xml php-intl php-imagick apache2-</pre>
<p>I’m installing on Ubuntu 22.04 Minimal <a href="https://web.archive.org/web/20240919030526/https://wiki.ubuntu.com/Minimal" rel="noopener">https://wiki.ubuntu.com/Minimal</a> on Google’s cloud platform. I try to keep original config files intact so have only altered the server.document-root and rewrite rules in lighttpd.conf</p>
<p>There is a tool similar to the one in apache to install the symlinks in /etc/lighttpd/conf-enabled</p>
<pre>james@instance-1:~$ sudo lighty-enable-mod fastcgi fastcgi-php auth deflate rewrite accesslog</pre>
<h4>Rewriting</h4>
<p>At first all the permalinks were showing ‘index.php’ which apache wasn’t doing before so I gathered together some rewriting rules from various places via Google. Through trial and error I ascertained that the order is significant, and I’ve included the rules I found but commented out. These still aren’t definitive but seem to be a work in progress and WordPress only seems to need the 4 uncommented ones at present. You can Google them to see where they came from:</p>
<pre>lighttpd "^/(wp-admin.+).*/?" =&gt; "$0"</pre>
<p>The Lighttpd wiki is very useful too: <a href="https://web.archive.org/web/20240919030526/https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs" rel="noopener">https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs</a></p>
<pre>james@instance-1:/etc/lighttpd$ cat lighttpd.conf
server.modules = (
	"mod_indexfile",
	"mod_access",
	"mod_alias",
 	"mod_redirect",
)

#url.rewrite = (
#"^/?$" =&gt; "/index.php",
# Exclude common directories
#"^/(wp-.+)$" =&gt; "$0",
# Exclude letsencrypt certbot
#"^/(.well-.+)$" =&gt; "$0",
#"^/xmlrpc.php" =&gt; "$0",
#"^/sitemap.xml" =&gt; "$0",
# Handle permalinks and feeds
#"^/(.+)/?$" =&gt; "/index.php/$1"
#)

url.rewrite-if-not-file = (
 "^/(wp-admin.+).*/?" =&gt; "$0",
# Exclude letsencrypt certbot
 "^/(.well-.+)$" =&gt; "$0",
# REST API for block editor &amp; Jetpack 
 "(?:\?(.*))?$" =&gt; "/index.php?$1",
# "(\/styles\/|\/images\/|\/scripts\/)" =&gt; "$0",
 "^/(wp-.+).*/?" =&gt; "$0",
# "^/images/.*/?" =&gt; "$0",
# "^/temp/.*/?" =&gt; "$0",
# "^/keyword/([A-Za-z_0-9\-]+)/?$" =&gt; "/index.php?keyword=$1",
# "^/.*?(\?.*)?$" =&gt; "/index.php$1"
)

server.document-root        = "/var/www/html/xyze.co.uk"
.
.
.

</pre>
<p>You need to set the permalinks in wp-admin as well under Settings, Permalinks:</p>
<pre>Custom Structure https://www.xyze.co.uk/index.php /%postname%/</pre>
<h4>WordPress (this is not needed if using Let’s Encrypt)</h4>
<p>The way I’ve installed WordPress before is to just use http and then use the ‘Flexible’ shared Cloudflare certificate that encrypts traffic from the user to Cloudflare but then its served to Cloudflare using http. This has worked fine with apache but both the classic editor and block editor weren’t working in Lighttpd and searching with the error from the block editor I stumbled across this:<br />
<a href="https://web.archive.org/web/20240919030526/https://wordpress.org/support/topic/publishing-failed-you-are-probably-offline/" rel="noopener">https://wordpress.org/support/topic/publishing-failed-you-are-probably-offline/</a></p>
<pre>james@instance-1:~$ cat /var/www/html/xyze.co.uk/wp-config.php

/* Add any custom values between this line and the "stop editing" line. */

define( 'WP_SITEURL', 'http://xyze.co.uk' );
define( 'WP_HOME', 'http://xyze.co.uk' );

/* That's all, stop editing! Happy publishing. */
</pre>
<p>This allowed me to use http if I wanted to add or edit a post and Cloudflare’s Flexible https worked too.</p>
<h4>Let’s Encrypt</h4>
<p>However now we have Let’s Encrypt with certbot, its better to have proper https.</p>
<pre>james@instance-1:~$ sudo apt install certbot
james@instance-1:~$ sudo certbot certonly --webroot -w /var/www/html/xyze.co.uk/ -d www.xyze.co.uk
</pre>
<p><a href="https://web.archive.org/web/20240919030526/https://eff-certbot.readthedocs.io/en/stable/using.html" rel="noopener">https://eff-certbot.readthedocs.io/en/stable/using.html</a><br />
Says that “For historical reasons, the containing directories are created with permissions of 0700 meaning that certificates are accessible only to servers that run as the root user. If you will never downgrade to an older version of Certbot, then you can safely fix this using chmod 0755 /etc/letsencrypt/{live,archive}”<br />
Which I did.</p>
<p>This time I copied /etc/lighttpd/conf-available/10-ssl.conf to 10-ssl-xyze.conf and then created the symlink manually.</p>
<pre>james@instance-1:/etc/lighttpd/conf-enabled$ sudo ln -s ../conf-available/10-ssl-xyze.conf
james@instance-1:/etc/lighttpd/conf-enabled$ cat 10-ssl-xyze.conf
# /usr/share/doc/lighttpd/ssl.txt
# -*- conflicts: mbedtls, gnutls, nss, wolfssl -*-

server.modules += ( "mod_openssl" )

# ssl.* in global scope gets inherited by
#   $SERVER["socket"] == "..." { ssl.engine = "enable" }
#ssl.pemfile = "/etc/lighttpd/server.pem"
ssl.pemfile = "/etc/letsencrypt/live/www.xyze.co.uk/fullchain.pem" # Combined Certificate
ssl.privkey = "/etc/letsencrypt/live/www.xyze.co.uk/privkey.pem"

ssl.cipher-list = "HIGH"

$SERVER["socket"] == ":443" {
ssl.engine = "enable"
}

$HTTP["scheme"] == "http" {
$HTTP["host"] == "www.xyze.co.uk" { # HTTP URL
url.redirect = ("/.*" =&gt; "https://www.xyze.co.uk$0") # Redirection HTTPS URL
}
}

include_shell "/usr/share/lighttpd/use-ipv6.pl 443"
</pre>
<p>At first I copied the example from the howtoforge link above but lighttpd kept failing to restart producing an error like this: ssl.pemfile has to be set in same $SERVER[“socket”] scope as other ssl.* directives</p>
<p>Eventually I worked out that the pem files had to be in the global file or in all of the socket, scheme, and host directives, so I moved it out of the socket directive so they’re now global and inherited by all of them.</p>
<p>Finally I changed the wp-config.php to https – or you could comment them out as long as they’re set to https in Settings, General on the WordPress Dashboard. And Cloudflare can now use ‘Full’ encryption and ‘<span class="c_c">Always Use HTTPS’.</span></p>
<h4>Cloudflare</h4>
<p>I added some Firewall rules using the dash console:</p>
<pre>WordPress Spam Filter
(http.request.uri.path contains "wp-comments-post.php") or (http.request.uri.path contains "wp-login.php")
Managed Challenge

Protect the wp-admin Area
(http.request.uri.path contains "/wp-admin/" and not http.request.uri.path contains "/wp-admin/admin-ajax.php" and not http.request.uri.path contains "/wp-admin/theme-editor.php")
Managed Challenge

Block xmlrpc.php Attacks
(http.request.uri.path contains "/xmlrpc.php")
Block

Block wp-login
(http.request.uri.path contains "wp-login.php" and ip.geoip.country ne "GB")
Block
</pre>
<h4>Postscript</h4>
<p>I followed a guide to install Redis <a href="https://web.archive.org/web/20240919030526/https://www.section.io/engineering-education/how-to-set-up-and-configure-redis-caching-for-wordpress/" rel="noopener">here</a> except I installed the php client as it seemed to work faster. This uses a WordPress plugin from <a href="https://web.archive.org/web/20240919030526/https://en-gb.wordpress.org/plugins/redis-cache/" rel="noopener">here.</a> Php will need reloading but I rebooted as I’d also installed some kernel updates.</p>
<pre>james@instance-1:~$ sudo apt install php-redis</pre>
<p>I also installed a Cloudflare cache plugin from <a href="https://web.archive.org/web/20240919030526/https://wordpress.org/plugins/wp-cloudflare-page-cache/" rel="noopener">here</a> which needs your api key from Cloudflare and works really well. There is also the W3 Total Cache in place of the redis cache plugin.</p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/wordpress-lighttpd-and-cloudflare/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AWS CLI start instance</title>
		<link>https://www.xyze.co.uk/awscli-start-instance/</link>
					<comments>https://www.xyze.co.uk/awscli-start-instance/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 31 Aug 2022 17:22:39 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[awscli]]></category>
		<guid isPermaLink="false">https://xyze.co.uk/?p=62</guid>

					<description><![CDATA[I wanted to start an instance from my terminal rather than going onto the AWS console. Firstly choose the profile, then search for the instance: export AWS_PROFILE=xyze aws ec2 describe-instances --output table &#124; grep -B150 backup &#124; grep InstanceId –output table presents the output as a nice table rather than json. Grep searches for the ... <a title="AWS CLI start instance" class="read-more" href="https://www.xyze.co.uk/awscli-start-instance/" aria-label="Read more about AWS CLI start instance">Read more</a>]]></description>
										<content:encoded><![CDATA[<div class="entry-content">
<p>I wanted to start an instance from my terminal rather than going onto the AWS console. Firstly choose the profile, then search for the instance:</p>
<pre>export AWS_PROFILE=xyze
aws ec2 describe-instances --output table | grep -B150 backup | grep InstanceId
</pre>
<p>–output table presents the output as a nice table rather than json. Grep searches for the name I gave the instance, and B150 prints the lines before we get to the name. I’m grepping this to find the InstanceId so I can launch the machine.</p>
<p>Its a good idea to check you’ve got the right one:</p>
<pre>aws ec2 describe-instances --output table --instance-ids i-044c47167ba728a23
</pre>
<p>And then you can start it:</p>
<pre>aws ec2 start-instances --instance-ids i-044c47167ba728a23
</pre>
</div>
<footer class="entry-meta" aria-label="Entry meta"></footer>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/awscli-start-instance/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Daily Backups</title>
		<link>https://www.xyze.co.uk/daily-backups/</link>
					<comments>https://www.xyze.co.uk/daily-backups/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 01 Sep 2021 00:21:38 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[aws backup]]></category>
		<category><![CDATA[awscli]]></category>
		<category><![CDATA[boto3]]></category>
		<category><![CDATA[deep archive]]></category>
		<category><![CDATA[glacier]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[s3api]]></category>
		<category><![CDATA[venv]]></category>
		<guid isPermaLink="false">https://xyze.co.uk/?p=23</guid>

					<description><![CDATA[Amazon’s guide to AWS Backup is here: https://docs.aws.amazon.com/aws-backup/latest/devguide/whatisbackup.html Our Backup plan is called xyze-prod-backup and can be viewed by clicking on ‘Manage Backup plans’ from the AWS Backup dashboard. I’ve set up a backup rule called ‘DailyBackups’ which are kept for 7 days in EBS as most recent backups are likely to be the ones that ... <a title="Daily Backups" class="read-more" href="https://www.xyze.co.uk/daily-backups/" aria-label="Read more about Daily Backups">Read more</a>]]></description>
										<content:encoded><![CDATA[<div class="entry-content">
<p>Amazon’s guide to AWS Backup is here: <a href="https://web.archive.org/web/20240919030531/https://docs.aws.amazon.com/aws-backup/latest/devguide/whatisbackup.html" rel="noopener">https://docs.aws.amazon.com/aws-backup/latest/devguide/whatisbackup.html</a></p>
<p>Our Backup plan is called xyze-prod-backup and can be viewed by clicking on ‘Manage Backup plans’ from the AWS Backup dashboard.</p>
<p>I’ve set up a backup rule called ‘DailyBackups’ which are kept for 7 days in EBS as most recent backups are likely to be the ones that may be required to restore a server. I’ve written a boto3 script using their API to copy weekly backups to their ‘Deep Archive’ tape backups. Keeping the weekly backups on the Deep Archive for 12 months will save about $140 per month from our AWS bill and can be restored in less than 12 hours if needed. The bucket lifecycle rules are set to: keep for a year and then delete, and the backups will transition from standard to deep storage right away.</p>
<p>They’re based on snapshots which are also stored as AMI’s which allow for easy restores instead of messing with snapshots and volumes like before.</p>
<p>What to backup (aka Resource assignments) hasn’t changed and uses the ‘Daily’ tags. To add an instance to the backup plan all we do is tag an instance as ‘Daily’ under the Backup tag.</p>
<p>My boto3 script requires the latest python so the easiest thing to do is to run it in a virtual environment which can be set up as shown. In the end I had added it to Lambda running once a week which meant we didn’t have to run an additional backup server like before. Unfortunately Lambda only lets your function operate for 15 mins at a time which wasn’t enough for the whole script to run as I’d introduced a wait between each one as there was a maximum gigabytes of concurrent copying that you could use at a time. I may modify the script but for now I’ve created a new instance which, like the previous one, is called backup.cloud.xyze. The script runs once a week as a cronjob on the ubuntu user. Apparently lifecycle transitions are queued before midnight UTC so 10pm was chosen so standard storage will cost very little. This failed once so the time was put back to 7pm. I’ve set it to power down after the backup completes and sends an email. The minutes sleep in the crontab is because Postfix needs some time to send us the email. I’ve created a small Lambda function called boot-backup-instance and created a cronjob in EventBridge which starts backup.cloud.xyze at 6.45pm every Friday which should be enough time for it to initialise before the backup starts using the cronjob below:</p>
<pre># m h  dom mon dow   command
0 19 * * 5 cd /home/ubuntu/newscripts &amp;&amp; source env/bin/activate &amp;&amp; python3 ./copy-ami.py 2&gt;&amp;1 | /usr/bin/mailx -s "Weekly backup to glacier. Please keep in public-support-internal" support@xyze.co.uk &amp;&amp; /usr/bin/sleep 60 &amp;&amp; /usr/bin/sudo /usr/sbin/poweroff</pre>
<p>At first the script failed as ‘source’ is only in bash not dash so I had to reconfigure using ‘sudo dpkg-reconfigure dash’ (which is preferable to alternatives according to the internet) and then it failed again as the backup user needed the additional IAM permissions detailed here:<br />
<a href="https://web.archive.org/web/20240919030531/https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html" target="_blank" rel="noopener noreferrer">https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebsapi-permissions.html</a><br />
I was using my permissions originally and Lambda was internal so that’s why its different. The backup user has EC2 &amp; S3 full access too.</p>
<pre>sudo apt-get install python3-venv
python3 -m venv env
source env/bin/activate
pip3 install boto3
export AWS_PROFILE=xyze
</pre>
<p>To run the copy-ami.py script below we need to export our AWS credentials.</p>
<pre>#!/usr/bin/env python
#James Holland September 2021

import boto3
import datetime
import json

#Uncomment for Lambda
#def lambda_handler(event, context):

# A counter was added for readability when cron sends email
count = 0
s3 = boto3.client('s3')
client = boto3.client('ec2')

#Get yesterdays date as today's backups might not have been done yet
date_filter = (datetime.datetime.now() - datetime.timedelta(days=1))
#This is only needed if archiving legacy backups as was done initially and is always one less day than the above date
date_filter_minus = (datetime.datetime.now() - datetime.timedelta(days=0))

#Documented here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_images
response = client.describe_images(
Filters=[
       {
           'Name': 'tag:Backup',
           'Values': [
               'Daily',
           ]
       },
   ],
)

for ami in response['Images']:

   ami_creation_date_str = ami['CreationDate']
   ami_creation_date = datetime.datetime.strptime(ami_creation_date_str, "%Y-%m-%dT%H:%M:%S.%fZ")
   ami_image_id = eval(json.dumps(ami['ImageId']))
   ami_image_name = ami['Name']
   ami_image_id_bin = eval(json.dumps(ami['ImageId'])) + ".bin"
   name = [tag['Value'] for tag in ami['Tags'] if tag['Key'] == 'Name'][0]
   if datetime.datetime.timestamp(ami_creation_date) &gt; datetime.datetime.timestamp(date_filter) and datetime.datetime.timestamp(ami_creation_date) &lt; datetime.datetime.timestamp(date_filter_minus):
#Print the result to standard output to maybe send by email - but not implemented yet
       count = count + 1
       print(count, ami_image_id_bin, ami_creation_date, name)

#Documented here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.create_store_image_task
       copyami = client.create_store_image_task(
       ImageId=ami_image_id,
       Bucket='xyze-backups',
       S3ObjectTags=[
       {
               'Key': 'Name',
               'Value': name
           },
           {
               'Key': 'Backup-Date',
               'Value': ami_creation_date_str
           },
       ],
       DryRun=False
       )

#A waiter was added because doing them all at once exceeded the limit imposed by Amazon
#Now the bucket is polled every 30 seconds to see if the backup file is there before doing the next one
#I've included an hour's worth of checking because sometimes the copying pauses for minutes at a time
#Documented here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html?highlight=waiter#S3.Waiter.ObjectExists
       waiter = s3.get_waiter('object_exists')
       waiter.wait(
       Bucket='xyze-backups',
       WaiterConfig={
          'Delay': 30,
          'MaxAttempts': 120
       },
       Key=ami_image_id_bin
       )</pre>
<h2 id="Restore_from_backup"><span id="chapter_internalit_dailybackups_2" class="ecpHeading">Restore from backup</span></h2>
<p>Hopefully the backup you need will be from the last 7 days. All you need to do here is to go to the AMI images on the EC2 dashboard on the AWS console, sort for the date you want, choose the image and launch it as a new instance. You can check what the instance family is from the current instance.</p>
<p>Restoring from cold storage is a bit more involved particularly as this method is new and Amazon hasn’t developed it much yet. Lets say you want to restore a previous copy of our backup box. This xargs cludge will search through all the backups and grep the results to your terminal as shown:</p>
<pre>aws s3 ls s3://xyze-backups | awk '{print $4}' | xargs -n1 --verbose -I {} aws s3api get-object-tagging --bucket xyze-backups --key {} | grep -B5 backup.cloud.xyze

aws s3api get-object-tagging --bucket xyze-backups --key ami-00323c135ac547f5b.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-006955f1847ecac96.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-018110dd5440eeb60.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-01c721b7baa2f09d9.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-037206e2c482b8c07.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-0423091a04eed102e.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-054d2d2434c6acd87.bin
           "Key": "Backup-Date",
           "Value": "2021-09-01T07:07:54.000Z"
       },
       {
           "Key": "Name",
           "Value": "backup.cloud.xyze"
aws s3api get-object-tagging --bucket xyze-backups --key ami-05ce0d7981dfa3afb.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-0615d33a9898f5a41.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-06eed532a0d19e117.bin
aws s3api get-object-tagging --bucket xyze-backups --key ami-07f0a939f8d408d3f.bin</pre>
<p>Choose the date you’re after and the ami key is shown above the grepped date. In our example we then use the aws cli to restore the ami image. Again we’re utilising the s3api. I’ve set the days the restored object will expire to 3 days when I am next on shift. A restored object is charged at the standard rate so don’t set it any more than necessary. If you click on the object in the s3 dashboard you will see a ‘Restoration in progress’ dialog. The restoration is normally complete within 12 hours but in practice can be shorter. You can check on its progress using ‘s3api head-object’ as shown.</p>
<p>When its complete you can run the ‘create-restore-image-task’ and the object will soon appear in the AMI images on the EC2 dashboard and as before you can now launch a new instance from the backup.</p>
<pre>aws s3api restore-object --bucket xyze-backups --key ami-054d2d2434c6acd87.bin --restore-request '{"Days":3,"GlacierJobParameters":{"Tier":"Standard"}}'

aws s3api head-object --bucket xyze-backups --key ami-054d2d2434c6acd87.bin

aws ec2 create-restore-image-task --bucket xyze-backups --name ami-backup.cloud.xyze --object-key ami-054d2d2434c6acd87.bin</pre>
</div>
<footer class="entry-meta" aria-label="Entry meta"></footer>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/daily-backups/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AWS CLI archive ami</title>
		<link>https://www.xyze.co.uk/aws-cli-archive-ami/</link>
					<comments>https://www.xyze.co.uk/aws-cli-archive-ami/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 15 Apr 2020 14:25:26 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[awscli]]></category>
		<guid isPermaLink="false">https://xyze.co.uk/?p=73</guid>

					<description><![CDATA[I use Amazon’s Daily Backup service which creates Amazon Machine Images from snapshots which I keep for a year in S3 Deep Archive and then automatically delete using a Lifecycle Rule (Daily backups.) However I’ve upgraded the Git server and I want to keep a copy of the old one in a bucket of old ... <a title="AWS CLI archive ami" class="read-more" href="https://www.xyze.co.uk/aws-cli-archive-ami/" aria-label="Read more about AWS CLI archive ami">Read more</a>]]></description>
										<content:encoded><![CDATA[<div class="entry-content">
<p>I use Amazon’s Daily Backup service which creates Amazon Machine Images from snapshots which I keep for a year in S3 Deep Archive and then automatically delete using a Lifecycle Rule (<a href="https://web.archive.org/web/20240919030524/https://www.xyze.co.uk/daily-backups/">Daily backups</a>.) However I’ve upgraded the Git server and I want to keep a copy of the old one in a bucket of old instances. I want to try using the cli again rather than the AWS console. Firstly choose the profile, then search for the ami:</p>
<pre>export AWS_PROFILE=xyze
aws ec2 describe-images --owners 000000000000 --output table | grep -B50 git | grep ImageId</pre>
<p>This uses an option ‘owners’ which is your AWS account. Help with the command can be viewed using the help:</p>
<pre>aws ec2 describe-images help</pre>
<p>As previously (<a href="https://web.archive.org/web/20240919030524/https://www.xyze.co.uk/awscli-start-instance/">AWS CLI start instance</a>) its useful to check we’ve got the right one:</p>
<pre>aws ec2 describe-images --output table --image-ids ami-0905c88505b225019</pre>
<p>This command stores the image in s3:</p>
<pre>aws ec2 create-store-image-task --s3-object-tags Key=Name,Value=old-git --image-id ami-0905c88505b225019 --bucket old-instances</pre>
<p>And this renames the file and moves it into Glacier Deep Archive:</p>
<pre>aws s3 mv s3://old-instances/ami-0905c88505b225019.bin s3://old-instances/old-git.bin --storage-class DEEP_ARCHIVE</pre>
</div>
<footer class="entry-meta" aria-label="Entry meta"></footer>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/aws-cli-archive-ami/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Install AWS CLI</title>
		<link>https://www.xyze.co.uk/install-awscli/</link>
					<comments>https://www.xyze.co.uk/install-awscli/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 15 Apr 2020 00:24:12 +0000</pubDate>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[awscli]]></category>
		<category><![CDATA[pip]]></category>
		<guid isPermaLink="false">https://xyze.co.uk/?p=33</guid>

					<description><![CDATA[I’m using pip to install the latest awscli as the version in apt won’t work for the new ‘Deep Archive’ however awscli v2 is now available and should be used instead of the old one: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html pip3 install awscli Now we need to configure the cli by installing authentication from AWS. Log into the AWS account ... <a title="Install AWS CLI" class="read-more" href="https://www.xyze.co.uk/install-awscli/" aria-label="Read more about Install AWS CLI">Read more</a>]]></description>
										<content:encoded><![CDATA[<div class="entry-content">
<p>I’m using pip to install the latest awscli as the version in apt won’t work for the new ‘Deep Archive’ however awscli v2 is now available and should be used instead of the old one: <a href="https://web.archive.org/web/20240919030528/https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html" rel="noopener">https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html</a></p>
<pre>pip3 install awscli</pre>
<p>Now we need to configure the cli by installing authentication from AWS. Log into the AWS account and go to IAM. Click on Users, then your name, and then Create access key as shown below. Save the file as you won’t be able to get it again and will have to create a new one.</p>
<p><img fetchpriority="high" decoding="async" class="alignnone wp-image-42 size-large" src="https://web.archive.org/web/20240919030528im_/https://i0.wp.com/xyze.co.uk/wp-content/uploads/2020/04/Screenshot_at_2019-10-09_02-23-36-1024x495.png?resize=900%2C435&amp;ssl=1" alt="" width="900" height="435" data-recalc-dims="1" /></p>
<p>Now add the keys using the default region: eu-west-1</p>
<pre>aws configure --profile xyze</pre>
<p>To use the xyze profile for the whole of your current terminal session:</p>
<pre>export AWS_PROFILE=xyze</pre>
</div>
<footer class="entry-meta" aria-label="Entry meta"></footer>
]]></content:encoded>
					
					<wfw:commentRss>https://www.xyze.co.uk/install-awscli/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
