<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.r512.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bacchas</id>
	<title>rbachwiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.r512.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bacchas"/>
	<link rel="alternate" type="text/html" href="https://www.r512.com/index.php/Special:Contributions/Bacchas"/>
	<updated>2026-11-14T06:30:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://www.r512.com/index.php?title=Setup_SSL&amp;diff=3007</id>
		<title>Setup SSL</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Setup_SSL&amp;diff=3007"/>
		<updated>2026-11-13T16:15:50Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Revoking and Removing a Certificate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;html&amp;gt; &amp;lt;h2&amp;gt;&amp;lt;a href=&amp;quot;https://www.linode.com/docs/guides/enabling-https-using-certbot-with-apache-on-ubuntu/&amp;quot; target=_blank&amp;gt;Linode Doc to setup SSL Link to Linode Doc&amp;lt;/a&amp;gt; &amp;lt;/h2&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
=[[Certbot | Certbot website]]=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Installing Snapd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;subhead&amp;quot;&amp;quot;&amp;gt;If snapd is not installed, install it now.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install snapd&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install the core snap.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo snap install core&lt;br /&gt;
 sudo snap refresh core&lt;br /&gt;
&lt;br /&gt;
==Installing Certbot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The next step is to install Certbot using the snap command.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Remove any previously installed certbot packages to avoid conflicts with the new Snap package.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove certbot&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use Snap to install Certbot.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo snap install --classic certbot&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Configure a symbolic link to the Certbot directory using the ln command.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo ln -s /snap/bin/certbot /usr/bin/certbot&lt;br /&gt;
&lt;br /&gt;
==Requesting a TLS/SSL Certificate Using Certbot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;During the certificate granting process, Certbot asks a series of questions about the domain so it can properly request the certificate. You must agree to the terms of service and provide a valid administrative email address. Depending upon the server configuration, the messages displayed by Certbot might differ somewhat from what is shown here.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Run Certbot to start the certificate request. When Certbot runs, it requests and installs certificate file along with a private key file. When used with the Apache plugin (--apache), Certbot also automatically edits the configuration files for Apache, which dramatically simplifies configuring HTTPS for your web server. If you prefer to manually adjust the configuration files, you can run Certbot using the certonly command.&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;*Request a certfifcate and automatically configure it on Apache (recommended):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo certbot --apache&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
During the installation process, Certbot will prompt you for some basic information including your email address and domain name.&lt;br /&gt;
&lt;br /&gt;
Enter email address. The first prompt is to request an email address where Certbot can send urgent notices about the domain or registration. This should be the address of the web server administrator.&lt;br /&gt;
&lt;br /&gt;
Accept terms of service. Certbot next asks you to agree to the Let’s Encrypt terms of service. Use the link in the output to download the PDF file and review the document. If you agree with the terms, enter Y. Entering N terminates the certificate request.&lt;br /&gt;
&lt;br /&gt;
Optionally subscribe to mailing list. Certbot asks if you want to subscribe to the EFF mailing list. You can answer either Y or N without affecting the rest of the installation.&lt;br /&gt;
&lt;br /&gt;
Enter domain name(s). Certbot now requests a domain name for the certificate. If there is a virtual host file for the domain, Certbot displays the names of the eligible domains. Select the numbers corresponding to the domains you are requesting certificates for, separated by spaces. If the domain doesn’t appear, you can enter the name for each domain without the http or https prefix. For each domain name, you should request separate certificates with and without the www prefix. If you have more than one domain to certify, separate the names with either a space or a comma.&lt;br /&gt;
&lt;br /&gt;
 www.example.com example.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&lt;br /&gt;
Certbot displays the names of domains configured in the virtual host files within Apache. Select the numbers corresponding to the domains you are requesting certificates for, separated by spaces.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Certbot then communicates with Let’s Encrypt to request the certificate(s) and perform any necessary challenges as defined in the ACME standard (see Challenge Types). In most cases, ownership can be proven through the HTTP challenge, which automatically adds a file on your web server. If you wish to change the challenge type or perform challenge manually, see the Manual section in the Certbot documentation.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If the operation is successful, Certbot confirms the certificates are enabled and outputs the details. It also displays some information about the directories where the certificates and key chains are stored, along with the expiration date. Certificates typically expire in 90 days.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Testing the HTTPS Connection===&lt;br /&gt;
The next step is to confirm the website is properly configured to use your new certificate and is accessible over HTTPS. To do this, navigate to your website on a web browser, making sure to specify the https:// protocol when entering your URL. If a lock is visible to the left of the domain name on the browser’s address bar, the certificate is likely working as expected. If the certificate is not installed properly, the browser displays a warning page.&lt;br /&gt;
&lt;br /&gt;
You can also enter your domain into the SSL Server Test by Qualys SSL Labs to verify that the TLS/SSL certificate has been properly installed and configured.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Renewing a TLS/SSL Certificate Using Certbot===&lt;br /&gt;
Upon installation, Certbot is configured to renew any certificates automatically. It is not necessary to manually request an updated certificate or run Certbot again unless the site configuration changes. However, Certbot makes it possible to test the auto-renew mechanism or to forcibly update all certificates.&lt;br /&gt;
&lt;br /&gt;
===Test Automated Renewals===&lt;br /&gt;
To confirm Certbot is configured to renew its certificates automatically, use certbot renew along with the dry-run flag.&lt;br /&gt;
&lt;br /&gt;
 sudo certbot renew --dry-run&lt;br /&gt;
&lt;br /&gt;
Certbot inspects the certificates and confirms they are not due to be renewed, but simulates the process anyway. It displays details regarding whether the renewal would have been successful.&lt;br /&gt;
&lt;br /&gt;
== Add additional domains==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; This will create a new certificate for the domains you are adding &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  sudo certbot --apache&lt;br /&gt;
&lt;br /&gt;
===Changing a Certificate’s Domains===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The --cert-name flag can also be used to modify the domains a certificate contains, by specifying new domains using the -d or --domains flag. If certificate example.com previously contained example.com and www.example.com, it can be modified to only contain example.com by specifying only example.com with the -d or --domains flag. Example:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 certbot certonly --cert-name example.com -d example.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The same format can be used to expand the set of domains a certificate contains, or to replace that set entirely:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 certbot certonly --cert-name example.com -d example.org,www.example.org&lt;br /&gt;
&lt;br /&gt;
==Revoking and Removing a Certificate==&lt;br /&gt;
&lt;br /&gt;
 certbot certificates&lt;br /&gt;
&lt;br /&gt;
* this list the certificates on the server&lt;br /&gt;
&lt;br /&gt;
 certbot delete --cert-name example.com&lt;br /&gt;
&lt;br /&gt;
* This deletes the cert&lt;br /&gt;
&lt;br /&gt;
*3. Remove or turn off the site’s web server config on the old server, because it still points at the deleted certificate files. If you skip this, Apache or nginx may refuse to restart.&lt;br /&gt;
&lt;br /&gt;
 a2dissite example.com&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
=[[Linode]]=&lt;br /&gt;
[[Category:Linode]]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Setup_SSL&amp;diff=3006</id>
		<title>Setup SSL</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Setup_SSL&amp;diff=3006"/>
		<updated>2026-11-13T16:15:23Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;html&amp;gt; &amp;lt;h2&amp;gt;&amp;lt;a href=&amp;quot;https://www.linode.com/docs/guides/enabling-https-using-certbot-with-apache-on-ubuntu/&amp;quot; target=_blank&amp;gt;Linode Doc to setup SSL Link to Linode Doc&amp;lt;/a&amp;gt; &amp;lt;/h2&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;
=[[Certbot | Certbot website]]=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Installing Snapd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;subhead&amp;quot;&amp;quot;&amp;gt;If snapd is not installed, install it now.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install snapd&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install the core snap.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo snap install core&lt;br /&gt;
 sudo snap refresh core&lt;br /&gt;
&lt;br /&gt;
==Installing Certbot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The next step is to install Certbot using the snap command.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Remove any previously installed certbot packages to avoid conflicts with the new Snap package.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove certbot&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use Snap to install Certbot.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo snap install --classic certbot&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Configure a symbolic link to the Certbot directory using the ln command.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo ln -s /snap/bin/certbot /usr/bin/certbot&lt;br /&gt;
&lt;br /&gt;
==Requesting a TLS/SSL Certificate Using Certbot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;During the certificate granting process, Certbot asks a series of questions about the domain so it can properly request the certificate. You must agree to the terms of service and provide a valid administrative email address. Depending upon the server configuration, the messages displayed by Certbot might differ somewhat from what is shown here.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Run Certbot to start the certificate request. When Certbot runs, it requests and installs certificate file along with a private key file. When used with the Apache plugin (--apache), Certbot also automatically edits the configuration files for Apache, which dramatically simplifies configuring HTTPS for your web server. If you prefer to manually adjust the configuration files, you can run Certbot using the certonly command.&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;*Request a certfifcate and automatically configure it on Apache (recommended):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo certbot --apache&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
During the installation process, Certbot will prompt you for some basic information including your email address and domain name.&lt;br /&gt;
&lt;br /&gt;
Enter email address. The first prompt is to request an email address where Certbot can send urgent notices about the domain or registration. This should be the address of the web server administrator.&lt;br /&gt;
&lt;br /&gt;
Accept terms of service. Certbot next asks you to agree to the Let’s Encrypt terms of service. Use the link in the output to download the PDF file and review the document. If you agree with the terms, enter Y. Entering N terminates the certificate request.&lt;br /&gt;
&lt;br /&gt;
Optionally subscribe to mailing list. Certbot asks if you want to subscribe to the EFF mailing list. You can answer either Y or N without affecting the rest of the installation.&lt;br /&gt;
&lt;br /&gt;
Enter domain name(s). Certbot now requests a domain name for the certificate. If there is a virtual host file for the domain, Certbot displays the names of the eligible domains. Select the numbers corresponding to the domains you are requesting certificates for, separated by spaces. If the domain doesn’t appear, you can enter the name for each domain without the http or https prefix. For each domain name, you should request separate certificates with and without the www prefix. If you have more than one domain to certify, separate the names with either a space or a comma.&lt;br /&gt;
&lt;br /&gt;
 www.example.com example.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&lt;br /&gt;
Certbot displays the names of domains configured in the virtual host files within Apache. Select the numbers corresponding to the domains you are requesting certificates for, separated by spaces.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Certbot then communicates with Let’s Encrypt to request the certificate(s) and perform any necessary challenges as defined in the ACME standard (see Challenge Types). In most cases, ownership can be proven through the HTTP challenge, which automatically adds a file on your web server. If you wish to change the challenge type or perform challenge manually, see the Manual section in the Certbot documentation.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If the operation is successful, Certbot confirms the certificates are enabled and outputs the details. It also displays some information about the directories where the certificates and key chains are stored, along with the expiration date. Certificates typically expire in 90 days.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Testing the HTTPS Connection===&lt;br /&gt;
The next step is to confirm the website is properly configured to use your new certificate and is accessible over HTTPS. To do this, navigate to your website on a web browser, making sure to specify the https:// protocol when entering your URL. If a lock is visible to the left of the domain name on the browser’s address bar, the certificate is likely working as expected. If the certificate is not installed properly, the browser displays a warning page.&lt;br /&gt;
&lt;br /&gt;
You can also enter your domain into the SSL Server Test by Qualys SSL Labs to verify that the TLS/SSL certificate has been properly installed and configured.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Renewing a TLS/SSL Certificate Using Certbot===&lt;br /&gt;
Upon installation, Certbot is configured to renew any certificates automatically. It is not necessary to manually request an updated certificate or run Certbot again unless the site configuration changes. However, Certbot makes it possible to test the auto-renew mechanism or to forcibly update all certificates.&lt;br /&gt;
&lt;br /&gt;
===Test Automated Renewals===&lt;br /&gt;
To confirm Certbot is configured to renew its certificates automatically, use certbot renew along with the dry-run flag.&lt;br /&gt;
&lt;br /&gt;
 sudo certbot renew --dry-run&lt;br /&gt;
&lt;br /&gt;
Certbot inspects the certificates and confirms they are not due to be renewed, but simulates the process anyway. It displays details regarding whether the renewal would have been successful.&lt;br /&gt;
&lt;br /&gt;
== Add additional domains==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; This will create a new certificate for the domains you are adding &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  sudo certbot --apache&lt;br /&gt;
&lt;br /&gt;
===Changing a Certificate’s Domains===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The --cert-name flag can also be used to modify the domains a certificate contains, by specifying new domains using the -d or --domains flag. If certificate example.com previously contained example.com and www.example.com, it can be modified to only contain example.com by specifying only example.com with the -d or --domains flag. Example:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 certbot certonly --cert-name example.com -d example.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The same format can be used to expand the set of domains a certificate contains, or to replace that set entirely:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 certbot certonly --cert-name example.com -d example.org,www.example.org&lt;br /&gt;
&lt;br /&gt;
==Revoking and Removing a Certificate==&lt;br /&gt;
&lt;br /&gt;
 certbot certificates&lt;br /&gt;
&lt;br /&gt;
* this list the certificates on the server&lt;br /&gt;
&lt;br /&gt;
certbot delete --cert-name example.com&lt;br /&gt;
&lt;br /&gt;
* This deletes the cert&lt;br /&gt;
&lt;br /&gt;
*3. Remove or turn off the site’s web server config on the old server, because it still points at the deleted certificate files. If you skip this, Apache or nginx may refuse to restart.&lt;br /&gt;
&lt;br /&gt;
 a2dissite example.com&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=[[Linode]]=&lt;br /&gt;
[[Category:Linode]]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3005</id>
		<title>Moving To New Server</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3005"/>
		<updated>2026-11-11T17:31:25Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Moving Joomla to a new Server=&lt;br /&gt;
&lt;br /&gt;
==On the old server, dump the database:==&lt;br /&gt;
 mysqldump -u root --single-transaction --routines DBNAME &amp;gt; joomla.sql&lt;br /&gt;
&lt;br /&gt;
Copy the files while preserving permissions and timestamps:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/&lt;br /&gt;
&lt;br /&gt;
== On the new server, create the database and user, then import: ==&lt;br /&gt;
&lt;br /&gt;
===Create the database in phpmyadmin===&lt;br /&gt;
* Log in to phpMyAdmin (as root or another admin user).&lt;br /&gt;
* Click Databases in the top tab bar.&lt;br /&gt;
* Under “Create database,” enter the name and pick the collation utf8mb4_unicode_ci (or utf8mb4_general_ci). Click Create.&lt;br /&gt;
&lt;br /&gt;
==Import from the command line== &lt;br /&gt;
 mysql -u root DBNAME &amp;lt; joomla.sql&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3004</id>
		<title>Moving To New Server</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3004"/>
		<updated>2026-11-11T17:30:59Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==On the old server, dump the database:==&lt;br /&gt;
 mysqldump -u root --single-transaction --routines DBNAME &amp;gt; joomla.sql&lt;br /&gt;
&lt;br /&gt;
Copy the files while preserving permissions and timestamps:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/&lt;br /&gt;
&lt;br /&gt;
== On the new server, create the database and user, then import: ==&lt;br /&gt;
&lt;br /&gt;
===Create the database in phpmyadmin===&lt;br /&gt;
* Log in to phpMyAdmin (as root or another admin user).&lt;br /&gt;
* Click Databases in the top tab bar.&lt;br /&gt;
* Under “Create database,” enter the name and pick the collation utf8mb4_unicode_ci (or utf8mb4_general_ci). Click Create.&lt;br /&gt;
&lt;br /&gt;
==Import from the command line== &lt;br /&gt;
 mysql -u root DBNAME &amp;lt; joomla.sql&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3003</id>
		<title>Moving To New Server</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3003"/>
		<updated>2026-11-11T17:30:41Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==On the old server, dump the database:==&lt;br /&gt;
 mysqldump -u root -p --single-transaction --routines DBNAME &amp;gt; joomla.sql&lt;br /&gt;
&lt;br /&gt;
Copy the files while preserving permissions and timestamps:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/&lt;br /&gt;
&lt;br /&gt;
== On the new server, create the database and user, then import: ==&lt;br /&gt;
&lt;br /&gt;
===Create the database in phpmyadmin===&lt;br /&gt;
* Log in to phpMyAdmin (as root or another admin user).&lt;br /&gt;
* Click Databases in the top tab bar.&lt;br /&gt;
* Under “Create database,” enter the name and pick the collation utf8mb4_unicode_ci (or utf8mb4_general_ci). Click Create.&lt;br /&gt;
&lt;br /&gt;
==Import from the command line== &lt;br /&gt;
 mysql -u root DBNAME &amp;lt; joomla.sql&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3002</id>
		<title>Moving To New Server</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3002"/>
		<updated>2026-11-11T17:30:23Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==On the old server, dump the database:==&lt;br /&gt;
 mysqldump -u root -p --single-transaction --routines DBNAME &amp;gt; joomla.sql&lt;br /&gt;
&lt;br /&gt;
Copy the files while preserving permissions and timestamps:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/&lt;br /&gt;
&lt;br /&gt;
== On the new server, create the database and user, then import: ==&lt;br /&gt;
&lt;br /&gt;
===Create the database in phpmyadmin===&lt;br /&gt;
* Log in to phpMyAdmin (as root or another admin user).&lt;br /&gt;
* Click Databases in the top tab bar.&lt;br /&gt;
* Under “Create database,” enter the name and pick the collation utf8mb4_unicode_ci (or utf8mb4_general_ci). Click Create.&lt;br /&gt;
&lt;br /&gt;
==Import from the command line== &lt;br /&gt;
 mysql -u root -p DBNAME &amp;lt; joomla.sql&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3001</id>
		<title>Moving To New Server</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3001"/>
		<updated>2026-11-11T17:29:26Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==On the old server, dump the database:==&lt;br /&gt;
 mysqldump -u root -p --single-transaction --routines DBNAME &amp;gt; joomla.sql&lt;br /&gt;
&lt;br /&gt;
Copy the files while preserving permissions and timestamps:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/&lt;br /&gt;
&lt;br /&gt;
== On the new server, create the database and user, then import: ==&lt;br /&gt;
&lt;br /&gt;
===Create the database in phpmyadmin===&lt;br /&gt;
* Log in to phpMyAdmin (as root or another admin user).&lt;br /&gt;
* Click Databases in the top tab bar.&lt;br /&gt;
* Under “Create database,” enter the name and pick the collation utf8mb4_unicode_ci (or utf8mb4_general_ci). Click Create.&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3000</id>
		<title>Moving To New Server</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Moving_To_New_Server&amp;diff=3000"/>
		<updated>2026-11-11T17:29:03Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: Created page with &amp;quot;==On the old server, dump the database:==  mysqldump -u root -p --single-transaction --routines DBNAME &amp;gt; joomla.sql  Copy the files while preserving permissions and timestamps:   rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/  == On the new server, create the database and user, then import: ==  ===Create the database in phpmyadmin=== 1. Log in to phpMyAdmin (as root or another admin user). 2. Click Databases in the top tab bar. 3. Under “Create...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==On the old server, dump the database:==&lt;br /&gt;
 mysqldump -u root -p --single-transaction --routines DBNAME &amp;gt; joomla.sql&lt;br /&gt;
&lt;br /&gt;
Copy the files while preserving permissions and timestamps:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz --progress /var/www/joomla/ user@newserver:/var/www/joomla/&lt;br /&gt;
&lt;br /&gt;
== On the new server, create the database and user, then import: ==&lt;br /&gt;
&lt;br /&gt;
===Create the database in phpmyadmin===&lt;br /&gt;
1. Log in to phpMyAdmin (as root or another admin user).&lt;br /&gt;
2. Click Databases in the top tab bar.&lt;br /&gt;
3. Under “Create database,” enter the name and pick the collation utf8mb4_unicode_ci (or utf8mb4_general_ci). Click Create.&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Joomla&amp;diff=2999</id>
		<title>Joomla</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Joomla&amp;diff=2999"/>
		<updated>2026-11-11T17:25:26Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== [[Joomla Tips]] ==&lt;br /&gt;
== [[Smartform Gold]]==&lt;br /&gt;
==[[Moving To New Server]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=MYSQL_DATABASE_RESTORE&amp;diff=2998</id>
		<title>MYSQL DATABASE RESTORE</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=MYSQL_DATABASE_RESTORE&amp;diff=2998"/>
		<updated>2026-11-11T14:44:23Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Script to import a CSV File into an existing Database */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Restore Database==&lt;br /&gt;
&amp;lt;p style=&amp;quot;background-color: #77a8f7; font-weight: bold; font-size: 1.2rem;&amp;quot;&amp;gt; I used this to restore r512 from the dumped .sql file in 2025 &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p style=&amp;quot;font-weight: bold;font-size: 1.3rem&amp;quot;&amp;gt; I tried to restore it using phpmyadmin, but it did not work, got many errors. probably because it was a raw sql dump backup. The target database must already exist. if it doesn&amp;#039;t, create it first&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* log into mysql&lt;br /&gt;
 CREATE DATABASE your_database_name;&lt;br /&gt;
&lt;br /&gt;
 mysql&lt;br /&gt;
 use databasename;&lt;br /&gt;
&lt;br /&gt;
 SOURCE /path/to/file/file.sql;&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;p class=&amp;quot;yellowbackground&amp;quot;&amp;gt;Script to import a CSV File into an existing Database&amp;lt;/p&amp;gt; ==&lt;br /&gt;
&amp;lt;p style=&amp;quot;background-color: #77a8f7; font-weight: bold; font-size: 1.2rem;&amp;quot;&amp;gt;The csv file has to be in a specific directory. /var/lib/mysql-files/&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p style=&amp;quot;background-color: #77a8f7; font-weight: bold; font-size: 1.2rem;&amp;quot;&amp;gt;The table has to already exist &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
mysql kartest &amp;lt;&amp;lt;EOF&lt;br /&gt;
truncate table songs;&lt;br /&gt;
load data infile &amp;#039;/var/lib/mysql-files/songs.csv&amp;#039;&lt;br /&gt;
into table songs&lt;br /&gt;
fields terminated by &amp;#039;|&amp;#039;&lt;br /&gt;
enclosed by &amp;#039;&amp;quot;&amp;#039;&lt;br /&gt;
lines terminated by &amp;#039;\n&amp;#039;&lt;br /&gt;
ignore 1 rows;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Copy csv file to a dir and run script on server ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
fxcopy=&amp;quot;/mnt/c/Users/john/Dropbox/Shining Cabinet/My Stuff/sqlitedb&amp;quot;&lt;br /&gt;
scp -i ~/.ssh/linode &amp;quot;$fxcopy/filename.csv&amp;quot; 1.1.1.1:/var/lib/mysql-files/&lt;br /&gt;
sleep 4&lt;br /&gt;
ssh -i ~/.ssh/linode root@1.1.1.1 /var/www/scripts/import.sh&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fixing error connecting to database from AppSheet ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; The permission has to be fixed to the old version in mysql server &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ALTER USER &amp;#039;username&amp;#039;@&amp;#039;%&amp;#039; IDENTIFIED WITH mysql_native_password BY &amp;#039;password&amp;#039;;&lt;br /&gt;
 FLUSH PRIVILEGES;&lt;br /&gt;
== Fix error where script to load the csv file would not execute on server===&lt;br /&gt;
&amp;lt;p class=&amp;quot;subhead&amp;quot;&amp;gt;Edit the /etc/mysql/my.cnf file &amp;lt;/p&amp;gt;&lt;br /&gt;
 [mysqld]&lt;br /&gt;
 secure-file-priv=&amp;quot;/var/lib/mysql-files&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; you may have to add the line if it doesn&amp;#039;t exist&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[#MySql Commands My Fav|Back To Top]]-[[Main_Page| Home]]&lt;br /&gt;
[[Category:Mysql]]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2997</id>
		<title>Docker Deploy App</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2997"/>
		<updated>2026-11-10T18:18:27Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Deploy PDF Extractor to a New Server =&lt;br /&gt;
&lt;br /&gt;
This guide deploys PDF Extractor using Docker Compose, with Apache providing HTTPS access.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* An Ubuntu server with Apache and Docker already installed.&lt;br /&gt;
* SSH access with root or sudo privileges.&lt;br /&gt;
* A domain or subdomain pointing to the new server.&lt;br /&gt;
* The complete application deployment ZIP, including:&lt;br /&gt;
** Dockerfile&lt;br /&gt;
** compose.yaml&lt;br /&gt;
** requirements.txt&lt;br /&gt;
** app.py&lt;br /&gt;
** static/ directory&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use the complete deployment ZIP for a new installation. An update-only ZIP may not contain everything required.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Example Settings ==&lt;br /&gt;
&lt;br /&gt;
Replace these example values where necessary:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Example&lt;br /&gt;
|-&lt;br /&gt;
| Application directory || /opt/pdfextractorwebapp&lt;br /&gt;
|-&lt;br /&gt;
| Website address || pdf.example.com&lt;br /&gt;
|-&lt;br /&gt;
| Deployment archive || pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
|-&lt;br /&gt;
| Local application port || 8000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The project files reside in /opt/pdfextractorwebapp on the server. The application runs inside its Docker container.&lt;br /&gt;
&lt;br /&gt;
== 1. Upload the Application ==&lt;br /&gt;
&lt;br /&gt;
Upload the complete deployment ZIP to the new server&amp;#039;s /tmp/ directory using SCP, SFTP, or your preferred file-transfer application.&lt;br /&gt;
&lt;br /&gt;
== 2. Check Docker Compose ==&lt;br /&gt;
&lt;br /&gt;
Connect to the server using SSH, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker --version&lt;br /&gt;
sudo docker compose version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both commands should display version information.&lt;br /&gt;
&lt;br /&gt;
If the second command fails, install the Docker Compose plugin for your Docker installation before continuing.&lt;br /&gt;
&lt;br /&gt;
== 3. Extract the Application ==&lt;br /&gt;
&lt;br /&gt;
Install unzip and curl if needed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y unzip curl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the application directory and extract the archive:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo mkdir -p /opt/pdfextractorwebapp&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Confirm the project files are directly inside this directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ls -la&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dockerfile and compose.yaml should be visible.&lt;br /&gt;
&lt;br /&gt;
== 4. Build and Start the Container ==&lt;br /&gt;
&lt;br /&gt;
From the application directory, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first build downloads dependencies and may take several minutes.&lt;br /&gt;
&lt;br /&gt;
* --build builds the application image.&lt;br /&gt;
* -d runs the container in the background.&lt;br /&gt;
&lt;br /&gt;
Check the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its status should show &amp;#039;&amp;#039;&amp;#039;Up&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The supplied compose.yaml includes a restart policy so the application restarts after a server reboot, provided Docker starts automatically.&lt;br /&gt;
&lt;br /&gt;
Enable Docker at startup:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl enable --now docker&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Test the Application Directly ==&lt;br /&gt;
&lt;br /&gt;
Before configuring Apache, test the application locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected results:&lt;br /&gt;
&lt;br /&gt;
* The health endpoint returns {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
* The application page returns HTTP 200.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Do not continue until these checks pass.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To investigate a failure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The supplied configuration binds port 8000 to 127.0.0.1. Keep this setting so Apache handles public access.&lt;br /&gt;
&lt;br /&gt;
== 6. Configure Apache ==&lt;br /&gt;
&lt;br /&gt;
Enable the reverse-proxy modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2enmod proxy proxy_http&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create an Apache site configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/pdfextractor.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following, replacing pdf.example.com with your actual hostname:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pdf.example.com&lt;br /&gt;
&lt;br /&gt;
    ProxyRequests Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyTimeout 600&lt;br /&gt;
&lt;br /&gt;
    LimitRequestBody 53477376&lt;br /&gt;
&lt;br /&gt;
    ProxyPass &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot; connectiontimeout=5 timeout=600&lt;br /&gt;
    ProxyPassReverse &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/pdfextractor-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/pdfextractor-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The timeout accommodates longer PDF exports. The request-body limit accommodates the application&amp;#039;s default 50 MB upload limit plus metadata.&lt;br /&gt;
&lt;br /&gt;
If this hostname already has an Apache configuration, update that configuration instead of creating a competing virtual host.&lt;br /&gt;
&lt;br /&gt;
Enable the site and validate the configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite pdfextractor.conf&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the result is &amp;#039;&amp;#039;&amp;#039;Syntax OK&amp;#039;&amp;#039;&amp;#039;, reload Apache:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test Apache&amp;#039;s connection to the application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i -H &amp;quot;Host: pdf.example.com&amp;quot; http://127.0.0.1/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected result: HTTP 200 and {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
&lt;br /&gt;
== 7. Configure DNS and Firewall Access ==&lt;br /&gt;
&lt;br /&gt;
At your DNS provider:&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&amp;#039;s A record to the new server&amp;#039;s public IPv4 address.&lt;br /&gt;
# If an AAAA record exists, update it to the new server&amp;#039;s IPv6 address, or remove it if IPv6 is unused.&lt;br /&gt;
&lt;br /&gt;
Allow inbound TCP ports &amp;#039;&amp;#039;&amp;#039;80&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;443&amp;#039;&amp;#039;&amp;#039; through the server firewall and any hosting-provider firewall.&lt;br /&gt;
&lt;br /&gt;
If UFW is already active, allow Apache traffic:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo ufw allow &amp;#039;Apache Full&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not enable UFW without first ensuring SSH access is allowed.&lt;br /&gt;
&lt;br /&gt;
Port 8000 does not need public access.&lt;br /&gt;
&lt;br /&gt;
If migrating an existing hostname, keep the old server running while DNS changes propagate.&lt;br /&gt;
&lt;br /&gt;
== 8. [[Setup_SSL]] ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ensure the HTTPS virtual host retains the ProxyPass and ProxyPassReverse settings, including timeout=600.&lt;br /&gt;
&lt;br /&gt;
== 9. Verify the Deployment ==&lt;br /&gt;
&lt;br /&gt;
Test the public HTTPS endpoint:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS https://pdf.example.com/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the website in a browser and verify:&lt;br /&gt;
&lt;br /&gt;
# The interface loads.&lt;br /&gt;
# A PDF can be uploaded.&lt;br /&gt;
# Page previews work.&lt;br /&gt;
# An export downloads successfully.&lt;br /&gt;
# Multiple PDFs can be processed together.&lt;br /&gt;
&lt;br /&gt;
== Updating the Application Later ==&lt;br /&gt;
&lt;br /&gt;
Upload the update ZIP to /tmp/, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/UPDATE-FILENAME.zip&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace UPDATE-FILENAME.zip with the actual archive name.&lt;br /&gt;
&lt;br /&gt;
Refresh the website after rebuilding.&lt;br /&gt;
&lt;br /&gt;
== Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
Run these commands from /opt/pdfextractorwebapp.&lt;br /&gt;
&lt;br /&gt;
=== View Container Status ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Recent Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Follow Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs -f pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Press Ctrl+C to stop following logs. This does not stop the container.&lt;br /&gt;
&lt;br /&gt;
=== Restart the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restarting does not apply source-code changes copied into the Docker image. Use a rebuild after updating application files.&lt;br /&gt;
&lt;br /&gt;
=== Rebuild After Changes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stop the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose stop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Apache Errors ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo tail -n 100 /var/log/apache2/pdfextractor-error.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Apache Displays a Proxy Error ===&lt;br /&gt;
&lt;br /&gt;
Check the application directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i --max-time 10 http://127.0.0.1:8000/health&lt;br /&gt;
curl -I --max-time 10 http://127.0.0.1:8000/&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the local application works, inspect the Apache configuration and error log.&lt;br /&gt;
&lt;br /&gt;
=== Permission Denied for Static Files ===&lt;br /&gt;
&lt;br /&gt;
If the container logs report PermissionError for /app/static/index.html, correct the source-file permissions and rebuild:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo chmod 755 static&lt;br /&gt;
sudo chmod 644 app.py static/index.html static/app.js static/style.css&lt;br /&gt;
&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corrected Dockerfile also normalizes these permissions during the build.&lt;br /&gt;
&lt;br /&gt;
=== Exports Time Out ===&lt;br /&gt;
&lt;br /&gt;
Confirm the active HTTPS virtual host includes timeout=600 on its ProxyPass directive.&lt;br /&gt;
&lt;br /&gt;
Validate and reload Apache after changing its configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For unusually large exports, try fewer pages or smaller batches.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.docker.com/reference/cli/docker/compose/up/ Docker Compose: build and start containers]&lt;br /&gt;
* [https://httpd.apache.org/docs/2.4/en/howto/reverse_proxy.html Apache reverse-proxy guide]&lt;br /&gt;
* [https://eff-certbot.readthedocs.io/en/stable/man/certbot.html Certbot documentation]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2996</id>
		<title>Docker Deploy App</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2996"/>
		<updated>2026-11-10T18:17:04Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Setup_SSL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Deploy PDF Extractor to a New Server =&lt;br /&gt;
&lt;br /&gt;
This guide deploys PDF Extractor using Docker Compose, with Apache providing HTTPS access.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* An Ubuntu server with Apache and Docker already installed.&lt;br /&gt;
* SSH access with root or sudo privileges.&lt;br /&gt;
* A domain or subdomain pointing to the new server.&lt;br /&gt;
* The complete application deployment ZIP, including:&lt;br /&gt;
** Dockerfile&lt;br /&gt;
** compose.yaml&lt;br /&gt;
** requirements.txt&lt;br /&gt;
** app.py&lt;br /&gt;
** static/ directory&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use the complete deployment ZIP for a new installation. An update-only ZIP may not contain everything required.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Example Settings ==&lt;br /&gt;
&lt;br /&gt;
Replace these example values where necessary:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Example&lt;br /&gt;
|-&lt;br /&gt;
| Application directory || /opt/pdfextractorwebapp&lt;br /&gt;
|-&lt;br /&gt;
| Website address || pdf.example.com&lt;br /&gt;
|-&lt;br /&gt;
| Deployment archive || pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
|-&lt;br /&gt;
| Local application port || 8000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The project files reside in /opt/pdfextractorwebapp on the server. The application runs inside its Docker container.&lt;br /&gt;
&lt;br /&gt;
== 1. Upload the Application ==&lt;br /&gt;
&lt;br /&gt;
Upload the complete deployment ZIP to the new server&amp;#039;s /tmp/ directory using SCP, SFTP, or your preferred file-transfer application.&lt;br /&gt;
&lt;br /&gt;
== 2. Check Docker Compose ==&lt;br /&gt;
&lt;br /&gt;
Connect to the server using SSH, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker --version&lt;br /&gt;
sudo docker compose version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both commands should display version information.&lt;br /&gt;
&lt;br /&gt;
If the second command fails, install the Docker Compose plugin for your Docker installation before continuing.&lt;br /&gt;
&lt;br /&gt;
== 3. Extract the Application ==&lt;br /&gt;
&lt;br /&gt;
Install unzip and curl if needed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y unzip curl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the application directory and extract the archive:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo mkdir -p /opt/pdfextractorwebapp&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Confirm the project files are directly inside this directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ls -la&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dockerfile and compose.yaml should be visible.&lt;br /&gt;
&lt;br /&gt;
== 4. Build and Start the Container ==&lt;br /&gt;
&lt;br /&gt;
From the application directory, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first build downloads dependencies and may take several minutes.&lt;br /&gt;
&lt;br /&gt;
* --build builds the application image.&lt;br /&gt;
* -d runs the container in the background.&lt;br /&gt;
&lt;br /&gt;
Check the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its status should show &amp;#039;&amp;#039;&amp;#039;Up&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The supplied compose.yaml includes a restart policy so the application restarts after a server reboot, provided Docker starts automatically.&lt;br /&gt;
&lt;br /&gt;
Enable Docker at startup:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl enable --now docker&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Test the Application Directly ==&lt;br /&gt;
&lt;br /&gt;
Before configuring Apache, test the application locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected results:&lt;br /&gt;
&lt;br /&gt;
* The health endpoint returns {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
* The application page returns HTTP 200.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Do not continue until these checks pass.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To investigate a failure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The supplied configuration binds port 8000 to 127.0.0.1. Keep this setting so Apache handles public access.&lt;br /&gt;
&lt;br /&gt;
== 6. Configure Apache ==&lt;br /&gt;
&lt;br /&gt;
Enable the reverse-proxy modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2enmod proxy proxy_http&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create an Apache site configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/pdfextractor.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following, replacing pdf.example.com with your actual hostname:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pdf.example.com&lt;br /&gt;
&lt;br /&gt;
    ProxyRequests Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyTimeout 600&lt;br /&gt;
&lt;br /&gt;
    LimitRequestBody 53477376&lt;br /&gt;
&lt;br /&gt;
    ProxyPass &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot; connectiontimeout=5 timeout=600&lt;br /&gt;
    ProxyPassReverse &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/pdfextractor-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/pdfextractor-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The timeout accommodates longer PDF exports. The request-body limit accommodates the application&amp;#039;s default 50 MB upload limit plus metadata.&lt;br /&gt;
&lt;br /&gt;
If this hostname already has an Apache configuration, update that configuration instead of creating a competing virtual host.&lt;br /&gt;
&lt;br /&gt;
Enable the site and validate the configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite pdfextractor.conf&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the result is &amp;#039;&amp;#039;&amp;#039;Syntax OK&amp;#039;&amp;#039;&amp;#039;, reload Apache:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test Apache&amp;#039;s connection to the application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i -H &amp;quot;Host: pdf.example.com&amp;quot; http://127.0.0.1/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected result: HTTP 200 and {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
&lt;br /&gt;
== 7. Configure DNS and Firewall Access ==&lt;br /&gt;
&lt;br /&gt;
At your DNS provider:&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&amp;#039;s A record to the new server&amp;#039;s public IPv4 address.&lt;br /&gt;
# If an AAAA record exists, update it to the new server&amp;#039;s IPv6 address, or remove it if IPv6 is unused.&lt;br /&gt;
&lt;br /&gt;
Allow inbound TCP ports &amp;#039;&amp;#039;&amp;#039;80&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;443&amp;#039;&amp;#039;&amp;#039; through the server firewall and any hosting-provider firewall.&lt;br /&gt;
&lt;br /&gt;
If UFW is already active, allow Apache traffic:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo ufw allow &amp;#039;Apache Full&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not enable UFW without first ensuring SSH access is allowed.&lt;br /&gt;
&lt;br /&gt;
Port 8000 does not need public access.&lt;br /&gt;
&lt;br /&gt;
If migrating an existing hostname, keep the old server running while DNS changes propagate.&lt;br /&gt;
&lt;br /&gt;
== 8. Enable HTTPS ==&lt;br /&gt;
&lt;br /&gt;
===[[Setup_SSL]]===&lt;br /&gt;
&lt;br /&gt;
Ensure the HTTPS virtual host retains the ProxyPass and ProxyPassReverse settings, including timeout=600.&lt;br /&gt;
&lt;br /&gt;
== 9. Verify the Deployment ==&lt;br /&gt;
&lt;br /&gt;
Test the public HTTPS endpoint:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS https://pdf.example.com/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the website in a browser and verify:&lt;br /&gt;
&lt;br /&gt;
# The interface loads.&lt;br /&gt;
# A PDF can be uploaded.&lt;br /&gt;
# Page previews work.&lt;br /&gt;
# An export downloads successfully.&lt;br /&gt;
# Multiple PDFs can be processed together.&lt;br /&gt;
&lt;br /&gt;
== Updating the Application Later ==&lt;br /&gt;
&lt;br /&gt;
Upload the update ZIP to /tmp/, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/UPDATE-FILENAME.zip&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace UPDATE-FILENAME.zip with the actual archive name.&lt;br /&gt;
&lt;br /&gt;
Refresh the website after rebuilding.&lt;br /&gt;
&lt;br /&gt;
== Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
Run these commands from /opt/pdfextractorwebapp.&lt;br /&gt;
&lt;br /&gt;
=== View Container Status ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Recent Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Follow Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs -f pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Press Ctrl+C to stop following logs. This does not stop the container.&lt;br /&gt;
&lt;br /&gt;
=== Restart the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restarting does not apply source-code changes copied into the Docker image. Use a rebuild after updating application files.&lt;br /&gt;
&lt;br /&gt;
=== Rebuild After Changes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stop the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose stop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Apache Errors ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo tail -n 100 /var/log/apache2/pdfextractor-error.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Apache Displays a Proxy Error ===&lt;br /&gt;
&lt;br /&gt;
Check the application directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i --max-time 10 http://127.0.0.1:8000/health&lt;br /&gt;
curl -I --max-time 10 http://127.0.0.1:8000/&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the local application works, inspect the Apache configuration and error log.&lt;br /&gt;
&lt;br /&gt;
=== Permission Denied for Static Files ===&lt;br /&gt;
&lt;br /&gt;
If the container logs report PermissionError for /app/static/index.html, correct the source-file permissions and rebuild:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo chmod 755 static&lt;br /&gt;
sudo chmod 644 app.py static/index.html static/app.js static/style.css&lt;br /&gt;
&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corrected Dockerfile also normalizes these permissions during the build.&lt;br /&gt;
&lt;br /&gt;
=== Exports Time Out ===&lt;br /&gt;
&lt;br /&gt;
Confirm the active HTTPS virtual host includes timeout=600 on its ProxyPass directive.&lt;br /&gt;
&lt;br /&gt;
Validate and reload Apache after changing its configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For unusually large exports, try fewer pages or smaller batches.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.docker.com/reference/cli/docker/compose/up/ Docker Compose: build and start containers]&lt;br /&gt;
* [https://httpd.apache.org/docs/2.4/en/howto/reverse_proxy.html Apache reverse-proxy guide]&lt;br /&gt;
* [https://eff-certbot.readthedocs.io/en/stable/man/certbot.html Certbot documentation]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2995</id>
		<title>Docker Deploy App</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2995"/>
		<updated>2026-11-10T18:16:25Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* 8. Enable HTTPS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Deploy PDF Extractor to a New Server =&lt;br /&gt;
&lt;br /&gt;
This guide deploys PDF Extractor using Docker Compose, with Apache providing HTTPS access.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* An Ubuntu server with Apache and Docker already installed.&lt;br /&gt;
* SSH access with root or sudo privileges.&lt;br /&gt;
* A domain or subdomain pointing to the new server.&lt;br /&gt;
* The complete application deployment ZIP, including:&lt;br /&gt;
** Dockerfile&lt;br /&gt;
** compose.yaml&lt;br /&gt;
** requirements.txt&lt;br /&gt;
** app.py&lt;br /&gt;
** static/ directory&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use the complete deployment ZIP for a new installation. An update-only ZIP may not contain everything required.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Example Settings ==&lt;br /&gt;
&lt;br /&gt;
Replace these example values where necessary:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Example&lt;br /&gt;
|-&lt;br /&gt;
| Application directory || /opt/pdfextractorwebapp&lt;br /&gt;
|-&lt;br /&gt;
| Website address || pdf.example.com&lt;br /&gt;
|-&lt;br /&gt;
| Deployment archive || pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
|-&lt;br /&gt;
| Local application port || 8000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The project files reside in /opt/pdfextractorwebapp on the server. The application runs inside its Docker container.&lt;br /&gt;
&lt;br /&gt;
== 1. Upload the Application ==&lt;br /&gt;
&lt;br /&gt;
Upload the complete deployment ZIP to the new server&amp;#039;s /tmp/ directory using SCP, SFTP, or your preferred file-transfer application.&lt;br /&gt;
&lt;br /&gt;
== 2. Check Docker Compose ==&lt;br /&gt;
&lt;br /&gt;
Connect to the server using SSH, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker --version&lt;br /&gt;
sudo docker compose version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both commands should display version information.&lt;br /&gt;
&lt;br /&gt;
If the second command fails, install the Docker Compose plugin for your Docker installation before continuing.&lt;br /&gt;
&lt;br /&gt;
== 3. Extract the Application ==&lt;br /&gt;
&lt;br /&gt;
Install unzip and curl if needed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y unzip curl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the application directory and extract the archive:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo mkdir -p /opt/pdfextractorwebapp&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Confirm the project files are directly inside this directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ls -la&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dockerfile and compose.yaml should be visible.&lt;br /&gt;
&lt;br /&gt;
== 4. Build and Start the Container ==&lt;br /&gt;
&lt;br /&gt;
From the application directory, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first build downloads dependencies and may take several minutes.&lt;br /&gt;
&lt;br /&gt;
* --build builds the application image.&lt;br /&gt;
* -d runs the container in the background.&lt;br /&gt;
&lt;br /&gt;
Check the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its status should show &amp;#039;&amp;#039;&amp;#039;Up&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The supplied compose.yaml includes a restart policy so the application restarts after a server reboot, provided Docker starts automatically.&lt;br /&gt;
&lt;br /&gt;
Enable Docker at startup:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl enable --now docker&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Test the Application Directly ==&lt;br /&gt;
&lt;br /&gt;
Before configuring Apache, test the application locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected results:&lt;br /&gt;
&lt;br /&gt;
* The health endpoint returns {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
* The application page returns HTTP 200.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Do not continue until these checks pass.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To investigate a failure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The supplied configuration binds port 8000 to 127.0.0.1. Keep this setting so Apache handles public access.&lt;br /&gt;
&lt;br /&gt;
== 6. Configure Apache ==&lt;br /&gt;
&lt;br /&gt;
Enable the reverse-proxy modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2enmod proxy proxy_http&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create an Apache site configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/pdfextractor.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following, replacing pdf.example.com with your actual hostname:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pdf.example.com&lt;br /&gt;
&lt;br /&gt;
    ProxyRequests Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyTimeout 600&lt;br /&gt;
&lt;br /&gt;
    LimitRequestBody 53477376&lt;br /&gt;
&lt;br /&gt;
    ProxyPass &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot; connectiontimeout=5 timeout=600&lt;br /&gt;
    ProxyPassReverse &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/pdfextractor-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/pdfextractor-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The timeout accommodates longer PDF exports. The request-body limit accommodates the application&amp;#039;s default 50 MB upload limit plus metadata.&lt;br /&gt;
&lt;br /&gt;
If this hostname already has an Apache configuration, update that configuration instead of creating a competing virtual host.&lt;br /&gt;
&lt;br /&gt;
Enable the site and validate the configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite pdfextractor.conf&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the result is &amp;#039;&amp;#039;&amp;#039;Syntax OK&amp;#039;&amp;#039;&amp;#039;, reload Apache:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test Apache&amp;#039;s connection to the application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i -H &amp;quot;Host: pdf.example.com&amp;quot; http://127.0.0.1/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected result: HTTP 200 and {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
&lt;br /&gt;
== 7. Configure DNS and Firewall Access ==&lt;br /&gt;
&lt;br /&gt;
At your DNS provider:&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&amp;#039;s A record to the new server&amp;#039;s public IPv4 address.&lt;br /&gt;
# If an AAAA record exists, update it to the new server&amp;#039;s IPv6 address, or remove it if IPv6 is unused.&lt;br /&gt;
&lt;br /&gt;
Allow inbound TCP ports &amp;#039;&amp;#039;&amp;#039;80&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;443&amp;#039;&amp;#039;&amp;#039; through the server firewall and any hosting-provider firewall.&lt;br /&gt;
&lt;br /&gt;
If UFW is already active, allow Apache traffic:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo ufw allow &amp;#039;Apache Full&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not enable UFW without first ensuring SSH access is allowed.&lt;br /&gt;
&lt;br /&gt;
Port 8000 does not need public access.&lt;br /&gt;
&lt;br /&gt;
If migrating an existing hostname, keep the old server running while DNS changes propagate.&lt;br /&gt;
&lt;br /&gt;
== 8. Enable HTTPS ==&lt;br /&gt;
&lt;br /&gt;
==[[Setup_SSL]]==&lt;br /&gt;
&lt;br /&gt;
Ensure the HTTPS virtual host retains the ProxyPass and ProxyPassReverse settings, including timeout=600.&lt;br /&gt;
&lt;br /&gt;
== 9. Verify the Deployment ==&lt;br /&gt;
&lt;br /&gt;
Test the public HTTPS endpoint:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS https://pdf.example.com/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the website in a browser and verify:&lt;br /&gt;
&lt;br /&gt;
# The interface loads.&lt;br /&gt;
# A PDF can be uploaded.&lt;br /&gt;
# Page previews work.&lt;br /&gt;
# An export downloads successfully.&lt;br /&gt;
# Multiple PDFs can be processed together.&lt;br /&gt;
&lt;br /&gt;
== Updating the Application Later ==&lt;br /&gt;
&lt;br /&gt;
Upload the update ZIP to /tmp/, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/UPDATE-FILENAME.zip&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace UPDATE-FILENAME.zip with the actual archive name.&lt;br /&gt;
&lt;br /&gt;
Refresh the website after rebuilding.&lt;br /&gt;
&lt;br /&gt;
== Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
Run these commands from /opt/pdfextractorwebapp.&lt;br /&gt;
&lt;br /&gt;
=== View Container Status ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Recent Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Follow Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs -f pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Press Ctrl+C to stop following logs. This does not stop the container.&lt;br /&gt;
&lt;br /&gt;
=== Restart the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restarting does not apply source-code changes copied into the Docker image. Use a rebuild after updating application files.&lt;br /&gt;
&lt;br /&gt;
=== Rebuild After Changes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stop the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose stop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Apache Errors ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo tail -n 100 /var/log/apache2/pdfextractor-error.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Apache Displays a Proxy Error ===&lt;br /&gt;
&lt;br /&gt;
Check the application directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i --max-time 10 http://127.0.0.1:8000/health&lt;br /&gt;
curl -I --max-time 10 http://127.0.0.1:8000/&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the local application works, inspect the Apache configuration and error log.&lt;br /&gt;
&lt;br /&gt;
=== Permission Denied for Static Files ===&lt;br /&gt;
&lt;br /&gt;
If the container logs report PermissionError for /app/static/index.html, correct the source-file permissions and rebuild:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo chmod 755 static&lt;br /&gt;
sudo chmod 644 app.py static/index.html static/app.js static/style.css&lt;br /&gt;
&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corrected Dockerfile also normalizes these permissions during the build.&lt;br /&gt;
&lt;br /&gt;
=== Exports Time Out ===&lt;br /&gt;
&lt;br /&gt;
Confirm the active HTTPS virtual host includes timeout=600 on its ProxyPass directive.&lt;br /&gt;
&lt;br /&gt;
Validate and reload Apache after changing its configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For unusually large exports, try fewer pages or smaller batches.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.docker.com/reference/cli/docker/compose/up/ Docker Compose: build and start containers]&lt;br /&gt;
* [https://httpd.apache.org/docs/2.4/en/howto/reverse_proxy.html Apache reverse-proxy guide]&lt;br /&gt;
* [https://eff-certbot.readthedocs.io/en/stable/man/certbot.html Certbot documentation]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2994</id>
		<title>Docker Deploy App</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_Deploy_App&amp;diff=2994"/>
		<updated>2026-11-10T18:03:40Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: Created page with &amp;quot;= Deploy PDF Extractor to a New Server =  This guide deploys PDF Extractor using Docker Compose, with Apache providing HTTPS access.  == Requirements ==  * An Ubuntu server with Apache and Docker already installed. * SSH access with root or sudo privileges. * A domain or subdomain pointing to the new server. * The complete application deployment ZIP, including: ** Dockerfile ** compose.yaml ** requirements.txt ** app.py ** static/ directory  &amp;#039;&amp;#039;&amp;#039;Use the complete deploymen...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Deploy PDF Extractor to a New Server =&lt;br /&gt;
&lt;br /&gt;
This guide deploys PDF Extractor using Docker Compose, with Apache providing HTTPS access.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* An Ubuntu server with Apache and Docker already installed.&lt;br /&gt;
* SSH access with root or sudo privileges.&lt;br /&gt;
* A domain or subdomain pointing to the new server.&lt;br /&gt;
* The complete application deployment ZIP, including:&lt;br /&gt;
** Dockerfile&lt;br /&gt;
** compose.yaml&lt;br /&gt;
** requirements.txt&lt;br /&gt;
** app.py&lt;br /&gt;
** static/ directory&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use the complete deployment ZIP for a new installation. An update-only ZIP may not contain everything required.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Example Settings ==&lt;br /&gt;
&lt;br /&gt;
Replace these example values where necessary:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Example&lt;br /&gt;
|-&lt;br /&gt;
| Application directory || /opt/pdfextractorwebapp&lt;br /&gt;
|-&lt;br /&gt;
| Website address || pdf.example.com&lt;br /&gt;
|-&lt;br /&gt;
| Deployment archive || pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
|-&lt;br /&gt;
| Local application port || 8000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The project files reside in /opt/pdfextractorwebapp on the server. The application runs inside its Docker container.&lt;br /&gt;
&lt;br /&gt;
== 1. Upload the Application ==&lt;br /&gt;
&lt;br /&gt;
Upload the complete deployment ZIP to the new server&amp;#039;s /tmp/ directory using SCP, SFTP, or your preferred file-transfer application.&lt;br /&gt;
&lt;br /&gt;
== 2. Check Docker Compose ==&lt;br /&gt;
&lt;br /&gt;
Connect to the server using SSH, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker --version&lt;br /&gt;
sudo docker compose version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both commands should display version information.&lt;br /&gt;
&lt;br /&gt;
If the second command fails, install the Docker Compose plugin for your Docker installation before continuing.&lt;br /&gt;
&lt;br /&gt;
== 3. Extract the Application ==&lt;br /&gt;
&lt;br /&gt;
Install unzip and curl if needed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y unzip curl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the application directory and extract the archive:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo mkdir -p /opt/pdfextractorwebapp&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/pdf-extractor-web-full-deploy-2026-11-10.zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Confirm the project files are directly inside this directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ls -la&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dockerfile and compose.yaml should be visible.&lt;br /&gt;
&lt;br /&gt;
== 4. Build and Start the Container ==&lt;br /&gt;
&lt;br /&gt;
From the application directory, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first build downloads dependencies and may take several minutes.&lt;br /&gt;
&lt;br /&gt;
* --build builds the application image.&lt;br /&gt;
* -d runs the container in the background.&lt;br /&gt;
&lt;br /&gt;
Check the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its status should show &amp;#039;&amp;#039;&amp;#039;Up&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The supplied compose.yaml includes a restart policy so the application restarts after a server reboot, provided Docker starts automatically.&lt;br /&gt;
&lt;br /&gt;
Enable Docker at startup:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl enable --now docker&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Test the Application Directly ==&lt;br /&gt;
&lt;br /&gt;
Before configuring Apache, test the application locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected results:&lt;br /&gt;
&lt;br /&gt;
* The health endpoint returns {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
* The application page returns HTTP 200.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Do not continue until these checks pass.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To investigate a failure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The supplied configuration binds port 8000 to 127.0.0.1. Keep this setting so Apache handles public access.&lt;br /&gt;
&lt;br /&gt;
== 6. Configure Apache ==&lt;br /&gt;
&lt;br /&gt;
Enable the reverse-proxy modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2enmod proxy proxy_http&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create an Apache site configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/pdfextractor.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following, replacing pdf.example.com with your actual hostname:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName pdf.example.com&lt;br /&gt;
&lt;br /&gt;
    ProxyRequests Off&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyTimeout 600&lt;br /&gt;
&lt;br /&gt;
    LimitRequestBody 53477376&lt;br /&gt;
&lt;br /&gt;
    ProxyPass &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot; connectiontimeout=5 timeout=600&lt;br /&gt;
    ProxyPassReverse &amp;quot;/&amp;quot; &amp;quot;http://127.0.0.1:8000/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/pdfextractor-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/pdfextractor-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The timeout accommodates longer PDF exports. The request-body limit accommodates the application&amp;#039;s default 50 MB upload limit plus metadata.&lt;br /&gt;
&lt;br /&gt;
If this hostname already has an Apache configuration, update that configuration instead of creating a competing virtual host.&lt;br /&gt;
&lt;br /&gt;
Enable the site and validate the configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite pdfextractor.conf&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the result is &amp;#039;&amp;#039;&amp;#039;Syntax OK&amp;#039;&amp;#039;&amp;#039;, reload Apache:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test Apache&amp;#039;s connection to the application:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i -H &amp;quot;Host: pdf.example.com&amp;quot; http://127.0.0.1/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected result: HTTP 200 and {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}.&lt;br /&gt;
&lt;br /&gt;
== 7. Configure DNS and Firewall Access ==&lt;br /&gt;
&lt;br /&gt;
At your DNS provider:&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&amp;#039;s A record to the new server&amp;#039;s public IPv4 address.&lt;br /&gt;
# If an AAAA record exists, update it to the new server&amp;#039;s IPv6 address, or remove it if IPv6 is unused.&lt;br /&gt;
&lt;br /&gt;
Allow inbound TCP ports &amp;#039;&amp;#039;&amp;#039;80&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;443&amp;#039;&amp;#039;&amp;#039; through the server firewall and any hosting-provider firewall.&lt;br /&gt;
&lt;br /&gt;
If UFW is already active, allow Apache traffic:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo ufw allow &amp;#039;Apache Full&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not enable UFW without first ensuring SSH access is allowed.&lt;br /&gt;
&lt;br /&gt;
Port 8000 does not need public access.&lt;br /&gt;
&lt;br /&gt;
If migrating an existing hostname, keep the old server running while DNS changes propagate.&lt;br /&gt;
&lt;br /&gt;
== 8. Enable HTTPS ==&lt;br /&gt;
&lt;br /&gt;
After DNS points to the new server, install Certbot and its Apache plugin if needed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install -y certbot python3-certbot-apache&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obtain a certificate and enable redirection to HTTPS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo certbot --apache -d pdf.example.com --redirect&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Follow the prompts.&lt;br /&gt;
&lt;br /&gt;
Check the configuration and certificate renewal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo certbot renew --dry-run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure the HTTPS virtual host retains the ProxyPass and ProxyPassReverse settings, including timeout=600.&lt;br /&gt;
&lt;br /&gt;
== 9. Verify the Deployment ==&lt;br /&gt;
&lt;br /&gt;
Test the public HTTPS endpoint:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -fsS https://pdf.example.com/health&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the website in a browser and verify:&lt;br /&gt;
&lt;br /&gt;
# The interface loads.&lt;br /&gt;
# A PDF can be uploaded.&lt;br /&gt;
# Page previews work.&lt;br /&gt;
# An export downloads successfully.&lt;br /&gt;
# Multiple PDFs can be processed together.&lt;br /&gt;
&lt;br /&gt;
== Updating the Application Later ==&lt;br /&gt;
&lt;br /&gt;
Upload the update ZIP to /tmp/, then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo unzip -o /tmp/UPDATE-FILENAME.zip&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&lt;br /&gt;
curl -fsS http://127.0.0.1:8000/health&lt;br /&gt;
curl -I http://127.0.0.1:8000/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace UPDATE-FILENAME.zip with the actual archive name.&lt;br /&gt;
&lt;br /&gt;
Refresh the website after rebuilding.&lt;br /&gt;
&lt;br /&gt;
== Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
Run these commands from /opt/pdfextractorwebapp.&lt;br /&gt;
&lt;br /&gt;
=== View Container Status ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose ps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Recent Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Follow Application Logs ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose logs -f pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Press Ctrl+C to stop following logs. This does not stop the container.&lt;br /&gt;
&lt;br /&gt;
=== Restart the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restarting does not apply source-code changes copied into the Docker image. Use a rebuild after updating application files.&lt;br /&gt;
&lt;br /&gt;
=== Rebuild After Changes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stop the Application ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo docker compose stop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== View Apache Errors ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo tail -n 100 /var/log/apache2/pdfextractor-error.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Apache Displays a Proxy Error ===&lt;br /&gt;
&lt;br /&gt;
Check the application directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -i --max-time 10 http://127.0.0.1:8000/health&lt;br /&gt;
curl -I --max-time 10 http://127.0.0.1:8000/&lt;br /&gt;
sudo docker compose logs --tail=100 pdf-extractor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the local application works, inspect the Apache configuration and error log.&lt;br /&gt;
&lt;br /&gt;
=== Permission Denied for Static Files ===&lt;br /&gt;
&lt;br /&gt;
If the container logs report PermissionError for /app/static/index.html, correct the source-file permissions and rebuild:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /opt/pdfextractorwebapp&lt;br /&gt;
&lt;br /&gt;
sudo chmod 755 static&lt;br /&gt;
sudo chmod 644 app.py static/index.html static/app.js static/style.css&lt;br /&gt;
&lt;br /&gt;
sudo docker compose up -d --build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corrected Dockerfile also normalizes these permissions during the build.&lt;br /&gt;
&lt;br /&gt;
=== Exports Time Out ===&lt;br /&gt;
&lt;br /&gt;
Confirm the active HTTPS virtual host includes timeout=600 on its ProxyPass directive.&lt;br /&gt;
&lt;br /&gt;
Validate and reload Apache after changing its configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For unusually large exports, try fewer pages or smaller batches.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.docker.com/reference/cli/docker/compose/up/ Docker Compose: build and start containers]&lt;br /&gt;
* [https://httpd.apache.org/docs/2.4/en/howto/reverse_proxy.html Apache reverse-proxy guide]&lt;br /&gt;
* [https://eff-certbot.readthedocs.io/en/stable/man/certbot.html Certbot documentation]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker&amp;diff=2993</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker&amp;diff=2993"/>
		<updated>2026-11-10T18:00:09Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Docker on Raspberry Pi]]==&lt;br /&gt;
==[[Docker tutorial]]==&lt;br /&gt;
==[[Docker Deploy App]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2992</id>
		<title>INSTALL PHYMYADMIN</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2992"/>
		<updated>2026-11-10T17:03:14Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Installing phpMyAdmin on Ubuntu Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing phpMyAdmin on Ubuntu Server ==&lt;br /&gt;
&lt;br /&gt;
==== 1. Install the packages ====&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install -y phpmyadmin php-mbstring php-zip php-gd php-json php-curl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 2. Answer the installer prompts ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Prompt !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Web server to configure || Press &amp;#039;&amp;#039;&amp;#039;Space&amp;#039;&amp;#039;&amp;#039; to select &amp;#039;&amp;#039;&amp;#039;apache2&amp;#039;&amp;#039;&amp;#039;, then Tab and Enter&lt;br /&gt;
|-&lt;br /&gt;
| Configure database with dbconfig-common || Choose &amp;#039;&amp;#039;&amp;#039;Yes&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Password for the phpmyadmin user || Set a password, or leave blank for a random one&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Note|If you skip selecting apache2, phpMyAdmin will not be wired into Apache.}}&lt;br /&gt;
&lt;br /&gt;
==== 3. Enable mbstring and restart Apache ====&lt;br /&gt;
&lt;br /&gt;
 sudo phpenmod mbstring&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
phpMyAdmin is now available at &amp;lt;code&amp;gt;http://your-server-ip/phpmyadmin&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Creating an admin user ===&lt;br /&gt;
On Ubuntu, MySQL&amp;#039;s root account uses socket authentication, so logging in as root with a password through phpMyAdmin will fail. Create a dedicated admin user instead:&lt;br /&gt;
&lt;br /&gt;
 sudo mysql&lt;br /&gt;
&lt;br /&gt;
 CREATE USER &amp;#039;pmaadmin&amp;#039;@&amp;#039;localhost&amp;#039; IDENTIFIED BY &amp;#039;a-strong-password&amp;#039;;&lt;br /&gt;
 GRANT ALL PRIVILEGES ON *.* TO &amp;#039;pmaadmin&amp;#039;@&amp;#039;localhost&amp;#039; WITH GRANT OPTION;&lt;br /&gt;
 FLUSH PRIVILEGES;&lt;br /&gt;
 EXIT;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log in to phpMyAdmin as &amp;lt;code&amp;gt;pmaadmin&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Security hardening ===&lt;br /&gt;
phpMyAdmin is a frequent target for bots. If the server is reachable from the internet, apply the following.&lt;br /&gt;
&lt;br /&gt;
==== Restrict access by IP ====&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/apache2/conf-available/phpmyadmin.conf&amp;lt;/code&amp;gt; and add this inside the &amp;lt;code&amp;gt;&amp;amp;lt;Directory /usr/share/phpmyadmin&amp;amp;gt;&amp;lt;/code&amp;gt; block:&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2991</id>
		<title>INSTALL PHYMYADMIN</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2991"/>
		<updated>2026-11-10T17:02:01Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Installing phpMyAdmin on Ubuntu Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing phpMyAdmin on Ubuntu Server ==&lt;br /&gt;
&lt;br /&gt;
==== 1. Install the packages ====&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install -y phpmyadmin php-mbstring php-zip php-gd php-json php-curl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 2. Answer the installer prompts ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Prompt !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Web server to configure || Press &amp;#039;&amp;#039;&amp;#039;Space&amp;#039;&amp;#039;&amp;#039; to select &amp;#039;&amp;#039;&amp;#039;apache2&amp;#039;&amp;#039;&amp;#039;, then Tab and Enter&lt;br /&gt;
|-&lt;br /&gt;
| Configure database with dbconfig-common || Choose &amp;#039;&amp;#039;&amp;#039;Yes&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Password for the phpmyadmin user || Set a password, or leave blank for a random one&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Note|If you skip selecting apache2, phpMyAdmin will not be wired into Apache.}}&lt;br /&gt;
&lt;br /&gt;
==== 3. Enable mbstring and restart Apache ====&lt;br /&gt;
&lt;br /&gt;
 sudo phpenmod mbstring&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
phpMyAdmin is now available at &amp;lt;code&amp;gt;http://your-server-ip/phpmyadmin&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Creating an admin user ===&lt;br /&gt;
On Ubuntu, MySQL&amp;#039;s root account uses socket authentication, so logging in as root with a password through phpMyAdmin will fail. Create a dedicated admin user instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mysql&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE USER &amp;#039;pmaadmin&amp;#039;@&amp;#039;localhost&amp;#039; IDENTIFIED BY &amp;#039;a-strong-password&amp;#039;;&lt;br /&gt;
GRANT ALL PRIVILEGES ON *.* TO &amp;#039;pmaadmin&amp;#039;@&amp;#039;localhost&amp;#039; WITH GRANT OPTION;&lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
EXIT;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log in to phpMyAdmin as &amp;lt;code&amp;gt;pmaadmin&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Security hardening ===&lt;br /&gt;
phpMyAdmin is a frequent target for bots. If the server is reachable from the internet, apply the following.&lt;br /&gt;
&lt;br /&gt;
==== Restrict access by IP ====&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/apache2/conf-available/phpmyadmin.conf&amp;lt;/code&amp;gt; and add this inside the &amp;lt;code&amp;gt;&amp;amp;lt;Directory /usr/share/phpmyadmin&amp;amp;gt;&amp;lt;/code&amp;gt; block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2990</id>
		<title>INSTALL PHYMYADMIN</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2990"/>
		<updated>2026-11-10T17:00:20Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing phpMyAdmin on Ubuntu Server ==&lt;br /&gt;
&lt;br /&gt;
This guide assumes a working LAMP stack (Apache, MySQL, PHP) is already installed.&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Ubuntu Server with Apache2, MySQL, and PHP installed&lt;br /&gt;
* A user with &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; privileges&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
&lt;br /&gt;
==== 1. Install the packages ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y phpmyadmin php-mbstring php-zip php-gd php-json php-curl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 2. Answer the installer prompts ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Prompt !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Web server to configure || Press &amp;#039;&amp;#039;&amp;#039;Space&amp;#039;&amp;#039;&amp;#039; to select &amp;#039;&amp;#039;&amp;#039;apache2&amp;#039;&amp;#039;&amp;#039;, then Tab and Enter&lt;br /&gt;
|-&lt;br /&gt;
| Configure database with dbconfig-common || Choose &amp;#039;&amp;#039;&amp;#039;Yes&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Password for the phpmyadmin user || Set a password, or leave blank for a random one&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Note|If you skip selecting apache2, phpMyAdmin will not be wired into Apache.}}&lt;br /&gt;
&lt;br /&gt;
==== 3. Enable mbstring and restart Apache ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo phpenmod mbstring&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
phpMyAdmin is now available at &amp;lt;code&amp;gt;http://your-server-ip/phpmyadmin&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Creating an admin user ===&lt;br /&gt;
On Ubuntu, MySQL&amp;#039;s root account uses socket authentication, so logging in as root with a password through phpMyAdmin will fail. Create a dedicated admin user instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mysql&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE USER &amp;#039;pmaadmin&amp;#039;@&amp;#039;localhost&amp;#039; IDENTIFIED BY &amp;#039;a-strong-password&amp;#039;;&lt;br /&gt;
GRANT ALL PRIVILEGES ON *.* TO &amp;#039;pmaadmin&amp;#039;@&amp;#039;localhost&amp;#039; WITH GRANT OPTION;&lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
EXIT;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Log in to phpMyAdmin as &amp;lt;code&amp;gt;pmaadmin&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Security hardening ===&lt;br /&gt;
phpMyAdmin is a frequent target for bots. If the server is reachable from the internet, apply the following.&lt;br /&gt;
&lt;br /&gt;
==== Restrict access by IP ====&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/apache2/conf-available/phpmyadmin.conf&amp;lt;/code&amp;gt; and add this inside the &amp;lt;code&amp;gt;&amp;amp;lt;Directory /usr/share/phpmyadmin&amp;amp;gt;&amp;lt;/code&amp;gt; block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2989</id>
		<title>INSTALL PHYMYADMIN</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=INSTALL_PHYMYADMIN&amp;diff=2989"/>
		<updated>2026-11-10T16:39:57Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: Created page with &amp;quot; sudo apt update  sudo apt install -y phpmyadmin php-mbstring php-zip php-gd php-json php-curl&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; sudo apt update&lt;br /&gt;
 sudo apt install -y phpmyadmin php-mbstring php-zip php-gd php-json php-curl&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Mysql&amp;diff=2988</id>
		<title>Mysql</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Mysql&amp;diff=2988"/>
		<updated>2026-11-10T16:39:27Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=[[DADABIK]]=&lt;br /&gt;
=[[MYSQL COMMANDS]]=&lt;br /&gt;
=[[INSTALL PHYMYADMIN]]=&lt;br /&gt;
=[[MYSQL DATABASE RESTORE]]=&lt;br /&gt;
=[[MYSQL DATABASE BACKUP]]=&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2987</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2987"/>
		<updated>2026-11-05T17:40:36Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;apt might report that you have none of these packages installed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Images, containers, volumes, and networks stored in /var/lib/docker/ aren&amp;#039;t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section [https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine].&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Install using the apt repository===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker apt repository. Afterward, you can install and update Docker from the repository.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Add Docker&amp;#039;s official GPG key:&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install ca-certificates curl&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Add the repository to Apt sources:&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Install the Docker packages.===&lt;br /&gt;
 sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
===After installation, verify that Docker is running:===&lt;br /&gt;
 sudo systemctl status docker&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If Docker is not running, start it manually:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo systemctl start docker&lt;br /&gt;
&lt;br /&gt;
===Verify that the installation is successful by running the hello-world image:===&lt;br /&gt;
&lt;br /&gt;
sudo docker run hello-world&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2986</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2986"/>
		<updated>2026-11-05T17:37:13Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;apt might report that you have none of these packages installed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Images, containers, volumes, and networks stored in /var/lib/docker/ aren&amp;#039;t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section [https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine].&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Install using the apt repository===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker apt repository. Afterward, you can install and update Docker from the repository.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Add Docker&amp;#039;s official GPG key:&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install ca-certificates curl&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Add the repository to Apt sources:&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2985</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2985"/>
		<updated>2026-11-05T17:36:29Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;apt might report that you have none of these packages installed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Images, containers, volumes, and networks stored in /var/lib/docker/ aren&amp;#039;t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section [https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine].&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Install using the apt repository===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker apt repository. Afterward, you can install and update Docker from the repository.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
# Add Docker&amp;#039;s official GPG key:&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install ca-certificates curl&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Add the repository to Apt sources:&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2984</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2984"/>
		<updated>2026-11-05T17:35:52Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;apt might report that you have none of these packages installed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Images, containers, volumes, and networks stored in /var/lib/docker/ aren&amp;#039;t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section [https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine].&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Install using the apt repository===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker apt repository. Afterward, you can install and update Docker from the repository.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2983</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2983"/>
		<updated>2026-11-05T17:34:34Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;apt might report that you have none of these packages installed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Images, containers, volumes, and networks stored in /var/lib/docker/ aren&amp;#039;t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section [https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine].&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2982</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2982"/>
		<updated>2026-11-05T17:31:45Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;apt might report that you have none of these packages installed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Images, containers, volumes, and networks stored in /var/lib/docker/ aren&amp;#039;t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2981</id>
		<title>Docker tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Docker_tutorial&amp;diff=2981"/>
		<updated>2026-11-05T17:30:51Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Installing Docker on Ubuntu ===&lt;br /&gt;
=== Uninstall old version first===&lt;br /&gt;
&lt;br /&gt;
 sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)&lt;br /&gt;
&lt;br /&gt;
==[[Docker]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Tailscale&amp;diff=2980</id>
		<title>Tailscale</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Tailscale&amp;diff=2980"/>
		<updated>2026-10-16T18:57:02Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Updating Tailscale on Synology Nas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Enable Routing on synology to access local printers==&lt;br /&gt;
* SSH into synology&lt;br /&gt;
 sudo tailscale up --advertise-routes=192.168.20.0/24 --reset&lt;br /&gt;
* in tailscale admin&lt;br /&gt;
** Right click on 3 dots &lt;br /&gt;
** Edit Route Settings&lt;br /&gt;
** Turn on node&lt;br /&gt;
** Right click on 3 dots again&lt;br /&gt;
** Disable key expiration&lt;br /&gt;
&lt;br /&gt;
==Resetting back node to default==&lt;br /&gt;
 sudo tailscale up --reset&lt;br /&gt;
&lt;br /&gt;
* Tailscale admin&lt;br /&gt;
** Reverse previous settings&lt;br /&gt;
&lt;br /&gt;
== Updating Tailscale on Synology Nas ==&lt;br /&gt;
1. Create a scheduled task on each NAS: Create → Scheduled Task → User-defined script&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User: root&lt;br /&gt;
Schedule: weekly, at a quiet time&lt;br /&gt;
Run command:&lt;br /&gt;
&lt;br /&gt;
TS=/var/packages/Tailscale/target/bin/tailscale&lt;br /&gt;
$TS version&lt;br /&gt;
$TS update --yes&lt;br /&gt;
sleep 30&lt;br /&gt;
$TS configure synology&lt;br /&gt;
synosystemctl restart pkgctl-Tailscale.service&lt;br /&gt;
sleep 20&lt;br /&gt;
$TS version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
2. Run it once by hand and check the output file. The second version number should be newer than 1.58.2.&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Tailscale&amp;diff=2979</id>
		<title>Tailscale</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Tailscale&amp;diff=2979"/>
		<updated>2026-10-16T18:56:06Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Enable Routing on synology to access local printers==&lt;br /&gt;
* SSH into synology&lt;br /&gt;
 sudo tailscale up --advertise-routes=192.168.20.0/24 --reset&lt;br /&gt;
* in tailscale admin&lt;br /&gt;
** Right click on 3 dots &lt;br /&gt;
** Edit Route Settings&lt;br /&gt;
** Turn on node&lt;br /&gt;
** Right click on 3 dots again&lt;br /&gt;
** Disable key expiration&lt;br /&gt;
&lt;br /&gt;
==Resetting back node to default==&lt;br /&gt;
 sudo tailscale up --reset&lt;br /&gt;
&lt;br /&gt;
* Tailscale admin&lt;br /&gt;
** Reverse previous settings&lt;br /&gt;
&lt;br /&gt;
== Updating Tailscale on Synology Nas ==&lt;br /&gt;
1. Create a scheduled task on each NAS: Create → Scheduled Task → User-defined script&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User: root&lt;br /&gt;
Schedule: weekly, at a quiet time&lt;br /&gt;
Run command:&lt;br /&gt;
&lt;br /&gt;
TS=/var/packages/Tailscale/target/bin/tailscale&lt;br /&gt;
$TS version&lt;br /&gt;
$TS update --yes&lt;br /&gt;
sleep 30&lt;br /&gt;
$TS configure synology&lt;br /&gt;
synosystemctl restart pkgctl-Tailscale.service&lt;br /&gt;
sleep 20&lt;br /&gt;
$TS version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=RecipeApp&amp;diff=2978</id>
		<title>RecipeApp</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=RecipeApp&amp;diff=2978"/>
		<updated>2026-06-10T19:45:24Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Recipe App ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1. Install Packages &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install apache2 sqlite3 libsqlite3-dev libapache2-mod-php php-sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If your Apache uses a specific PHP version, install SQLite for that version. Check Apache PHP:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl -M | grep -i php&lt;br /&gt;
ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Example: if Apache uses PHP 8.1:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install php8.1-sqlite3&lt;br /&gt;
sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Verify SQLite support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
php -m | grep -i sqlite&lt;br /&gt;
ls -la /etc/php/*/apache2/conf.d/ | grep sqlite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; You should see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pdo_sqlite&lt;br /&gt;
sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; 2. Copy App Files&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example location:3. Set Permissions&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Apache must write to SQLite and image upload folders:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p data uploads/recipes&lt;br /&gt;
sudo chown -R www-data:www-data data uploads&lt;br /&gt;
sudo chmod -R 775 data uploads&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Do not make the whole app writable unless needed. Only data/ and uploads/ need write access.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;4. Apache Virtual Host&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a site config:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/mysite.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName mysite.com&lt;br /&gt;
    ServerAlias www.mysite.com&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /var/www/html/mysite&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/html/mysite&amp;gt;&lt;br /&gt;
        Options -Indexes +FollowSymLinks&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/mysite-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/mysite-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable the site: &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite mysite.conf&lt;br /&gt;
sudo a2enmod rewrite&lt;br /&gt;
sudo apachectl configtest&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If config test says Syntax OK, Apache is good.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;5. Test App From Server&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;From the app folder: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/mysite&lt;br /&gt;
&lt;br /&gt;
php -l index.php&lt;br /&gt;
php -l lib/Database.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;7. Optional HTTPS&lt;br /&gt;
Install Certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache&lt;br /&gt;
&lt;br /&gt;
Issue certificate:&lt;br /&gt;
&lt;br /&gt;
 sudo certbot --apache -d mysite.com -d www.mysite.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Then test:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apachectl configtest&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;8. Common Troubleshooting&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check Apache/PHP errors:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/mysite-error.log&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Watch live while refreshing the browser:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -f /var/log/apache2/mysite-error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PDOException: could not find driver&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install SQLite for Apache’s active PHP version:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
 sudo apt install php8.1-sqlite3&lt;br /&gt;
 sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see permission errors for SQLite or uploads:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo chown -R www-data:www-data /var/www/html/mysite/data /var/www/html/mysite/uploads&lt;br /&gt;
 sudo chmod -R 775 /var/www/html/mysite/data /var/www/html/mysite/uploads&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Back up these folders/files:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 /var/www/html/mysite/data/cocktails.sqlite&lt;br /&gt;
 /var/www/html/mysite/uploads/&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Those contain your saved recipes and uploaded images.&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=RecipeApp&amp;diff=2977</id>
		<title>RecipeApp</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=RecipeApp&amp;diff=2977"/>
		<updated>2026-06-10T19:43:24Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Recipe App ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1. Install Packages &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install apache2 sqlite3 libsqlite3-dev libapache2-mod-php php-sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If your Apache uses a specific PHP version, install SQLite for that version. Check Apache PHP:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl -M | grep -i php&lt;br /&gt;
ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Example: if Apache uses PHP 8.1:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install php8.1-sqlite3&lt;br /&gt;
sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Verify SQLite support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
php -m | grep -i sqlite&lt;br /&gt;
ls -la /etc/php/*/apache2/conf.d/ | grep sqlite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; You should see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pdo_sqlite&lt;br /&gt;
sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; 2. Copy App Files&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example location:3. Set Permissions&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Apache must write to SQLite and image upload folders:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p data uploads/recipes&lt;br /&gt;
sudo chown -R www-data:www-data data uploads&lt;br /&gt;
sudo chmod -R 775 data uploads&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Do not make the whole app writable unless needed. Only data/ and uploads/ need write access.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;4. Apache Virtual Host&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a site config:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/11square.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName 11square.com&lt;br /&gt;
    ServerAlias www.11square.com&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/html/11square&amp;gt;&lt;br /&gt;
        Options -Indexes +FollowSymLinks&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/11square-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/11square-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable the site: &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite 11square.conf&lt;br /&gt;
sudo a2enmod rewrite&lt;br /&gt;
sudo apachectl configtest&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If config test says Syntax OK, Apache is good.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;5. Test App From Server&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;From the app folder: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
php -l index.php&lt;br /&gt;
php -l lib/Database.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;7. Optional HTTPS&lt;br /&gt;
Install Certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache&lt;br /&gt;
&lt;br /&gt;
Issue certificate:&lt;br /&gt;
&lt;br /&gt;
 sudo certbot --apache -d 11square.com -d www.11square.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Then test:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apachectl configtest&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;8. Common Troubleshooting&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check Apache/PHP errors:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/11square-error.log&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Watch live while refreshing the browser:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -f /var/log/apache2/11square-error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PDOException: could not find driver&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install SQLite for Apache’s active PHP version:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
 sudo apt install php8.1-sqlite3&lt;br /&gt;
 sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see permission errors for SQLite or uploads:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo chown -R www-data:www-data /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
 sudo chmod -R 775 /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Back up these folders/files:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 /var/www/html/11square/data/cocktails.sqlite&lt;br /&gt;
 /var/www/html/11square/uploads/&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Those contain your saved recipes and uploaded images.&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=RecipeApp&amp;diff=2976</id>
		<title>RecipeApp</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=RecipeApp&amp;diff=2976"/>
		<updated>2026-06-10T19:42:20Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Recipe App ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1. Install Packages &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install apache2 sqlite3 libsqlite3-dev libapache2-mod-php php-sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If your Apache uses a specific PHP version, install SQLite for that version. Check Apache PHP:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl -M | grep -i php&lt;br /&gt;
ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Example: if Apache uses PHP 8.1:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install php8.1-sqlite3&lt;br /&gt;
sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Verify SQLite support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
php -m | grep -i sqlite&lt;br /&gt;
ls -la /etc/php/*/apache2/conf.d/ | grep sqlite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; You should see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pdo_sqlite&lt;br /&gt;
sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; 2. Copy App Files&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example location:3. Set Permissions&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Apache must write to SQLite and image upload folders:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p data uploads/recipes&lt;br /&gt;
sudo chown -R www-data:www-data data uploads&lt;br /&gt;
sudo chmod -R 775 data uploads&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Do not make the whole app writable unless needed. Only data/ and uploads/ need write access.&lt;br /&gt;
4. Apache Virtual Host&lt;br /&gt;
Create a site config:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/11square.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName 11square.com&lt;br /&gt;
    ServerAlias www.11square.com&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/html/11square&amp;gt;&lt;br /&gt;
        Options -Indexes +FollowSymLinks&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/11square-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/11square-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;Enable the site: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite 11square.conf&lt;br /&gt;
sudo a2enmod rewrite&lt;br /&gt;
sudo apachectl configtest&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;If config test says Syntax OK, Apache is good.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;5. Test App From Server&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;From the app folder: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
php -l index.php&lt;br /&gt;
php -l lib/Database.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;7. Optional HTTPS&lt;br /&gt;
Install Certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache&lt;br /&gt;
&lt;br /&gt;
Issue certificate:&lt;br /&gt;
&lt;br /&gt;
 sudo certbot --apache -d 11square.com -d www.11square.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Then test:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apachectl configtest&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;8. Common Troubleshooting&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check Apache/PHP errors:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/11square-error.log&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Watch live while refreshing the browser:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -f /var/log/apache2/11square-error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PDOException: could not find driver&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install SQLite for Apache’s active PHP version:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
 sudo apt install php8.1-sqlite3&lt;br /&gt;
 sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see permission errors for SQLite or uploads:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo chown -R www-data:www-data /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
 sudo chmod -R 775 /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Back up these folders/files:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 /var/www/html/11square/data/cocktails.sqlite&lt;br /&gt;
 /var/www/html/11square/uploads/&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Those contain your saved recipes and uploaded images.&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=RecipeApp&amp;diff=2975</id>
		<title>RecipeApp</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=RecipeApp&amp;diff=2975"/>
		<updated>2026-06-10T19:41:12Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Recipe App ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;1. Install Packages &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install apache2 sqlite3 libsqlite3-dev libapache2-mod-php php-sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;If your Apache uses a specific PHP version, install SQLite for that version. Check Apache PHP:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl -M | grep -i php&lt;br /&gt;
ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; Example: if Apache uses PHP 8.1:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install php8.1-sqlite3&lt;br /&gt;
sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; Verify SQLite support:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
php -m | grep -i sqlite&lt;br /&gt;
ls -la /etc/php/*/apache2/conf.d/ | grep sqlite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; You should see:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pdo_sqlite&lt;br /&gt;
sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; 2. Copy App Files&lt;br /&gt;
Example location:3. Set Permissions&lt;br /&gt;
Apache must write to SQLite and image upload folders:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p data uploads/recipes&lt;br /&gt;
sudo chown -R www-data:www-data data uploads&lt;br /&gt;
sudo chmod -R 775 data uploads&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; Do not make the whole app writable unless needed. Only data/ and uploads/ need write access.&lt;br /&gt;
4. Apache Virtual Host&lt;br /&gt;
Create a site config:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/11square.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName 11square.com&lt;br /&gt;
    ServerAlias www.11square.com&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/html/11square&amp;gt;&lt;br /&gt;
        Options -Indexes +FollowSymLinks&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/11square-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/11square-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;Enable the site: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite 11square.conf&lt;br /&gt;
sudo a2enmod rewrite&lt;br /&gt;
sudo apachectl configtest&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;If config test says Syntax OK, Apache is good.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;5. Test App From Server&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;From the app folder: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
php -l index.php&lt;br /&gt;
php -l lib/Database.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;7. Optional HTTPS&lt;br /&gt;
Install Certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache&lt;br /&gt;
&lt;br /&gt;
Issue certificate:&lt;br /&gt;
&lt;br /&gt;
 sudo certbot --apache -d 11square.com -d www.11square.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Then test:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apachectl configtest&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;8. Common Troubleshooting&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check Apache/PHP errors:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/11square-error.log&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Watch live while refreshing the browser:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -f /var/log/apache2/11square-error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PDOException: could not find driver&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install SQLite for Apache’s active PHP version:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
 sudo apt install php8.1-sqlite3&lt;br /&gt;
 sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see permission errors for SQLite or uploads:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo chown -R www-data:www-data /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
 sudo chmod -R 775 /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Back up these folders/files:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 /var/www/html/11square/data/cocktails.sqlite&lt;br /&gt;
 /var/www/html/11square/uploads/&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Those contain your saved recipes and uploaded images.&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=RecipeApp&amp;diff=2974</id>
		<title>RecipeApp</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=RecipeApp&amp;diff=2974"/>
		<updated>2026-06-10T19:18:30Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: Created page with &amp;quot;== Recipe App ==  &amp;#039;&amp;#039;&amp;#039;&amp;#039;1. Install Packages &amp;#039;&amp;#039;&amp;#039;&amp;#039;  &amp;lt;pre&amp;gt; sudo apt update  sudo apt install apache2 sqlite3 libsqlite3-dev libapache2-mod-php php-sqlite3 &amp;lt;/pre&amp;gt;  &amp;#039;&amp;#039;&amp;#039;&amp;#039;If your Apache uses a specific PHP version, install SQLite for that version. Check Apache PHP:&amp;#039;&amp;#039;&amp;#039;&amp;#039;  &amp;lt;pre&amp;gt; apachectl -M | grep -i php ls -la /etc/apache2/mods-enabled/php*.load &amp;lt;/pre&amp;gt;  &amp;#039;&amp;#039;&amp;#039;&amp;#039; Example: if Apache uses PHP 8.1:&amp;#039;&amp;#039;&amp;#039;&amp;#039;  &amp;lt;pre&amp;gt; sudo apt install php8.1-sqlite3 sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlit...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Recipe App ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;1. Install Packages &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
sudo apt install apache2 sqlite3 libsqlite3-dev libapache2-mod-php php-sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;If your Apache uses a specific PHP version, install SQLite for that version. Check Apache PHP:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl -M | grep -i php&lt;br /&gt;
ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; Example: if Apache uses PHP 8.1:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install php8.1-sqlite3&lt;br /&gt;
sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; Verify SQLite support:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
php -m | grep -i sqlite&lt;br /&gt;
ls -la /etc/php/*/apache2/conf.d/ | grep sqlite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; You should see:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pdo_sqlite&lt;br /&gt;
sqlite3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; 2. Copy App Files&lt;br /&gt;
Example location:3. Set Permissions&lt;br /&gt;
Apache must write to SQLite and image upload folders:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p data uploads/recipes&lt;br /&gt;
sudo chown -R www-data:www-data data uploads&lt;br /&gt;
sudo chmod -R 775 data uploads&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; Do not make the whole app writable unless needed. Only data/ and uploads/ need write access.&lt;br /&gt;
4. Apache Virtual Host&lt;br /&gt;
Create a site config:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo nano /etc/apache2/sites-available/11square.conf&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName 11square.com&lt;br /&gt;
    ServerAlias www.11square.com&lt;br /&gt;
&lt;br /&gt;
    DocumentRoot /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/html/11square&amp;gt;&lt;br /&gt;
        Options -Indexes +FollowSymLinks&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/11square-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/11square-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;Enable the site: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite 11square.conf&lt;br /&gt;
sudo a2enmod rewrite&lt;br /&gt;
sudo apachectl configtest&lt;br /&gt;
sudo systemctl restart apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;If config test says Syntax OK, Apache is good.&lt;br /&gt;
5. Test App From Server&lt;br /&gt;
From the app folder: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html/11square&lt;br /&gt;
&lt;br /&gt;
php -l index.php&lt;br /&gt;
php -l lib/Database.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;7. Optional HTTPS&lt;br /&gt;
Install Certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache&lt;br /&gt;
&lt;br /&gt;
Issue certificate:&lt;br /&gt;
&lt;br /&gt;
 sudo certbot --apache -d 11square.com -d www.11square.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Then test:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apachectl configtest&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;8. Common Troubleshooting&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check Apache/PHP errors:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/11square-error.log&lt;br /&gt;
 sudo tail -n 100 /var/log/apache2/error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Watch live while refreshing the browser:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo tail -f /var/log/apache2/11square-error.log&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you see:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PDOException: could not find driver&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Install SQLite for Apache’s active PHP version:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ls -la /etc/apache2/mods-enabled/php*.load&lt;br /&gt;
 sudo apt install php8.1-sqlite3&lt;br /&gt;
 sudo phpenmod -v 8.1 -s apache2 pdo_sqlite sqlite3&lt;br /&gt;
 sudo systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
If you see permission errors for SQLite or uploads:&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
sudo chmod -R 775 /var/www/html/11square/data /var/www/html/11square/uploads&lt;br /&gt;
Backup&lt;br /&gt;
Back up these folders/files:&lt;br /&gt;
/var/www/html/11square/data/cocktails.sqlite&lt;br /&gt;
/var/www/html/11square/uploads/&lt;br /&gt;
Those contain your saved recipes and uploaded images.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=AI_APPS&amp;diff=2973</id>
		<title>AI APPS</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=AI_APPS&amp;diff=2973"/>
		<updated>2026-06-10T19:09:27Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[PYTHONAPP]]==&lt;br /&gt;
==[[IMAGEBROWSER]]==&lt;br /&gt;
==[[RecipeApp]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2972</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2972"/>
		<updated>2026-05-29T16:46:21Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install php-mysql php-gd exiftool&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -E &amp;#039;pdo_mysql|gd&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Create Database==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;In phpMyAdmin:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a database, for example imagebrowser.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use collation utf8mb4_unicode_ci.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Import:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 database/schema.sql&lt;br /&gt;
&lt;br /&gt;
4. Create MySQL User&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You can do this in phpMyAdmin, or with MySQL CLI:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER &amp;#039;imagebrowser_user&amp;#039;@&amp;#039;localhost&amp;#039; IDENTIFIED BY &amp;#039;your-strong-password&amp;#039;;&lt;br /&gt;
GRANT ALL PRIVILEGES ON imagebrowser.* TO &amp;#039;imagebrowser_user&amp;#039;@&amp;#039;localhost&amp;#039;;&lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Configure app on the server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html&lt;br /&gt;
cp config/config.example.php config/config.php&lt;br /&gt;
nano config/config.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set these values&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;#039;base_url&amp;#039; =&amp;gt; &amp;#039;&amp;#039;,&lt;br /&gt;
&amp;#039;categories_dir&amp;#039; =&amp;gt; __DIR__ . &amp;#039;/../categories&amp;#039;,&lt;br /&gt;
&amp;#039;thumbnail_dir&amp;#039; =&amp;gt; __DIR__ . &amp;#039;/../cache/thumbs&amp;#039;,&lt;br /&gt;
&amp;#039;db&amp;#039; =&amp;gt; [&lt;br /&gt;
    &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;127.0.0.1&amp;#039;,&lt;br /&gt;
    &amp;#039;port&amp;#039; =&amp;gt; 3306,&lt;br /&gt;
    &amp;#039;database&amp;#039; =&amp;gt; &amp;#039;imagebrowser&amp;#039;,&lt;br /&gt;
    &amp;#039;username&amp;#039; =&amp;gt; &amp;#039;imagebrowser_user&amp;#039;,&lt;br /&gt;
    &amp;#039;password&amp;#039; =&amp;gt; &amp;#039;your-strong-password&amp;#039;,&lt;br /&gt;
    &amp;#039;charset&amp;#039; =&amp;gt; &amp;#039;utf8mb4&amp;#039;,&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use base_url =&amp;gt; &amp;#039;&amp;#039; if the app is at the domain root. If installed in a subfolder like /gallery, use:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;#039;base_url&amp;#039; =&amp;gt; &amp;#039;/gallery&amp;#039;,&lt;br /&gt;
&lt;br /&gt;
6. Set Permissions&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Apache/PHP must be able to read categories/ and write to cache/ and uploads:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/html/cache /var/www/html/uploads /var/www/html/categories&lt;br /&gt;
sudo chmod -R 775 /var/www/html/cache /var/www/html/uploads /var/www/html/categories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
7. Apache Setup&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check which document root Apache is actually serving:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apachectl -S&lt;br /&gt;
&lt;br /&gt;
8.  Setup Conf file&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/apache2/sites-available/imagebrowser.conf&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName yourdomain.com&lt;br /&gt;
    DocumentRoot /var/www/imagebrowser&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/imagebrowser&amp;gt;&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/imagebrowser_error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/imagebrowser_access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8. Enable it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2ensite imagebrowser.conf&lt;br /&gt;
sudo a2enmod rewrite&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
9. Create an Admin User For the App&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cd into the App Folder&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html&lt;br /&gt;
php cli/create_admin.php admin@example.com &amp;quot;your-admin-password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10.  Add Images to the Category Folder&lt;br /&gt;
&lt;br /&gt;
11. Sign in to the Admin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
https://yourdomain.com/login.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12. Go ot Admin and click&lt;br /&gt;
&lt;br /&gt;
 Sync Library&lt;br /&gt;
 Render Category Thumbnails&lt;br /&gt;
&lt;br /&gt;
13. Quick verifications. Run these on the server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html&lt;br /&gt;
php -l index.php&lt;br /&gt;
php -l thumb.php&lt;br /&gt;
php -l app/bootstrap.php&lt;br /&gt;
php -l app/thumbnails.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2971</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2971"/>
		<updated>2026-05-29T16:33:28Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install php-mysql php-gd exiftool&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -E &amp;#039;pdo_mysql|gd&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Create Database==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;In phpMyAdmin:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a database, for example imagebrowser.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use collation utf8mb4_unicode_ci.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Import:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 database/schema.sql&lt;br /&gt;
&lt;br /&gt;
4. Create MySQL User&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You can do this in phpMyAdmin, or with MySQL CLI:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER &amp;#039;imagebrowser_user&amp;#039;@&amp;#039;localhost&amp;#039; IDENTIFIED BY &amp;#039;your-strong-password&amp;#039;;&lt;br /&gt;
GRANT ALL PRIVILEGES ON imagebrowser.* TO &amp;#039;imagebrowser_user&amp;#039;@&amp;#039;localhost&amp;#039;;&lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Configure app on the server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/html&lt;br /&gt;
cp config/config.example.php config/config.php&lt;br /&gt;
nano config/config.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set these values&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;#039;base_url&amp;#039; =&amp;gt; &amp;#039;&amp;#039;,&lt;br /&gt;
&amp;#039;categories_dir&amp;#039; =&amp;gt; __DIR__ . &amp;#039;/../categories&amp;#039;,&lt;br /&gt;
&amp;#039;thumbnail_dir&amp;#039; =&amp;gt; __DIR__ . &amp;#039;/../cache/thumbs&amp;#039;,&lt;br /&gt;
&amp;#039;db&amp;#039; =&amp;gt; [&lt;br /&gt;
    &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;127.0.0.1&amp;#039;,&lt;br /&gt;
    &amp;#039;port&amp;#039; =&amp;gt; 3306,&lt;br /&gt;
    &amp;#039;database&amp;#039; =&amp;gt; &amp;#039;imagebrowser&amp;#039;,&lt;br /&gt;
    &amp;#039;username&amp;#039; =&amp;gt; &amp;#039;imagebrowser_user&amp;#039;,&lt;br /&gt;
    &amp;#039;password&amp;#039; =&amp;gt; &amp;#039;your-strong-password&amp;#039;,&lt;br /&gt;
    &amp;#039;charset&amp;#039; =&amp;gt; &amp;#039;utf8mb4&amp;#039;,&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use base_url =&amp;gt; &amp;#039;&amp;#039; if the app is at the domain root. If installed in a subfolder like /gallery, use:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;#039;base_url&amp;#039; =&amp;gt; &amp;#039;/gallery&amp;#039;,&lt;br /&gt;
&lt;br /&gt;
6. Set Permissions&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Apache/PHP must be able to read categories/ and write to cache/ and uploads:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/html/cache /var/www/html/uploads /var/www/html/categories&lt;br /&gt;
sudo chmod -R 775 /var/www/html/cache /var/www/html/uploads /var/www/html/categories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
7. Apache Setup&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Check which document root Apache is actually serving:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo apachectl -S&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2970</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2970"/>
		<updated>2026-05-29T16:21:44Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install php-mysql php-gd exiftool&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -E &amp;#039;pdo_mysql|gd&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Create Database==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;In phpMyAdmin:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a database, for example imagebrowser.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use collation utf8mb4_unicode_ci.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Import:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 database/schema.sql&lt;br /&gt;
&lt;br /&gt;
4. Create MySQL User&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You can do this in phpMyAdmin, or with MySQL CLI:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER &amp;#039;imagebrowser_user&amp;#039;@&amp;#039;localhost&amp;#039; IDENTIFIED BY &amp;#039;your-strong-password&amp;#039;;&lt;br /&gt;
GRANT ALL PRIVILEGES ON imagebrowser.* TO &amp;#039;imagebrowser_user&amp;#039;@&amp;#039;localhost&amp;#039;;&lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2969</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2969"/>
		<updated>2026-05-29T16:19:32Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install php-mysql php-gd exiftool&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -E &amp;#039;pdo_mysql|gd&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Create Database==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;In phpMyAdmin:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a database, for example imagebrowser.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Use collation utf8mb4_unicode_ci.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Import:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2968</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2968"/>
		<updated>2026-05-29T16:19:10Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install php-mysql php-gd exiftool&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -E &amp;#039;pdo_mysql|gd&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Create Database==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;In phpMyAdmin:&lt;br /&gt;
&lt;br /&gt;
Create a database, for example imagebrowser.&lt;br /&gt;
Use collation utf8mb4_unicode_ci.&lt;br /&gt;
Import:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2967</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2967"/>
		<updated>2026-05-29T16:16:54Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2966</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2966"/>
		<updated>2026-05-29T16:16:45Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Even if PHP is already installed, confirm MySQL and GD support:&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2965</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2965"/>
		<updated>2026-05-29T16:16:18Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;br /&gt;
* Even if PHP is already installed, confirm MySQL and GD support:&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2964</id>
		<title>IMAGEBROWSER</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=IMAGEBROWSER&amp;diff=2964"/>
		<updated>2026-05-29T16:15:48Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: Created page with &amp;quot;== Server Setup == 1. upload contents to web folder&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Setup ==&lt;br /&gt;
1. upload contents to web folder&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=AI_APPS&amp;diff=2963</id>
		<title>AI APPS</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=AI_APPS&amp;diff=2963"/>
		<updated>2026-05-29T16:14:50Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[PYTHONAPP]]==&lt;br /&gt;
==[[IMAGEBROWSER]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=AI_APPS&amp;diff=2962</id>
		<title>AI APPS</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=AI_APPS&amp;diff=2962"/>
		<updated>2026-05-29T16:14:08Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: Created page with &amp;quot;==PYTHONAPP==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[PYTHONAPP]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Main_Page&amp;diff=2961</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Main_Page&amp;diff=2961"/>
		<updated>2026-05-29T16:13:57Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[APPSHEET]]==&lt;br /&gt;
==[[AI APPS]]==&lt;br /&gt;
&lt;br /&gt;
== [[AWS|Amazon Cloud Service]] ==&lt;br /&gt;
== [[Bash]] ==&lt;br /&gt;
== [[Bluhost]] ==&lt;br /&gt;
==[[Centos OS]] ==&lt;br /&gt;
&lt;br /&gt;
== [[Docker]]==&lt;br /&gt;
== [[Github]]==&lt;br /&gt;
==[[Google Sheets]]==&lt;br /&gt;
== [[Hacking|Hacking And Security ]] ==&lt;br /&gt;
==[[Hardware]]==&lt;br /&gt;
==[[IOS Apps]]==&lt;br /&gt;
==[[JavaScript]]==&lt;br /&gt;
==[[Linode]]==&lt;br /&gt;
==[[Login and reset Forget Password]]==&lt;br /&gt;
== [[Math]] ==&lt;br /&gt;
== [[Mac]] ==&lt;br /&gt;
== [[Mysql]] ==&lt;br /&gt;
== [[Networking]] ==&lt;br /&gt;
== [[Open Source Software]] ==&lt;br /&gt;
== [[Oracle SQL]] ==&lt;br /&gt;
== [[Programming]] ==&lt;br /&gt;
== [[Problem Solution]] ==&lt;br /&gt;
== [[Software Tips]] ==&lt;br /&gt;
==[[Tailscale]]==&lt;br /&gt;
== [[Utilities]] ==&lt;br /&gt;
== [[Ubuntu Tips]] ==&lt;br /&gt;
&lt;br /&gt;
== [[Web Links]] ==&lt;br /&gt;
== [[Windows]] ==&lt;br /&gt;
==[[Virtualization]]==&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=PYTHONAPP&amp;diff=2960</id>
		<title>PYTHONAPP</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=PYTHONAPP&amp;diff=2960"/>
		<updated>2026-05-29T15:31:45Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Karaoke app Deployment=&lt;br /&gt;
==  Prerequisite Check ==&lt;br /&gt;
# ssh into the server&lt;br /&gt;
# verify what is installed&lt;br /&gt;
 apache2 -v&lt;br /&gt;
 python3 --version&lt;br /&gt;
 mysql --version&lt;br /&gt;
 which certbot&lt;br /&gt;
# if certbot isn&amp;#039;t installed&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache -y&lt;br /&gt;
&lt;br /&gt;
# Install Python venv if needed:&lt;br /&gt;
 sudo apt install python3-venv python3-pip -y&lt;br /&gt;
&lt;br /&gt;
==  Create the App Directory ==&lt;br /&gt;
 sudo mkdir -p /var/www/html/myapp&lt;br /&gt;
 cd /var/www/html/myapp&lt;br /&gt;
&lt;br /&gt;
== Upload App Files ==&lt;br /&gt;
# Upload the .env file (hidden, so it won&amp;#039;t be picked up by scp -r)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you don&amp;#039;t see .env in Finder, press Cmd+Shift+. to toggle hidden files.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Set up the Python Environment ==&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/html/myapp&lt;br /&gt;
 python3 -m venv venv&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 pip install flask pymysql cryptography gunicorn DBUtils&lt;br /&gt;
 deactivate&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The cryptography package is required for MySQL caching_sha2_password auth.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Configure the Database ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Open phpMyAdmin in your browser. Make sure the user in your .env file has privileges on the dbasename database. If not, in phpMyAdmin run:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 GRANT ALL PRIVILEGES ON dbasename.* TO &amp;#039;YourUser&amp;#039;@&amp;#039;localhost&amp;#039;;&lt;br /&gt;
 FLUSH PRIVILEGES;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Verify your .env file on the server has the correct values:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 cat /var/www/html/myapp/.env&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; It should contain &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 DB_HOST=localhost&lt;br /&gt;
 DB_USER=YourUser&lt;br /&gt;
 DB_PASS=YourPassword&lt;br /&gt;
 DB_NAME=dbasename&lt;br /&gt;
 SECRET_KEY=some-random-string&lt;br /&gt;
 HOST_NAME= name for the host side&lt;br /&gt;
 PORT=3001&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important: Use a different port from any other apps you have running. I&amp;#039;m using 3001 here — pick whatever&amp;#039;s free.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Test App Manually==&lt;br /&gt;
 cd /var/www/html/myapp&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 python3 app.py&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You should see &amp;quot;Karaoke app running on http://localhost:3001&amp;quot;. In another SSH window test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo nano /etc/systemd/system/myapp.service&lt;br /&gt;
&lt;br /&gt;
== Create the systemd Service ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Paste &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=My App mydir (Gunicorn)&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 User=www-data&lt;br /&gt;
 Group=www-data&lt;br /&gt;
 WorkingDirectory=/var/www/html/myapp&lt;br /&gt;
 Environment=&amp;quot;PATH=/var/www/html/myapp/venv/bin&amp;quot;&lt;br /&gt;
 ExecStart=/var/www/html/myapp/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:3001 app:app&lt;br /&gt;
 Restart=always&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Save (Ctrl+O, Enter, Ctrl+X).&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set permissions:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo chown -R www-data:www-data /var/www/html/myapp&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable and start &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo systemctl daemon-reload&lt;br /&gt;
 sudo systemctl enable myapp&lt;br /&gt;
 sudo systemctl start myapp&lt;br /&gt;
 sudo systemctl status myapp&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You should see active (running). If not:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo journalctl -u myapp -n 50&lt;br /&gt;
&lt;br /&gt;
== Configure Apache Reverse Proxy==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable required modules (only needed once on the server):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo a2enmod proxy proxy_http ssl rewrite headers&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create the HTTP vhost (which certbot will upgrade later):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/apache2/sites-available/mydomain.conf&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Paste — replace yourdomain.com with your actual domain&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName yourdomain.com&lt;br /&gt;
    ServerAlias www.yourdomain.com&lt;br /&gt;
    DocumentRoot /var/www/html/domainfolder&lt;br /&gt;
#the proxy stuff below is needed if you are doing reverse proxy. not needed for a regular port 80 deployment&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyPass / http://127.0.0.1:3001/&lt;br /&gt;
    ProxyPassReverse / http://127.0.0.1:3001/&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/mydomain-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/mydomain-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable and reload&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo a2ensite mydomain.conf&lt;br /&gt;
 sudo apache2ctl configtest&lt;br /&gt;
 sudo systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
Test in your browser: http://yourdomain.com — you should see the login page.&lt;br /&gt;
&lt;br /&gt;
== Enable HTTPS with Certbot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Make sure your domain&amp;#039;s DNS A record points to your server IP first.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Run certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo certbot --apache -d yourdomain.com -d www.yourdomain.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Choose 2 (Redirect) when asked, so HTTP automatically redirects to HTTPS.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Certbot will create /etc/apache2/sites-available/rb222-le-ssl.conf and enable it.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apache2ctl configtest&lt;br /&gt;
 sudo systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Visit https://yourdomain.com — you should see the lock icon and the app.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If certbot fails to auto-configure (it sometimes does), create the SSL vhost manually:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/apache2/sites-available/mydomain-le-ssl.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_ssl.c&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName yourdomain.com&lt;br /&gt;
    ServerAlias www.yourdomain.com&lt;br /&gt;
&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyPass / http://127.0.0.1:3001/&lt;br /&gt;
    ProxyPassReverse / http://127.0.0.1:3001/&lt;br /&gt;
&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem&lt;br /&gt;
    Include /etc/letsencrypt/options-ssl-apache.conf&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/rb222-ssl-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/rb222-ssl-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;then&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo a2ensite mydomain-le-ssl.conf&lt;br /&gt;
 sudo systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cert auto-renewal is already enabled by certbot&amp;#039;s systemd timer — verify with&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo systemctl list-timers | grep certbot&lt;br /&gt;
&lt;br /&gt;
=Database Optimization=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE INDEX idx_songs_title ON songs(Title(100));&lt;br /&gt;
CREATE INDEX idx_songs_artists ON songs(Artists(100));&lt;br /&gt;
CREATE INDEX idx_favorite_name ON Favorite(Name(80), Tag(20));&lt;br /&gt;
CREATE INDEX idx_queue_status ON queue(Status(20));&lt;br /&gt;
CREATE INDEX idx_queue_timestamp ON queue(TimeStamp(20));&lt;br /&gt;
CREATE INDEX idx_archive_name ON Archive_Singers(Name(80));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
= How to find out the service name of the app= &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is the service that starts the app, this will list all running services&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# &amp;quot;What services exist on this box?&amp;quot;&lt;br /&gt;
systemctl list-unit-files --type=service --state=enabled&lt;br /&gt;
&lt;br /&gt;
# &amp;quot;Which one is MY app?&amp;quot;&lt;br /&gt;
sudo grep -l &amp;quot;/var/www/html/&amp;lt;dirname&amp;gt;&amp;quot; /etc/systemd/system/*.service&lt;br /&gt;
&lt;br /&gt;
# &amp;quot;Which service owns port X?&amp;quot;&lt;br /&gt;
sudo lsof -i :3000 -P -n            # gets PID&lt;br /&gt;
ps -o unit= -p &amp;lt;PID&amp;gt;                # gets service name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== How to rebuild venv dir if deleted==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/karaapp          # your project dir&lt;br /&gt;
&lt;br /&gt;
# 1. Recreate the virtual environment&lt;br /&gt;
python3 -m venv venv&lt;br /&gt;
&lt;br /&gt;
# 2. Activate it&lt;br /&gt;
source venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
# 3. Reinstall dependencies&lt;br /&gt;
pip install --upgrade pip&lt;br /&gt;
pip install -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
# 4. Start the app (however you normally run it)&lt;br /&gt;
gunicorn app:app            # or: python app.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=PYTHONAPP&amp;diff=2959</id>
		<title>PYTHONAPP</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=PYTHONAPP&amp;diff=2959"/>
		<updated>2026-05-08T18:19:01Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: /* Configure Apache Reverse Proxy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Karaoke app Deployment=&lt;br /&gt;
==  Prerequisite Check ==&lt;br /&gt;
# ssh into the server&lt;br /&gt;
# verify what is installed&lt;br /&gt;
 apache2 -v&lt;br /&gt;
 python3 --version&lt;br /&gt;
 mysql --version&lt;br /&gt;
 which certbot&lt;br /&gt;
# if certbot isn&amp;#039;t installed&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install certbot python3-certbot-apache -y&lt;br /&gt;
&lt;br /&gt;
# Install Python venv if needed:&lt;br /&gt;
 sudo apt install python3-venv python3-pip -y&lt;br /&gt;
&lt;br /&gt;
==  Create the App Directory ==&lt;br /&gt;
 sudo mkdir -p /var/www/html/myapp&lt;br /&gt;
 cd /var/www/html/myapp&lt;br /&gt;
&lt;br /&gt;
== Upload App Files ==&lt;br /&gt;
# Upload the .env file (hidden, so it won&amp;#039;t be picked up by scp -r)&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you don&amp;#039;t see .env in Finder, press Cmd+Shift+. to toggle hidden files.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Set up the Python Environment ==&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/html/myapp&lt;br /&gt;
 python3 -m venv venv&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 pip install flask pymysql cryptography gunicorn DBUtils&lt;br /&gt;
 deactivate&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The cryptography package is required for MySQL caching_sha2_password auth.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Configure the Database ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Open phpMyAdmin in your browser. Make sure the user in your .env file has privileges on the dbasename database. If not, in phpMyAdmin run:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 GRANT ALL PRIVILEGES ON dbasename.* TO &amp;#039;YourUser&amp;#039;@&amp;#039;localhost&amp;#039;;&lt;br /&gt;
 FLUSH PRIVILEGES;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Verify your .env file on the server has the correct values:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 cat /var/www/html/myapp/.env&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; It should contain &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 DB_HOST=localhost&lt;br /&gt;
 DB_USER=YourUser&lt;br /&gt;
 DB_PASS=YourPassword&lt;br /&gt;
 DB_NAME=dbasename&lt;br /&gt;
 SECRET_KEY=some-random-string&lt;br /&gt;
 HOST_NAME= name for the host side&lt;br /&gt;
 PORT=3001&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important: Use a different port from any other apps you have running. I&amp;#039;m using 3001 here — pick whatever&amp;#039;s free.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Test App Manually==&lt;br /&gt;
 cd /var/www/html/myapp&lt;br /&gt;
 source venv/bin/activate&lt;br /&gt;
 python3 app.py&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You should see &amp;quot;Karaoke app running on http://localhost:3001&amp;quot;. In another SSH window test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo nano /etc/systemd/system/myapp.service&lt;br /&gt;
&lt;br /&gt;
== Create the systemd Service ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Paste &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=My App mydir (Gunicorn)&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 User=www-data&lt;br /&gt;
 Group=www-data&lt;br /&gt;
 WorkingDirectory=/var/www/html/myapp&lt;br /&gt;
 Environment=&amp;quot;PATH=/var/www/html/myapp/venv/bin&amp;quot;&lt;br /&gt;
 ExecStart=/var/www/html/myapp/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:3001 app:app&lt;br /&gt;
 Restart=always&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Save (Ctrl+O, Enter, Ctrl+X).&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set permissions:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo chown -R www-data:www-data /var/www/html/myapp&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable and start &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo systemctl daemon-reload&lt;br /&gt;
 sudo systemctl enable myapp&lt;br /&gt;
 sudo systemctl start myapp&lt;br /&gt;
 sudo systemctl status myapp&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;You should see active (running). If not:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo journalctl -u myapp -n 50&lt;br /&gt;
&lt;br /&gt;
== Configure Apache Reverse Proxy==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable required modules (only needed once on the server):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo a2enmod proxy proxy_http ssl rewrite headers&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create the HTTP vhost (which certbot will upgrade later):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/apache2/sites-available/mydomain.conf&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Paste — replace yourdomain.com with your actual domain&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName yourdomain.com&lt;br /&gt;
    ServerAlias www.yourdomain.com&lt;br /&gt;
    DocumentRoot /var/www/html/domainfolder&lt;br /&gt;
#the proxy stuff below is needed if you are doing reverse proxy. not needed for a regular port 80 deployment&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyPass / http://127.0.0.1:3001/&lt;br /&gt;
    ProxyPassReverse / http://127.0.0.1:3001/&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/mydomain-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/mydomain-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Enable and reload&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo a2ensite mydomain.conf&lt;br /&gt;
 sudo apache2ctl configtest&lt;br /&gt;
 sudo systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
Test in your browser: http://yourdomain.com — you should see the login page.&lt;br /&gt;
&lt;br /&gt;
== Enable HTTPS with Certbot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Make sure your domain&amp;#039;s DNS A record points to your server IP first.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Run certbot:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo certbot --apache -d yourdomain.com -d www.yourdomain.com&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Choose 2 (Redirect) when asked, so HTTP automatically redirects to HTTPS.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Certbot will create /etc/apache2/sites-available/rb222-le-ssl.conf and enable it.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo apache2ctl configtest&lt;br /&gt;
 sudo systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Visit https://yourdomain.com — you should see the lock icon and the app.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If certbot fails to auto-configure (it sometimes does), create the SSL vhost manually:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/apache2/sites-available/mydomain-le-ssl.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_ssl.c&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
    ServerName yourdomain.com&lt;br /&gt;
    ServerAlias www.yourdomain.com&lt;br /&gt;
&lt;br /&gt;
    ProxyPreserveHost On&lt;br /&gt;
    ProxyPass / http://127.0.0.1:3001/&lt;br /&gt;
    ProxyPassReverse / http://127.0.0.1:3001/&lt;br /&gt;
&lt;br /&gt;
    SSLEngine on&lt;br /&gt;
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem&lt;br /&gt;
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem&lt;br /&gt;
    Include /etc/letsencrypt/options-ssl-apache.conf&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/rb222-ssl-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/rb222-ssl-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;then&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo a2ensite mydomain-le-ssl.conf&lt;br /&gt;
 sudo systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cert auto-renewal is already enabled by certbot&amp;#039;s systemd timer — verify with&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo systemctl list-timers | grep certbot&lt;br /&gt;
&lt;br /&gt;
=Database Optimization=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE INDEX idx_songs_title ON songs(Title(100));&lt;br /&gt;
CREATE INDEX idx_songs_artists ON songs(Artists(100));&lt;br /&gt;
CREATE INDEX idx_favorite_name ON Favorite(Name(80), Tag(20));&lt;br /&gt;
CREATE INDEX idx_queue_status ON queue(Status(20));&lt;br /&gt;
CREATE INDEX idx_queue_timestamp ON queue(TimeStamp(20));&lt;br /&gt;
CREATE INDEX idx_archive_name ON Archive_Singers(Name(80));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
= How to find out the service name of the app= &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is the service that starts the app, this will list all running services&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# &amp;quot;What services exist on this box?&amp;quot;&lt;br /&gt;
systemctl list-unit-files --type=service --state=enabled&lt;br /&gt;
&lt;br /&gt;
# &amp;quot;Which one is MY app?&amp;quot;&lt;br /&gt;
sudo grep -l &amp;quot;/var/www/html/&amp;lt;dirname&amp;gt;&amp;quot; /etc/systemd/system/*.service&lt;br /&gt;
&lt;br /&gt;
# &amp;quot;Which service owns port X?&amp;quot;&lt;br /&gt;
sudo lsof -i :3000 -P -n            # gets PID&lt;br /&gt;
ps -o unit= -p &amp;lt;PID&amp;gt;                # gets service name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
	<entry>
		<id>https://www.r512.com/index.php?title=Setup_Mac_for_ssh_into_synology&amp;diff=2958</id>
		<title>Setup Mac for ssh into synology</title>
		<link rel="alternate" type="text/html" href="https://www.r512.com/index.php?title=Setup_Mac_for_ssh_into_synology&amp;diff=2958"/>
		<updated>2026-04-24T19:02:27Z</updated>

		<summary type="html">&lt;p&gt;Bacchas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Set up Password-less Login ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For an unattended script, your Mac needs to log in without a password. Open Terminal on your Mac:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Generate a key:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 ssh-keygen -t ed25519 (Press Enter through all prompts).&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Copy it to the NAS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 ssh-copy-id -i ~/.ssh/id_ed25519.pub your_nas_user@100.x.y.z&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Test it:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 ssh your_nas_user@100.x.y.z. If you get in without a password, you’re ready.&lt;br /&gt;
&lt;br /&gt;
== Fix Permissions on the Synology==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Log in to your NAS with your password one last time and run these commands to restrict access to your home folder: &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set Home Directory to 755: SSH requires that your home directory is not writable by others.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 chmod 755 /volume1/homes/bacchas&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set .ssh Folder to 700: This folder must be readable only by you.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 chmod 700 /volume1/homes/bacchas/.ssh&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Set authorized_keys to 600: The key file must be strictly protected.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 chmod 600 /volume1/homes/bacchas/.ssh/authorized_keys &lt;br /&gt;
&lt;br /&gt;
== Verify &amp;quot;User Home Service&amp;quot; is Enabled ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;SSH keys won&amp;#039;t work if the NAS isn&amp;#039;t correctly mapping your home directory. &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;In DSM, go to Control Panel &amp;gt; User &amp;amp; Group &amp;gt; Advanced.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Scroll down to User Home and ensure Enable user home service is checked. &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Check Synology’s SSH Configuration ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sometimes PubkeyAuthentication is disabled in the system config. &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;On the NAS, edit the config file: &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo vi /etc/ssh/sshd_config.&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Find these lines and ensure they are uncommented (no # at the start):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 PubkeyAuthentication yes&lt;br /&gt;
 AuthorizedKeysFile .ssh/authorized_keys&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you made changes, restart the service in Control Panel &amp;gt; Terminal &amp;amp; SNMP by unchecking and re-checking the Enable SSH service box. &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Mac-Specific: Add Key to your SSH Agent==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;On macOS, your terminal might not be &amp;quot;offering&amp;quot; the key automatically. Run this command on your Mac to manually add it to your current session:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 ssh-add ~/.ssh/id_ed25519 &lt;br /&gt;
&lt;br /&gt;
==How to Troubleshoot==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If it still asks for a password, run the connection in &amp;quot;verbose&amp;quot; mode on your Mac:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 ssh -vvv username@192.168.20.22&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Look for a line that says &amp;quot;debug1: Next authentication method: publickey&amp;quot;. If it says &amp;quot;Authentication refused: bad ownership or modes,&amp;quot; it means the permission fix in Step 1 didn&amp;#039;t stick or was applied to the wrong path. &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Restart the Service==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Changes to sshd_config do not take effect until the service restarts.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Command: sudo &amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
 synosystemctl restart sshd.&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Alternative: Toggle &amp;quot;Enable SSH Service&amp;quot; off and back on in the DSM Control Panel. &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=Create config file=&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Create a config file in the ~/.ssh/config&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; This file contains the host name and the path to the ssh keys&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host wendy&lt;br /&gt;
	HostName 192.168.20.22&lt;br /&gt;
	User myname&lt;br /&gt;
	IdentityFile ~/.ssh/keyidfile&lt;br /&gt;
	IdentitiesOnly yes&lt;br /&gt;
&lt;br /&gt;
#for tailscale&lt;br /&gt;
&lt;br /&gt;
Host wendy-tailscale&lt;br /&gt;
	HostName 1.1.1.1&lt;br /&gt;
	User myname&lt;br /&gt;
	IdentityFile ~/.ssh/keyfile&lt;br /&gt;
        IdentitiesOnly yes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[[ Backup_script_on_mac_config_and_setup| Mac Setup]] - [[Bash| Bash menu]]-[[Main_Page| Home]]==&lt;br /&gt;
[[Category:Bash]]&lt;/div&gt;</summary>
		<author><name>Bacchas</name></author>
	</entry>
</feed>