Glen Mazza's Weblog

https://glenmazza.net/blog/date/20231208 Friday December 08, 2023

Deploying TightBlog on Linode

I've updated the software running this blog to a new version of TightBlog, running on a standalone Tomcat on Ubuntu running on Linode. It's still a SNAPSHOT version with some things to fix. Below are my installation notes. Note many of these instructions hold for deploying any WAR-file in such an environment, so what I've written below may be useful for other apps.

Linode preparation:

  1. Sign up for Linode. Best to first check for special starting credits, usually given at the top of their documentation. I used the $12/month plan providing 2 GB of RAM which has always worked fine for my needs.
  2. For the starting image for my new Linode, I used Ubuntu 22.04 LTS with its default partition of 50688 MB and 512 MB for swap space.
  3. I followed the remainder of the Getting Started Guide and most of the recommendations of the subsequent Securing Your Server guide.
  4. If you don't want the default Linode domain name of lixxxx-yy.members.linode.com (as you probably don't) go to a domain name registrar such as Namecheap or Squarespace to rent your desired domain. I used the latter to obtain glenmazza.net and then configured it for my linode following these instructions.
  5. As recommended in the Securing Your Server guide, I used key-based authentication allowing me to easily connect to my linode using "ssh (or sftp) glenmazza.net" from a command-line on my home computer. (If you haven't gotten a custom domain name yet, you'll find the default name and IP address in the Public IPs section on the Remote Access tab in the Linode Manager.)
  6. I created a ~/tbfiles folder (owned by a non-root normal user account) as a staging area for files I'm uploading to my linode as well as to hold the TightBlog media file directories and (optionally) Lucene search indexes.

Tomcat preparation:

  1. I installed OpenJDK 17 and then manually Tomcat on my image, using a non-root account. Another option, which I had problems getting to work before switching to the above (probably due to since-learned firewall configuration omissions on my part), is using sudo apt-get install, which if you use requires some extra configuration for it to work with JDK 17.

    Either Tomcat install method above should result in sudo systemctl [start|stop|restart] tomcat (or ...tomcat9) command-line instructions being available for starting and stopping Tomcat. After starting Tomcat, confirm you can access Tomcat's port 8080 from a browser using your linode's IP address.

  2. Create a signed SSL certificate for use with Tomcat. I used Certbot which generates 3-month certificates, and these instructions for placing the key Let's Encrypt generates in a Java keystore that can be read by Tomcat. (The cited Certbot article shows how .pem files can be used directly, saving some steps. When I update in 3 months I will update the instructions below.) My steps from Linode every three months:
    future note: update instructions to use pem files (see above)
    sudo systemctl stop tomcat
    For housekeeping on key updates, may wish to delete logs at /opt/tomcat/latest/logs 
    sudo -H certbot certonly --standalone -d glenmazza.net -d www.glenmazza.net
    (see "Congratulations!" feedback indicating Let's Encrypt worked.  Any problem running?  Try this)
    sudo -s
    cd /etc/letsencrypt/live/glenmazza.net*
    sudo openssl pkcs12 -export -in cert.pem -inkey privkey.pem -out cert_and_key.p12 -name tomcat -CAfile chain.pem -caname root
    -- The above command will prompt you for a password for the temporary cert_and_key.p12 file.
    -- Choose what you wish but remember for the next command ("abc" in the command below.) 
    -- The next command has placeholders for the Java key and keystore password (both necessary).  Choose what you wish but as I understand
    -- Tomcat expects the two to be the same (can see previous password via sudo more /var/lib/tomcat8/conf/server.xml) 
    sudo keytool -importkeystore -destkeystore MyDSKeyStore.jks -srckeystore cert_and_key.p12 -srcstorepass abc -srcstoretype PKCS12 -alias tomcat -deststorepass <changeit> -destkeypass <changeit>
    sudo cp MyDSKeyStore.jks /opt/tomcat/latest
    sudo systemctl start tomcat
    ...confirm website accessible again at https://..., if not working ensure tomcat dirs all owned by tomcat user & restart
    cd /etc/letsencrypt/live
    sudo rm -r glenmazza.net*
    

    The Java keystore password chosen above will need to be placed in the server.xml file next.

  3. Update the Tomcat conf/server.xml file to have HTTP running on port 80 and HTTPS on 443:
        <Connector port="80" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   URIEncoding="UTF-8"
                   redirectPort="443" />
    
        <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" 
        keystoreFile="MyTomcatKeystore.jks" keystorePass="?????"/>
    

    The keystore file referenced above would need to be placed in Tomcat's root directory, if you use another location be sure to update the keystoreFile value to include the path to the file.

  4. If you're using a non-root user to run Tomcat as suggested, you'll need to make some changes to allow that user to use privileged ports (ports under 1024, port 80 and port 443 in Tomcat's case). One way this can be done is via authbind. For authbind, first edit the /etc/default/tomcat8 file to activate it and then run a script similar to the following (replace "tomcat8" with the non-root user that is running Tomcat on your linode):
    sudo touch /etc/authbind/byport/80
    sudo chmod 500 /etc/authbind/byport/80
    sudo chown tomcat8 /etc/authbind/byport/80
    sudo touch /etc/authbind/byport/443
    sudo chmod 500 /etc/authbind/byport/443
    sudo chown tomcat8 /etc/authbind/byport/443
    
  5. Because the Ubuntu Linode I was using was running the UFW firewall by default, I needed further commands to be able to expose 80 and 443 to external browsers:

    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    

    Use sudo ufw status to confirm the ports are available, for IPv4 you should see:

    Status: active
    
    To                         Action      From
    --                         ------      ----
    OpenSSH                    ALLOW       Anywhere                  
    3306                       ALLOW       Anywhere                  
    8080/tcp                   ALLOW       Anywhere                  
    80/tcp                     ALLOW       Anywhere                  
    443/tcp                    ALLOW       Anywhere       
    

MySQL preparation:

  1. Install MySQL on your linode.
  2. As explained in the TightBlog wiki, create the database that will hold the TightBlog data.
  3. (Optional) To connect to the MySQL database on your linode using SquirrelSQL or another SQL client running on your local computer, these instructions will help.

TightBlog deployment:

  1. I built the TightBlog war following these instructions and renamed it to ROOT.war so it will be Tomcat's default application (i.e., have a shorter URL, https://yourdomain.com/ instead of https://yourdomain.com/tightblog). The WAR file will need to be placed in the Tomcat webapps folder as usual.
  2. There are three files that need to be uploaded to the Tomcat /lib folder, as explained on the Deploy to Tomcat page on the wiki: slf4j-api-1.7.25.jar, your JDBC driver (mysql-connector-java-X.X.X-bin.jar for MySQL), and the application-tbcustom.properties file (sample). Create or download these as appropriate.
  3. The application-tbcustom.properties makes reference to folders used for storing media files and search index information, for example /home/gmazza/tbfiles/mediafiles. Note for Tomcat to be able to read and write from these folders, the leaf folder (here, mediafiles should have the ownership of the user account running Tomcat (e.g. tomcat:tomcat), and that user must have execute permissions for every parent folder.
  4. For uploading files from your computer to your linode, see the scp or sftp commands, for example: scp ROOT.war myaccount@glenmazza.net:~/tbfiles. However, I prefer "sftp glenmazza.net", navigating to desired folders, and using "put" or "get" to upload or download respectively.
  5. After uploading the files and placing them in their proper locations, restart Tomcat and start the TightBlog application install process at https://yourdomain.com[/tightblog].

    Troubleshooting: if accessing https://yourdomain.com[/tightblog] from a browser returns 404's while you can still ping the domain, check to see if you can access that URL from a terminal window that is SSH'ed into your Linode using the command-line Lynx browser. If you can, that would mean Tomcat is running properly but there is most likely a problem with the authbind or iptable rerouting preventing external access. If you can't, Tomcat configuration should be looked at first.

  6. Best to create a test blog entry, and create a database backup and restore process and confirm it is working with your database instance (e.g., add a blog entry after the backup, restore the backup and confirm the new entry disappears, or delete a blog entry after a backup and confirm the restore returns it.) Simple commands for MySQL would be as follows (see here for more details on available commands):
    Export to a file:
    mysqldump -u root -p tightblogdb > db_backup_YYYYMMDD.sql
    Import into the database to restore it:
    mysql -u root tightblogdb < db_backup_YYYYMMDD.sql
    

    Best to save the backup copy outside of the linode (e.g., on your local machine) and create a regular backup routine.

  7. Soon after the blog is up, good to check if the emailing is working by sending yourself a comment for a blog entry. If no email is received, check the tightblog.log in the Tomcat logs folder for any mail sending exceptions. If you're using GMail and there is an authorization problem, the error logs may provide you a precise link at accounts.google.com where you can authorize TightBlog to use the email account.

Posted by Glen Mazza in Programming at 07:00AM Dec 08, 2023 | Comments[2]


Calendar
« December 2023
Sun Mon Tue Wed Thu Fri Sat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Today
About Me
Java Software Engineer
TightBlog project maintainer
Arlington, Virginia USA
glen.mazza at pm dot me
GitHub profile for Glen Mazza at Stack Overflow, Q&A for professional and enthusiast programmers
Blog Search


Blog article index
Navigation
About Blog
Blog software: TightBlog 4.0.0
Application Server: Tomcat
Database: MySQL
Hosted on: Linode
SSL Certificate: Let's Encrypt
Installation Instructions