CentOS 7 LAMP Server Tutorial Part 6: Moving to NGINX

Welcome to the latest installment in the CentOS 7 LAMP Server Tutorial: Modernized and explained series! In this article we are going to convert our LAMP server into a LEMP server by removing Apache and installing NGINX (pronounced "Engine X") instead.

Why would we want to replace the Apache web server with NGINX? The answer is in concurrence. NGINX can handle more connections at the same time as Apache without causing any additional work for the server. It can be used as a stand-alone web server or as a "buffer" or "buffer" between Apache and the rest of the Internet. In this tutorial we are going to replace the Apache web server with an independent installation of NGINX. Let us begin!

Preparation for the change.

If you followed our series, now you have a WordPress website that runs on Apache with PHP 7.3 and an Encrypt SSL certificate. Apache serves the non-SSL site on port 80 and the SSL site on port 443. NGINX also wants to listen on port 80 and port 443, because these are the ports that HTTP and HTTPS always use. We can not put NGINX alternative ports because that web browser would never find it. The solution is to disable or remove Apache, and then configure NGINX instead.

In Part 2 we set up Apache with a VirtualHost that tells Apache where our WordPress site should be from. NGINX will need a similar configuration so you know how to serve our website. We will also have to tell NGINX how to use the Encrypt SSL certificate.

We are going to make some drastic configuration changes in this tutorial, so it is necessary to have a warning: Backup of your dataY do not do this on a production server. If you already have a website in operation that is generating revenue or is important to you, having. The best thing for us is to get a second VPS, run the entire tutorial and then set up a test site. Once you are sure it works for you, migrate your site to your new server based on NGINX.

Eliminating apache

Are you still with us? Cool! This is going to be fun. As mentioned above, we need to get Apache out of the way so that NGINX can do its job. There are two ways to do it: Stop and disable Apache, or simply remove Apache. We are going to eliminate it. This is easily done with a single command:

yum - and remove httpd

This is what it looked like in our low-end VPS:

You will notice that Yum also deleted mod_ssl (the Apache SSL module) and the Let's Encrypt SSL certificate for Apache. We will replace them with the NGINX equivalents in the next step.

Installing NGINX

NGINX can be installed directly from the CentOS 7 Yum base repositories, but it lacks some of the functions that we will need. We will use a repository that is maintained by someone with the username "error". Do not worry, there are no mistakes! We need to install that repository before installing NGINX. Here is the command to use:

curl -o /etc/yum.repos.d/nginx-error.repo 

What about the Encrypt SSL certificates? In part 3 of this series, we learned that certbot uses its Apache module to intelligently request and install the Encrypt SSL certificates. But since we are switching to NGINX, we need to install the similar NGINX module for certbot.

The following command will install the updated version of NGINX and the NGINX certbot module:

yum -y install nginx python2-certbot-nginx

This is how it looked in our VPS:

Now we will enable NGINX to start at startup, and we will start it for the first time:

systemctl enable nginx.service
systemctl start nginx

You may notice that we are not doing anything with PHP. That's because we previously configured PHP-FPM for PHP 7.3. PHP-FPM is independent of the web server. We can use any web server to communicate with PHP-FPM through its Unix socket. We will be configuring that communication very soon. For now you should see the following page when you go to your website:

If you do not see that page, go back and review your work, it's probably something small.

Configuring NGINX to replace Apache

We originally configured Apache with a VirtualHost configuration so that it could serve files for our virtual website. NGINX has the same feature, but NGINX calls them "server blocks" instead of "virtual hosts". And like Apache, we can create a directory that is only for the configuration files that are specific to each hosted website.

First we create the necessary directory and then make a backup copy of the default nginx.conf file (the main NGINX configuration file) before creating our own files.

mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
mkdir / etc / nginx / sites-enabled

Now let's use "nano" to create two files: /etc/nginx/nginx.conf and /etc/nginx/sites-enabled/lowend.conf. The nginx.conf file contains directives for the entire server, where lowend.conf contains the server lock and the specific configuration information of our website. Copy and paste these configuration files. Be sure to read them in full, because they explain all the configuration. Comments are a very important part of this tutorial.

nano /etc/nginx/nginx.conf

Paste in the following configuration file:

nginx user;
auto worker_processes;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.

includes /usr/share/nginx/modules/*.conf;

events {
worker_connections 1024;

http {
log_format main & # 39; $ remote_addr - $ remote_user [$time_local] "$ request" & # 39;
& # 39; $ status $ body_bytes_sent "$ http_referer" & # 39;
& # 39; "$ http_user_agent" "$ http_x_forwarded_for" & # 39 ;;
access_log /var/log/nginx/access.log main;
log_format cache_status & # 39;[$time_local] "$ request" $ upstream_cache_status & # 39 ;;
access_log /var/log/nginx/cache.log cache_status;
send file in
tcp_nopush in;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1024;

includes /etc/nginx/mime.types;
default_type application / octet-stream;

# Enable the NGIXN fastcgi cache in / var / run / nginx-cache and configure the cache keys

fastcgi_cache_path / var / run / nginx-cache levels = 1: 2 keys_zone = nginx-cache: 100m inactive = 60m;
fastcgi_cache_key "$ scheme $ request_method $ host $ request_uri";

# Add X-Cache headers to HTTP requests. This allows us to see if the cached content is being served.
# If cached content is served, the header will contain the value "HIT", and if it is not "MISS".

add_header X-Cache $ upstream_cache_status;

# Detect session in the WordPress user cookie
# This is used in the Server Block to bypass the cache for registered WordPress users.
map $ http_cookie $ log_in {
default 0;
~ SESS 1;
~ wordpress_logged_in 1;

# Allow individual server blocks to be stored in / etc / nginx / site-enabled
# and still be included in the NGINX configuration.

includes /etc/nginx/sites-enabled/*.conf;


Now we will create the server block for our website:

nano /etc/nginx/sites-enabled/lowend.conf

Paste in the following configuration file:

server {

# We'll start enabling GZIP compression for the server
gzip in
gzip text types / simple text / css application / json application / x-javascript text / xml application / xml application / xml + rss text / javascript application / vnd.ms-fontobject application / x-font-ttf font / opentype image / svg + image xml / x-icon;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 1000;

# This server block listens on port 80 for HTTP requests
listen 80;

#Define the host names for this server block, separated by a space
server_name lowend-tutorial.tld www.lowend-tutorial.tld;

# Define the root of the document from which NGINX will serve the pages for the site.
root / home / lowend / public_html;

# Look for index.php. If you want to add index.html or any other default page, add it here.
Index index.php;

# Define the access log file for the account
access_log /home/lowend/logs/lowend-tutorial.tld-access.log main;

# Do not log in favicon.ico
location = /favicon.ico {
log_not_found off;
access_log disabled;

# Do not register robots.txt
location = /robots.txt {
allow everything;
log_not_found off;
access_log disabled;

Location / {
# include the "? $ args" part so that non-default permanent links do not break when a query string is used
try_files $ uri $ uri / /index.php?$args;

#Bypass cache for registered WordPress users
# This is important so that caching does not interfere with development.
fastcgi_cache_bypass $ log_in;
fastcgi_no_cache $ log_in;

location ~  .php $ {
try_files $ uri = 404;
# Connect to PHP-FPM for PHP calls through fastcgi
# This is the NGINX equivalent of the Apache fastcgi directives that were previously used
fastcgi_pass unix: /var/run/php73-fpm/php73-fpm.lowend.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
includes fastcgi_params;

# Make use of the nginx-cache that was defined in nginx.conf
fastcgi_cache nginx-cache;
fastcgi_cache_valid 200 60m;

# Set a maximum expiration time for several types of files, and do not register 404 for them
location ~ * . (js | css | png | jpg | jpeg | gif | ico) $ {
max expires;
log_not_found off;
# Configure the cache purge. This will allow us to use a small shell script to purge the cache every hour.
location ~ /purge(/.*) {
deny everything;
fastcgi_cache_purge nginx-cache "$ scheme $ request_method $ host $ 1";


Now we can restart NGINX to enable the new configuration:

systemctl restart nginx

NGINX and Let's Encrypt

In the previous steps, we eliminated the certbot-apache module and installed the certbot-nginx module. The new module does all the same things for NGINX that certbot-apache did for Apache. We will use the certbot-nginx module to reinstall our certificate with the following command:

certbot --nginx

As there is already a certificate, we can select the option "1: try to reinstall this existing certificate"

We also need to update our cron job to renew certificates. Edit the crontab with the following command:

crontab -e

Edit the configuration so that it looks like the following line:

1 * / 12 * * * certbot --nginx renew

Check your work

Now you should be able to load your WordPress website in a browser. If not, review all the previous steps and check the NGINX error logs.

With that reboot, NGINX is fully configured for your WordPress site. Caching is enabled, and when you log in to WordPress, NGINX will bypass the cache so you can easily see your changes.

Clearing the cache

We have configured a way to clear the NGINX cache by calling a URL with HTTP "PURGE" instead of "GET". This is an excellent way to do it, and in fact we install the customized version of NGINX just to enable this feature. But there is a minor problem. At the time of writing this article, there are no NGINX cache plugins for WordPress that really work when cleaning the cache using the "PURGE" method. They require that PHP can directly access the NGINX cache files, which presents a security risk: all sites share the same cache directory, and the PHP-FPM instance of each site would have access to another site cache. That is not safe at all!

To remedy this, we will take advantage of wp-cli to give us a list of all the publications and pages in your WordPress site, then pass it to a "for" loop that calls CURL to create an HTTP request that purges the cache. of each post or page. We're going to do this in a very simple shell script. This script should not go in the public_html directory, and should be owned by the user of the website and executed. The username of our website is "lowend" and, therefore, this file will be saved in / home / lowend /. We use the following command to create the file:

sudo -u lowend nano /home/lowend/flush.sh

Paste in the following script. Be sure to correct the URL to match your site:

#! / bin / bash
#Use wp-cli to find all the pages and publications and use CURL to issue a
# HTTP PURGE to empty the cache of each page and publication.
for page in
$ (/ usr / local / bin / wp --path = / home / lowend / public_html post list --post_type = page, post --format = csv --field = post_name)
do curl --silent --output / dev / null - X PURGE -I "https: //lowend-tutorial.tld/$page"

Now set the permissions to 755:

chmod 755 /home/lowend/flush.sh

We want to clear the cache regularly, so we'll create a cron job that will run our flush.sh script every hour:

crontab -e -u lowend

Paste in the following cron job:

1 * * * * /home/lowend/flush.sh

Last but not least, log in to your WordPress website and remove all caching add-ons. Instead, we're going to install an add-on called "Redis Object Cache" by Till Krüss. Install and activate the script, and it will take care of the caching of objects through Redis, while NGINX will take care of the caching of the page. It is a great configuration.

And with that, we're finished! Our tests showed that we were able to meet 30% more requests per second with this configuration. Depending on your VPS, you can do the same, and possibly much more.

The end is just the beginning

This tutorial marks the conclusion of the LAMP server series. We hope you found it informative! The things you learned from building your own server from scratch will help you understand and appreciate what goes on behind the scenes when you use a control panel that manages the settings for you. They really save a lot of work! But even more than that, you have learned how virtual hosting works, how you can configure PHP, and how to use the basic Linux tools to manage your server.

What other things could you do? Instead of configuring NGINX like we did in this tutorial, why not stop configuring Apache and learn how to configure NGINX as a proxy caching server? Learn how to create multiple websites by creating new users and new virtual hosts or server blocks (or both, as the case may be). Tired of building configuration files from scratch every time? Learn a tool like Ansible that will do all the work for you. The possibilities are endless. This may be the end of this series, but it is only the beginning for someone who is ready to continue learning. Enjoy!

Any tutorial on how to set up a domain in webmin

No virtualmin

I mean webmin alone, I've found some tutorials on YouTube but most are old.

thanks … | Read the rest of http://www.webhostingtalk.com/showthread.php?t=1771874&goto=newpost

Following the personalized Drupal 8 Commerce offer tutorial, but the "name is already in use" error

I am following the tutorial to create a personalized offer in the official documentation of Drupal 8 Commerce. But I receive an error that I stuck below when I click on any of the conditions, and none of the forms appear for any of the integrated trading offers. I followed the tutorial exactly, except for extending the OrderPromotionOfferBase class instead of the OrderFixedAmountOff class. I pasted the content of the OrderItemFixedAmountTarget class that I defined for the offer below the error.

The offer fields do not appear


An HTTP AJAX error occurred.
HTTP result code: 200
The debug information follows.
Path: / promotion / 1 / edit? Destination = / admin / commerce / promotions & ajax_form = 1
StatusText: OK
(!) Fatal error: Drupal class  my_module  Plugin  Commerce  PromotionOffer  OrderItemFixedAmountTarget can not be declared, because the name is already in use in / home / usertest / workspace / drupalsite / web / modules / my_module / src / Plugin / Commerce / PromotionOffer / OrderItemFixedAmountTarget.php on line 18
Call stack
10.0000438056 {main} () ... / index.php: 0
20,0006554920Drupal  Core  DrupalKernel-> handle () ... / index.php: 19
30.00441717448Stack  StackedHttpKernel-> handle () ... / DrupalKernel.php: 693
40.00441717448Drupal  Core  StackMiddleware  NegotiationMiddleware-> handle () ... / StackedHttpKernel.php: 23
50.00441718144Drupal  Core  StackMiddleware  ReverseProxyMiddleware-> handle () ... / NegotiationMiddleware.php: 52
60.00441718144Drupal  page_cache  StackMiddleware  PageCache-> handle () ... / ReverseProxyMiddleware.php: 47
70.00441718144Drupal  page_cache  StackMiddleware  PageCache-> pass () ... / PageCache.php: 85
80.00441718144Drupal  Core  StackMiddleware  KernelPreHandle-> handle () ... / PageCache.php: 106
90.00562139576Drupal  Core  StackMiddleware  Session-> handle () ... / KernelPreHandle.php: 47
100.00642260136Symfony  Component  HttpKernel  HttpKernel-> handle () ... / Session.php: 57
110.00652260552Symfony  Component  HttpKernel  HttpKernel-> handleRaw () ... / HttpKernel.php: 68
120.02877724544Drupal  Core  EventSubscriber  EarlyRenderingControllerWrapperSubscriber-> Drupal  Core  EventSubscriber  {closing} () ... / HttpKernel.php: 151
130.02877724544Drupal  Core  EventSubscriber  EarlyRenderingControllerWrapperSubscriber-> wrapControllerExecutionInRenderContext () ... / EarlyRenderingControllerWrapperSubscriber.php: 97
140.02877727080Drupal  Core  Render  Renderer-> executeInRenderContext () ... / EarlyRenderingControllerWrapperSubscriber.php: 124
150.02877727432Drupal  Core  EventSubscriber  EarlyRenderingControllerWrapperSubscriber-> Drupal  Core  EventSubscriber  {closing} () ... / Renderer.php: 582
160.02877727432call_user_func_array: {/ home / usertest / workspace / drupalsite / web / core / lib / Drupal / Core / EventSubscriber / EarlyRenderingControllerWrapperSubscriber.php: 123}
() ... / EarlyRenderingControllerWrapperSubscriber.php: 123
170.02877727840Drupal  Core  Entity  HtmlEntityFormController-> getContentResult () ... / EarlyRenderingControllerWrapperSubscriber.php: 123
180.02917849224Drupal  Core  Form  FormBuilder-> buildForm () ... / FormController.php: 93
190.043110154816Drupal  Core  Form  FormBuilder-> processForm () ... / FormBuilder.php: 319
200.087912157904Drupal  Core  Form  FormBuilder-> rebuildForm () ... / FormBuilder.php: 626
210.087912157904Drupal  Core  Form  FormBuilder-> retrieveForm () ... / FormBuilder.php: 369
220.087912160160call_user_func_array: {/ home / usertest / workspace / drupalsite / web / core / lib / Drupal / Core / Form / FormBuilder.php: 519}
() ... / FormBuilder.php: 519
230.087912160568Drupal  commerce_promotion  Form  PromotionForm-> buildForm () ... / FormBuilder.php: 519
240.088212170728Drupal  commerce_promotion  Form  PromotionForm-> buildForm () ... / PromotionForm.php: 31
250.088312171952Drupal  commerce_promotion  Form  PromotionForm-> form () ... / EntityForm.php: 117
260.088312171952Drupal  commerce_promotion  Form  PromotionForm-> form () ... / PromotionForm.php: 38
270.088312172728Drupal  Core  Entity  Entity  EntityFormDisplay-> buildForm () ... / ContentEntityForm.php: 125
280.089312198408Drupal  commerce  Plugin  Field  FieldWidget  PluginSelectWidget-> form () ... / EntityFormDisplay.php: 177
290.089312198408Drupal  commerce  Plugin  Field  FieldWidget  PluginSelectWidget-> formMultipleElements () ... / WidgetBase.php: 104
300.089312198784Drupal  commerce  Plugin  Field  FieldWidget  PluginSelectWidget-> formSingleElement () ... / WidgetBase.php: 202
310.089312199160Drupal  commerce  Plugin  Field  FieldWidget  PluginSelectWidget-> formElement () ... / WidgetBase.php: 335
320.089312201184Drupal  commerce  Plugin  Field  FieldWidget  PluginSelectWidget-> supportConfiguration () ... / PluginSelectWidget.php: 116
() ... / PluginSelectWidget.php: 149
() ... / PluginSelectWidget.php: 149
350.089312201840Composer  Autoload  ClassLoader-> loadClass () ... / PluginSelectWidget.php: 149
360.089412202032Composer  Autoload  includeFile () ... / ClassLoader.php: 322
370.089412202272include (& # 39; /home/usertest/workspace/drupalsite/web/modules/my_module/src/Plugin/Commerce/PromotionOffer/OrderItemFixedAmountTarget.php') ... / ClassLoader.php: 4444


Drupal namespace  my_module  Plugin  Commerce  PromotionOffer;

use Drupal  commerce_promotion  Plugin  Commerce  PromotionOffer  OrderPromotionOfferBase;
use Drupal  commerce_promotion  Plugin  Commerce  PromotionOffer  FixedAmountOffTrait;
use Drupal  commerce_order  Adjustment;
use Drupal  commerce_promotion  Entity  PromotionInterface;
use Drupal  Core  Entity  EntityInterface;

/ **
* @CommercePromotionOffer (
* id = "my_module_fixed_amount_target",
* label = @Translation ("Discount each product corresponding to a fixed amount"),
* entity_type = "commerce_order_item",
* /
The OrderItemFixedAmountTarget class extends OrderPromotionOfferBase {

use FixedAmountOffTrait;

/ **
* {@inheritdoc}
* /
applicable public function (entity EntityInterface $, promotion PromotionInterface $) {
$ this-> assertEntity ($ entity);
/ ** @var  Drupal  commerce_order  Entity  OrderInterface $ order * /
$ order = $ entity;
$ subtotal_price = $ order-> getSubTotalPrice ();
$ amount = $ this-> getAmount ();
if ($ subtotal_price-> getCurrencyCode ()! = $ amount-> getCurrencyCode ()) {
he came back;
// The amount of the promotion can not be greater than the subtotal, to avoid
// potentially have a total of negative order.
if ($ amount-> greaterThan ($ subtotal_price)) {
$ amount = $ subtotal_price;
// Divide the amount between the items in the order.
$ amounts = $ this-> divisor-> division ($ order, $ amount);

foreach ($ order-> getItems () as $ order_item) {
yes (isset ($ amounts[$order_item->id()])) {
$ order_item-> addAdjustment (new Adjust (

& # 39; type & # 39; => & # 39; promotion & # 39 ;,
// @todo Switch to label from the user interface when added to # 2770731.
& # 39; label & # 39; => t (& # 39; Discount & # 39;),
& # 39; quantity & # 39; => $ amounts[$order_item->id()]-> multiply (& # 39; - 1 & # 39;),
& # 39; source_id & # 39; => $ promotion-> id (),


Name: & # 39; Custom promotion conditions & # 39;
type: module
Description: Provides personalized offers and conditions & # 39;
Core: 8.x
Package: & # 39; Customized & # 39;
- trade: trade
- commerce: commerce_order
- drupal: options


<? php

/ **
* @case file
* Contains my_module_custom_promotion.module.
* /

use Drupal  Core  Routing  RouteMatchInterface;

/ **
* Implement hook_help ().
* /
function my_module_custom_promotion_help ($ route_name, RouteMatchInterface $ route_match) {
switch ($ route_name) {
// Help of the main module for module my_module_custom_promotion.
case & # 39; help.page.my_module_custom_promotion & # 39 ;:
$ output = & # 39; & # 39 ;;
$ exit. = & # 39;

& # 39; t (& # 39; About & # 39;). & # 39;

& # 39 ;; $ exit. = & # 39;

& # 39; t (& # 39; My awesome module & # 39;). & # 39;

& # 39 ;; returns $ output; default: } } / ** * Implement hook_theme (). * / function my_module_custom_promotion_theme () { he came back [ 'my_module_custom_promotion' => [ 'render element' => 'children', ], ]; }

I did the best I could, but I can not understand what I am doing wrong and because of this "name that is already in use" error. I've searched the entire project just in case, but the text "OrderItemFixedAmountTarget" is only used in this file.

CentOS 7 LAMP Server Tutorial Part 5: Accelerate WordPress with Redis

In the LAMP server tutorials of CentOS 7 above, we configured a LAMP stack, secured it with SSL encryption certificates and installed WordPress with WP-CLI. Here, in Part 5, we're going to improve our game a bit more by installing server-side caching with a program called Redis. Then, we will configure WordPress to use Redis and check our performance to see if Redis really had an impact. Let us begin!

According to redis.io, Redis is a "data structure store" that is used as an in-memory database. Because it stores information (called "objects") in memory, it saves the server the hassle of having to search its database. In this way, it serves as a cache, and as such can help the server to handle more traffic without having to work harder to do so.

By default, WordPress does not know how to use Redis. We're going to let WordPress use Redis by installing a WordPress caching add-on called "W3 Total Cache." First, we need to install Redis and start.

Redis is available in the CentOS software repository "Additional Packages for Enterprise Linux" (EPEL). If you have followed this series of tutorials from the beginning, then the CentOS EPOS repository is already enabled. If not, you must enable it now with the following command:

yum -and install epel-release

Now you are ready to install Redis. It's very easy, just a quick installation of Yum. Execute the following command:

yum - and install redis

This is how it looked in our VPS:

With Redis already installed, we need to start Redis for the first time and configure CentOS to start Redis at startup. Execute the following commands:

systemctl start redis
systemctl enable redis

This is how those commands looked in our VPS:

Finally, we must make sure that Redis has really started and that it is accessible. Like the default PHP-FPM configuration, Redis listens on the IP "localhost" ( on a specific port (6379). Other programs can communicate with Redis when making a connection to that IP and port.

Let's try that communication now using the redis-cli program. Just as you can ping an IP with the "ping" command, you can also ping Redis with the "redis-cli ping" command. If Redis is running correctly, it will simply respond with "PONG". Give it a try:

redis-cli ping

Ours was working properly, and here is how it looked:

If you have "PONG", then great! Redis is running and you are ready to configure WordPress to take advantage of it. Almost. First, we need PHP to be up to date.

Now that we know Redis is working, we need to give PHP the ability to talk to Redis. Fortunately, this is as simple as installing the PHP 7.3 Redis extension and restarting PHP-FPM. If you have followed our tutorial, the following commands will do the work:

yum -and install php73-php-redis
systemctl restart php73-php-fpm

As mentioned above, WordPress does not have the know-how to use Redis. It also has no integrated cache. We will solve both problems when installing the W3 Total Cache plugin for WordPress. Log in to your WordPress Control Panel and go to Add-ons> Add New. Search for "W3 Total Cache" and click "Install Now" as shown below:

Click on Enable to enable W3 Total Cache. You will see a new menu item in the WordPress Panel: "Performance." Click on Performance> General to access the full cache settings of W3.

Go to each cache configuration and enable it, and select "Redis" from the drop-down menu if available. If Redis is not available in any of the pull-down menus and is grayed out, it is likely that Redis is not installed, running or enabled in PHP. You must return to the previous steps taken before continuing.

Once all the caches have been enabled and Redis is selected, click "Save all configurations" as shown below:

Check the function of your site. If your site is not viewed correctly, you may need to change the Minification settings, as they can often cause problems with CSS and Javascript. It will take a bit of trial and error. Once your site is working properly, we can continue.

Setting up WordPress for Redis really is that easy! But it does not tell us if it is doing us any good. We want to know: Is Redis doing its job and is having an impact on speed? Let's find out!

To know if Redis is having a positive impact on your site, we will have to do some load testing. For that we use LoadImpact.com. Your free account will allow you to use up to 50 virtual users for 12 minutes at a time to load your site. We set up a test for 50 virtual users (VU) for 3 minutes using the "Stress" increase settings as shown below:

Both tests were executed with W3 Total Cache installed. The "Disk Caching" test was performed with W3 Total Cache configured for "Disk" or "Disk: Enhanced". The "Redis Caching" test was performed with Redis configured as mentioned above. You can see the results in the table below. Disk caching is blue, while Redis caching is red, of course.

With disk caching enabled, our WordPress site handled 27 requests per second with an average response time of 22 ms. For a single-core VPS with 512 mb of RAM, this fine.

When we reconfigured the site to use Redis, there was a very good improvement. The server was able to handle 35 requests per second, with an average response slightly higher than 34 ms. The largest response time is probably due to the server being busy handling many more requests. Still, 34ms is pretty good and completely acceptable.

On the other hand, 35 requests per second vs. 27 is VERY good. It's a 30% increase in performance, and all we had to do was install and configure Redis.

Although we have covered the general installation and the use of Redis, we have only scratched the surface. Redis can be configured in many different ways. It is possible to make an adjustment to obtain greater performance, and the fine adjustment for your specific requirements can produce even better results. You can learn more about Redis in the official Redis documentation: https://redis.io/documentation

Not quite! There is still more performance. In the next installment of this series, we will make even more use of caching by replacing Apache with a caching web server called Nginx (pronounced "Engine-X"). Check back soon!

Package management tutorial: apt, yum, dnf, pkg

In this tutorial, we will give you an overview of the package management utilities in Ubuntu and Debian, Centos, Fedora and FreeBSD. Once you install, for example, Apache and Nginx, PHP, a MySQL database, all these systems begin to behave similarly. The main difference is in the tools for the administration of packages and this is how most of the newcomers to the VPS boxes decide in which server to run their sites and applications.

What we are going to cover

  • suitable Utility for Debian and Ubuntu
  • mmm for Centos
  • DNF for fedora
  • pkg for FreeBSD

and for each of these will show how

  • find help / read manual,
  • install a package,
  • delete it,
  • find the package in a repository,
  • eventually verify the vulnerabilities and so on.


If you want to test the commands, you will need

  • root user access, as well as the ability to
  • SSH in the VPS.

Basic functions of package managers

Windows users download their applications from websites and each application is responsible for updates and security patches. Linux is different: all applications wait in calls repositories to be downloaded and installed. They are called programs that download and install the packages. package managers and each Linux distribution will have its own repository and the corresponding package manager. For the most popular systems, such as Ubuntu, there are repositories for each major version, for example, 14.04, 16.04 and so on. The call backport repositories can also exist, when a newer version of the package, say from Ubuntu version 16.04, is "back" to the repository for Ubuntu version 14.04.

Unlike Windows users, Linux would not even care what version is installed. The package manager would choose the appropriate version and take care of the rest of the process. Some software companies deliver installation files directly, for example, in Debian, but there are also lower level commands to handle these cases.

The package manager can search the repository so you can see if the package you want to install is there. It is also possible to test what would change in the system if you installed a package, which can be of vital importance in certain cases.

The same package manager can remove the installed package from the system cache and can also uninstall the application completely. If there is a newer version in the repository, in the SPV, the package can be updated in the run.

APT for Debian / Ubuntu

For systems similar to Debian, including Ubuntu, it is called the basic high-level package manager suitable. Its lower-level counterpart, to deal with particular files is called dpkg. The file type is .debutante.

suitable It is a relatively new service, and gained prominence with Ubuntu 16.04. The name of the package manager that was previously used is apt-get. To make things even more confusing, the set of tools that Debian uses to manage packages is called APT, which is not the suitable What we are talking about here

suitable was introduced to simplify the management of packages for normal users. It has more default values ​​and is easier to use than apt-get. apt-getHowever, it is not going anywhere and can still be used without problems. In this tutorial, we will use suitable only.

How to get help on apt Package Manager

The command to read the documentation about suitable is

fit help

You will have the most popular commands at a glance:

How to update the server

The package managers read the repository files to the system cache. The command is:

sudo apt update

Run that in the Debian box. Dozens of output lines will be produced, ending with

Note that it says that there are 3 packages that must be updated. run

apt list - upgradeable

to see the complete list.

Running the same update command in Ubuntu 19.0 will produce a different result:

Under Ubuntu, there will be 65 packages to update.

The full version of the server will be updated with:

sudo apt update

The command

sudo apt full update

it will perform a full update, which means that the dependencies of conflicting packages will be updated to the most recent version, eliminating at the same time the old or unused dependencies.

Update and update in a line

Following the recipes for installing the software for your VPS, you will often see the following line:

sudo apt update && sudo apt upgrade

that both updates and updates the server. That way, you are guaranteed to have the latest version of the software for installation.

Software installation

You can search the software to install:

sudo apt search packageName

The result may not be as usable, as it may consist of dozens of available packet lines. You may want to copy the contents of the terminal window into a text editor and look up the name of the package.

To install the software, the command is:

sudo apt install packageName

For example, running

sudo apt install perl

in Debian, let me install a new module for the programmins language perl, whereas in Ubuntu nothing needed to be installed as

Perl is already the most recent version (5.28.1-6).

suitable you can not install software from a URL, but the lower level package RPM can. However, installation from repositories is always more secure.

Remove packages with apt

To remove a package:

sudo apt remove packageName

suitable it will eliminate the unused dependencies, but in case there are still some, here is another command:

sudo apt autoremove

How to list all installed packages:

list of apt - installed

Yum Package Manager at Centos

mmm is the Centos package manager, a security-oriented version of Red Hat Linux. File format is .rpm. mmm install or update the dependencies of any package, which is the main benefit of its use. mmm It will download packages from the official repositories, but you can also configure your own repositories on systems that do not have access to the Internet.

How to get help on yum Package Manager


yum help

The first screen lists all the commands:

The second screen shows the available parameters for mmm:

How to update the server with Yum

the to update The Yum command updates and updates the system:

sudo yum update

Even if the installation of your server is only one day old, as is the case here, there will be something new to update and install:

He will ask for your approval, once or twice; answer Y if you want the installation to continue.

WARNING: For longer transactions, it may appear that the terminal is dead (nothing happens in your window). Be patient and wait. Otherwise, when another transaction is launched, Centos will ask you to finish the previous transaction first. Or, you can clean with the command like:

yum-complete-transaction --cleanup-only

Software installation with Yum

To find an installable package:

sudo yum search packageName

Install a package with the following command:

sudo yum install packageName

NOTE: mmm will be FOREVER Install the latest version of the kernel.

Deleting packages with yum

Delete a package with:

sudo yum remove packageName

mmm It includes three commands to eliminate the packages:

  • autoremover will completely erase any trace of the previous configuration.
  • remove will keep a local copy of the configuration files / directories that were changed from the default values ​​during installation.
  • delete is the same as remove.

DNF package manager in Fedora

While Centos is a free version of Red Hat Linux, Fedora is like a research and development lab for those two systems. As of version 22 of Fedora, DNF has replaced mmm as an official package manager and it is likely that one day the same will happen in Centos. DNF it should serve as the improved version of mmm so the commands will be similar.

With DNF, maintenance of groups of machines is made easier, so it is not necessary to manually update each one using rpm. As well

  • supports multiple repositories
  • applications stripping Technology for dependency calculations.
  • runs faster and takes less memory than mmm
  • about .RPM files consistently
  • is written in Python and runs in both Python 2 and Python 3
  • It has its own add-ons, which can modify its behavior and introduce new commands.

How to get help on DNF Package Manager

The command is:

dnf help

Here is a list of the main commands that it supports:

And this is the list of add-ons and a partial list of optional arguments:

How to update the server with DNF

To update and update all the software:

sudo dnf update

As usual, answer Y when asked if you want to continue with the installation.

There is also a command

dnf check-update

but you do not need to do this as DNF Update your cache automatically before making transactions.

Installing packages with DNF

Search for an installable package:

sudo dnf search packageName

To install a package:

sudo dnf install packageName

Deleting packages with DNF

To remove a package:

sudo dnf remove packageName

the autoremover The command will search the entire system and eliminate the unused dependencies:

sudo dnf autoremove 

This is the warning he sent me:

so be sure to always add the name of the package you want to remove automatically:

sudo dbf autoremove packageName

Differences between the apt and BNF commands

Here is a comparison between suitable Y DNF commands:

Ubuntu command Fedora Command
apt update dnf check-update
apt update dnf update
apt dist-upgrade dnf system update
proper installation dnf install
apt to remove dnf remove
apt debug N / A
apt-cache search search dnf

Management of packages with PKG in FreeBSD

FreeBSD has two ways to install software:

  • packages, which is similar to the installation .debutante packages in Ubuntu / Debian and .rpm in Centos / Fedora, and
  • ports that makes software from the source, and is not explained in more detail in this tutorial.

The main difference is that pkg will install only the binary packages.

How to get help on pkg Package Manager

The command is

pkg help

How to update the server with pkg

freebsd-update fetch install
pkg update && pkg upgrade

Press Y when asked if you want to install.

Installing packages with pkg

Search a package:

pkg search packagename

Install a package:

pkg install packagename

This is what you are installing. nginx It seems:

List of installed packages:

package information

Update from the remote repository:

pkg update

Remove an installed package:

pkg delete packageName

Dependency checking

Check for missing dependencies:

pkg check -d -a

Remove unnecessary dependencies:

pkg autoremove

Automatic and non-automatic packages

List of non-automatic packages:

query pkg -e & # 39;% a = 0 & # 39;% o

List of automatic packages:

query pkg -e & # 39;% a = 1 & # 39;% o

Change a package from automatic to non-automatic, which will prevent autoremover to remove it:

pkg set -A 0 packageName

Change a package from non-automatic to automatic, which will cause autoremover It will be removed once nothing depends on it.

pkg set -A 1 packageName

Safety notices

Audit installed packages for security notices:

pkg audit

And here is the result:

the audit The command goes to the FreeBSD vulnerability database and reads from there. Here is how the legible form looks:

Now we must wait for the updated version to appear and then use the to get better command to patch it.

Dusko Savic is a writer and technical programmer.


CentOS 7 LAMP Server Tutorial Part 4: WordPress and wp-cli

Welcome to the fourth installment of CentOS 7 LAMP Server Tutorial: Modernized and Explained series. In Part 1 and Part 2 we configure a LAMP server with PHP-FPM with PHP 7.3 and a modern version of MariaDB. Then we set up a single VirtualHost to host a website, and in Part 3 we set up that VirtualHost to run securely with a free SSL encryption certificate from Let.

In this bit, we are going to put into practice our new and brilliant server by installing WordPress. We will also learn how to use a tool that will allow us to install, configure and maintain WordPress directly from the command line.

The WordPress command-line interface

As its name clearly indicates, the WordPress command-line interface (or wp-cli) is a command-line administration for WordPress. Why would you want such a thing? Good question!

Linux server administrators are known for preferring to do things without having to leave the command line. Changing from a command line to a GUI or web interface is seen as inefficient at best. But there are more than just basic efficiencies. The command line interface can be automated with shell scripts that allow us to perform tedious tasks without having to click on the mouse button.

In addition, there are tasks that can be performed through wp-cli that would otherwise require editing the WordPress database directly or through the use of third-party add-ons. You can reset passwords, search and replace databases, and many more are available. Let's install it!

Installing wp-cli

Before installing wp-cli, we must meet a prerequisite. In the first article of this series of LAMP tutorials, we configure PHP 7.3 to work from the command line with

scl enable php73 bash

What we did not do was configure the necessary associations so that PHP 7.3 works the same from the command line as through Apache. In its current state, PHP can not access MySQL databases. Let's solve it now. Paste the following commands:

threw out #! / bin / bash >> /etc/profile.d/php73.sh
echo source / opt / remi / php73 / enable >> /etc/profile.d/php73.sh
echo export X_SCLS = "` scl enable php73 & # 39; echo $ X_SCLS & # 39; `" >> /etc/profile.d/php73.sh

Now we're good to go. Installing wp-cli could not be easier. Log in to your server as root and paste the following commands:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod + x wp-cli.phar
mv wp-cli.phar / usr / local / bin / wp

You can test your new wp-cli installation simply by typing the "wp" command on the command line:

The help documentation will be loaded into a Linux program called Less so you can scroll through it with the arrows up and down on your keyboard. Go ahead, take a look at the page and check the capabilities of wp-cli. Press q to exit.

Installing WordPress in our VirtualHost

You will remember that we created a VirtualHost called lowend-tutorial.tld with the username "lowend". Now let's create a database that matches that username for no other reason to associate the two in our heads. We are also going to create a MySQL user with a unique password so that a non-root user can access the database. This is a extremely Important step You should never access your databases as root! You will want to replace your own information, of course.

Creating the database and the user

To create the database, we will need to change to the MySQL interface (MariaDB) by simply typing

mysql -u root -p

We are logging in as root here because only the root user can add databases and database users. Edit the following command to match your own username and the chosen password, and paste it into:

create low-end database;
GRANT ALL PRIVILEGES IN lowend. * TO & # 39; lowend & # 39; @ & # 39; localhost & # 39; IDENTIFIED BY & # 39; Your-DB-Password & # 39 ;;
discard all privileges;

In these three commands, we created the database, created a user and gave it full access to the "low cost" database and all its tables. Then we discard the privileges to enact the changes. This is how it looked in our VPS:

Be sure to keep the name of the database, the username and password. We will need it to install WordPress. Exit the MySQL interface by simply typing "exit" and pressing Enter.

The typical method of installing WordPress is to download the files to the public_html directory and then go to the website in a browser to complete the installation. The wp-cli program allows us to omit all that and perform the installation from the command line.

First, switch to your VirtualHosts user and then to your public_html directory.

su - lowend
cd ~ / public_html /

This is the same public_html folder that we used to verify that PHP was running in Part 2 with the file "test.php". If that file still exists, it would be good to delete it.

rm test.php

With the public_html directory now empty, we will begin the installation of WordPress. First we need to use wp-cli to download the main WordPress files:

download wp kernel

If you now type "ls" you will see all the basic WordPress files. Now we have to configure WordPress. The main WordPress configuration file is wp-config.php, and it contains all the information that WordPress needs to communicate with the database, and more. You will see that it does not exist yet. We will use wp-cli to create it and then change its permissions so that they are correct. Edit the following command to match your configuration, then paste it into:

wp core config --dbhost = localhost --dbname = lowend --dbuser = lowend --dbpass = Your-DB-Password
chmod 644 wp-config.php

Now WordPress knows how to talk to your database, but that database is still empty. WordPress now needs an identity and its first administrator. We are going to configure those that use wp-cli and we will establish some permissions. Again, edit the following to match your own settings and paste it. Be sure to use your real email address and set a secure password! You can be sure that as soon as you install WordPress, there will be bots that will try to log in to it. It is also recommended that you do not use "wordpress_admin" as your user name for the administrative user. Choose something unique.

wp core install --url = https: //lowend-tutorial.tld --title = "LowEnd Tutorial Site" 
--admin_name = wordpress_admin --admin_password = Your-DB-Password 
chmod 755 wp-content / uploads

Here is how it looked on our server:

Now, we can prove that our new website works by simply visiting it in a browser: https: //lowend-tutorial.tld. Check it out and come back when you're finished.

Works? Cool! Otherwise, check for errors along the way and examine them for typographical errors or errors.

It's time to login at https: //lowend-tutorial.tld/wp-admin. Log in with the username and password that you created with wp core install. Once you have logged in, go to Settings> Permalinks> select Publish name and then Save the changes as shown below:

Changing the structure of Permalinks (the way WordPress assigns a URL to a page or blog post) ends things by writing the .htaccess file that is necessary for many other WordPress functions. The reconfiguration of the permanent links can be done through wp-cli, but when we tried it, the .htaccess file was not written. Your WordPress installation is now ready to become an awesome website. Well done!

Wait, is that all?

Yes, you did it! You built a LAMP server with PHP 7.3, secured it with an SSL encryption certificate that was automatically renewed and installed WordPress. However, rest assured that we will not stop here.

A few other things …

In this series, he installed a user, a VirtualHost, an SSL certificate and a website. But, if you create a second user, a second VirtualHost and a second PHP-FPM configuration file, you can host a second website on your server! And a third, and a fourth, and … as many as your server can handle! The process can even be automated with some simple shell scripts.

Next, we'll do fun things, like configuring Redis and then switching to Nginx instead of Apache. Stay tuned!

CentOS 7 LAMP Server Tutorial Part 3: Let's Encrypt SSL

Welcome to the third installment of CentOS 7 LAMP Server Tutorial: Modernized and Explained series. This tutorial is based on the work done in Part 1 and Part 2, so if you have not reviewed them, this is a good time.

In this release, we will secure our new virtual host (lowend-tutorial.tld) ​​with an encrypted SSL certificate from Let. We will install WordPress in Part 4. It will be good to have an SSL certificate installed before installing WordPress.

We will see how the Encrypt SSL certificate is installed and how we can use the certificate. Let us begin!

If you are not familiar with Let's Encrypt, take a moment to visit their website at https://letsencrypt.org/. They are a Certification Authority that offers free SSL certificates to anyone who can prove that they own the domain for which they are trying to obtain an SSL certificate.

The way they do it is through the ACME protocol. You can read more about this on your site, but it works like this: a program on the server (we'll talk about Certbot in a moment) places a code inside a file at http: //lowend-tutorial.tld/somefilename. Then he tells the servers of Let's Encrypt where that file is, and they go looking for it. If the URL exists and loads the encoded message, they know that the request came from the real lowend-tutorial.tld server and they issue a certificate.

That means that http: //lowend-tutorial.tld must be a functioning website before Let's Encrypt issues a certificate. In the last installment we had a job site although it had no content. That will work well for this purpose. As mentioned, the program that controls all this is called Certbot. It's incredible software that makes this whole process seem incredibly simple. Let's install Certbot!

For CentOS 7 we need to install both Certbot and the python module that Certbot uses to integrate with Apache. Use the following command:

yum -y install certbot python2-certbot-apache

Before we can run Certbot and get an SSL certificate from Encrypt, we need to do a little more configuration. HTTPS (SSL) connections occur on port 443 (compared to port 80 for unsecure HTTP connections), so we must allow port 443 to pass through the firewall. Firewalld knows the association between port 443 and https, so we can only enable "https" in Firewalld. Paste the following commands:

firewall-cmd --zone = public --add-service = https --permanent
firewall-cmd - upload

Certbot is smart and knows that we are running the Apache web server, and besides, it is smart enough to know it. how We are running Apache. Actually read the configuration files and react accordingly. You will remember that we created a new Apache VirtualHost in /etc/httpd/sites-enabled/lowend-tutorial.tld.conf. This configuration file is responsible for mapping http: //lowend-tutorial.tld to / home / lowend / public_html and make PHP work.

The first line of /etc/httpd/sites-enabled/lowend-tutorial.tld.conf It looks like this:

This VirtualHost is specific to port 80. But SSL happens on port 443, so it will be necessary to have a new VirtualHost for port 443. What do we need to do to configure everything? Let Certbot do his magic! On the command line, run certbot with the following command:


You will have to answer some questions. If you want your website to be automatically redirected to https: // you can configure it here or you can do it manually later in the website settings. This is how it looked in our VPS:

If you look in / etc / httpd / sites-enabled, you will see a new file, lowend-tutorial.tld-le-ssl.conf. An exam will show that the VirtualHost directive defines a VirtualHost on port 443 and that the entire VirtualHost file is wrapped in tags At the bottom there are some new lines related to SSL certificates. Here are the additions and changes:

... omitting original content from VirtualHost for brevity
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/lowend-tutorial.cf/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/lowend-tutorial.cf/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/lowend-tutorial.cf/chain.pem

You can see how the configuration is SSL-specific. SSL configuration is loaded and routes to SSL certificate files are now included. Certbot did all this for us, and even restarted Apache to enact the changes. Thanks, Certbot!

Let's see if everything worked. Upload your site in a browser, then change the URL to https: //. I should still charge. If not, check ACME errors carefully and make sure that the site was originally loaded with http: //. Also make sure that DNS points to the server correctly. These things explain most of the errors.

Like most good things, Let & # 39; s Encrypt SSL certificates do not last forever. They last 90 days and need to be renewed. If we ask Certbot to run regularly, it will automatically renew any SSL certificate that is less than 29 days from expiration. For that, we're going to use a cron job.

Cron jobs are automated tasks that run on a schedule that we define. These schedules are made in a tabulated file called "crontab". Linux has a built-in function to modify crontabs, but it is based on the use of its own text editor. We prefer nano because of its ease of use vs vim (feel free to disagree, we do not care!) And so we will establish it as our editor before starting to edit things:

echo "export VISUAL = nano"

Since we want this to be the case every time we start session, we will go ahead and add it to /root/.bash_profile. the .bash_profile file is a script that runs every time your user logs in:

echo "export VISUAL = nano" >> ~ / .bash_profile

Now let's edit the crontab file and add a job that will run every 12 hours:

crontab -e

With nano open, paste the following

1 * / 12 * * * certbot renew

That entry tells cron to execute the "certbot renew" command in the first minute of every 12 hours of each day. If there is a certificate that needs to be renewed, it will renew it for us as long as ACME can verify the domain again.

And with that, we're finished. He just installed Certbot, which installed an Encrypt SSL certificate on his CentOS 7 LAMP server. For more information, see the official Let's Encrypt and Certbot documentation. They are a treasure trove of information, especially if you need to solve problems:


In the next installment, we will install WordPress on our new LAMP server and learn to manage it without even leaving the command line. Stay tuned!

Earn $ 58 per day in Shopify without selling any product (Affiliate marketing tutorial) – Other opportunities to earn money

Shopify actually has one of the best affiliate programs (200% of commissions), and this tutorial will be based on getting references for shopify.

Here is the video version of this tutorial:


You will be doing a free course in shopify. You do not need to be an expert in shopify, just take a week or two to learn the basics, then combine the basic knowledge into a free course. People love free courses, that's why it's so effective. You can host your free course at Teachable.

Then, when people get the knowledge they need to start earning money with shopify, they will register through their link and you can expect to earn around $ 58 per person if the course is relatively good and you continue to provide value.

The good thing about this free course is that in Shopify you will also need some additional tools that also cost money. The best part is that these tools mostly have an affiliate program that you can use to earn even more money. The tools are, for example, automatic email responses, product research tools, in-store applications, espionage tools, etc.

Step 1. Set up your course.

Record your screen and talk about it. Showing your face is optional. Of course, you will have to design your free course for yourself, but I tell you that anyone can do this. In the free course, it would include something like:

-configure the store and launch it.
-Personalization of the store, brand, logos.
-apps to use
– Terms of service, return texts and additional menus.
-facebook / google pixels and other tools
-Collecting emails and email marketing. Get an answer
product research
– Obtaining traffic, social network automation tools, etc.
-ads, and spying ads.

Step 2. Accommodation.

Use Teachable and simply scroll down and you will find the free option. Or you can organize your course with builderall, clickfunnels or even free with the free test version of getresponse, (2 free landing pages). You can also use ontrapages if you only want to create a simple landing page (without collecting emails).

Step 3. The traffic.

1. Youtube Create tutorials on Shopify on YouTube and include the link to your store in the description. Go up every day to grow quickly and make sure you have good miniatures. An example of this is Hayden Bowles. Make your own version of some of your best videos and always try to do better.

2. Quora. The best option in my opinion, because you are not limited to the amount of fame you have. Anyone can produce a viral response, at any time. Start answering questions about & # 39; & # 39; Dropshipping & # 39; & # 39; and & # 39; & # 39; Shopify & # 39; & # 39; in the search bar. And be sure to rate it by the last questions. You really will not have the opportunity to compete for many opinions on older questions. Respond from 10 to 20 per day and include a link to your free course in some of your answers. Not all the answers Do not come forbidden.

3. Blogs The articles have the best potential in my opinion because they are like real estate online. They will simply sit there and give you clues about the autopilot. In addition, you can include several links in all articles.

4. Solo-ads. Creating an email list is one of the best things you can do. Use solo ads to sign up for your free course and create a solid email list at the same time. This costs money, however.

5. Facebook groups. Start your own fb group and only publish value. Invite other active members of other dropshipping groups. Then simply place your publication that has the link to your free course, so that each new member sees the link.

Step 4. Alternative method that makes you even more money.

Set up an email sequence in which you assign each individual part to the course every day. I recommend GetResponse for this. I show you the complete funnel and email sequence in the youtube video version of this guide.

The good thing about this is that you can also recommend another course or larger product at the end of your free course to which you are affiliated. I know Kevin David has an affiliate program for his courses. And they go for around $ 1000, I think.


[Tutorial] Drawing With Python (pyautogui) | Promotion Forum

Hello everyone, today I will show you how to draw a perfect rectangle in Paint (or any application / drawing program) with Python!
We will use & # 39; pyautogui & # 39 ;, which allows Python (do tests with Python 3.x +) to click, drag the mouse and type text. You can use this module to automate many things, including account records, game robots and, in this case, the drawing.
If you want to see how to draw a square instead of a rectangle, you can modify the code below or see how to draw a square in the Python tutorial.

Here is in action!


import pyautogui
distance = 50 # distance per line
def draw ():
pyautogui.click ();
pyautogui.dragRel (distance * 2, 0, duration = 0.5) # right
pyautogui.dragRel (0, distance, duration = 0.5) #down
pyautogui.dragRel (-distance * 2, 0, duration = 0.5) #left
pyautogui.dragRel (0, -distance, duration = 0.5) #up
continuecript = entry ("Press any key to continue or write & # 39; exit & # 39; to close")
if (continuecript! = & # 39; exit & # 39;):
to draw()
print ("Thanks for trying this!")

answer = input ("Are you ready to draw? Press any key to continue")
to draw()

Let's check the code!
On the one hand, you must make sure that pyautogui is installed on your system, so that you can use pip install pyautogui in your command line
The first line is: import pyautogui to make sure that our script can use it.

distance = 50 # distance per line

This allows us to declare how much each line of our rectangle should be!

def draw ():

We define our function as draw () and then we have our code inside the function.

pyautogui.click ();
pyautogui.dragRel (distance * 2, 0, duration = 0.5) # right
pyautogui.dragRel (0, distance, duration = 0.5) [HASH=17389]#down[/HASH]
pyautogui.dragRel (-distance * 2, 0, duration = 0.5) [HASH=17390]#left[/HASH]
pyautogui.dragRel (0, -distance, duration = 0.5) [HASH=17391]#above[/HASH]

In this segment, we are saying "click where the user's mouse is currently located". This starts with our line in Paint, for example.
Then we use dragRel () four times to drag our lines perfectly straight.
It works like this … dragRel (distanceX, distanceY, duration)
So, in the first line, we are saying that we want pyautogui to click where the mouse moves and then drag the mouse "distance" * 2 pixels (100) on the X axis, so we go to the right.
We say 0 for the distance And because we do not want the line to go up or down, only to the right.
We ask the script to do this in 0.5 seconds, so it's pretty fast, but we can also slow it down or faster.
In line 2, we have a distanceX of 0 that tells the script not to move left or right. DistanceY is a distance variable (50 pixels), so it knows to lower 50px. The duration remains the same for everyone.
Then we go to the left saying "go on the X-axis -100 (-distance * 2) pixels, and obviously do not go up or down".
Finally, we end up telling the mouse to move up by going -50 pixels on the Y axis to finish our rectangle.

The final result is a perfect rectangle.

continuecript = entry ("Press any key to continue or write & # 39; exit & # 39; to close")
if (continuecript! = & # 39; exit & # 39;):
to draw()
print ("Thanks for trying this!")

This last part of our function allows the user to draw another rectangle just after pressing any key. If you type exit, you will be grateful that they have tried the Python script and stop running.
This is so you can create a lot of perfect rectangle if you wish.

answer = input ("Are you ready to draw? Press any key to continue")
to draw()

Although our draw () function has the ability to continue, we do not start the actual function, so at the bottom of my Python file I have a simple input question to ask the user if he is ready to start.
You can place the mouse over the starting point of your rectangle and press enter on the command line. Then, the mouse will click where the mouse is floating (in Paint / Photoshop / whatever) and begin to draw.

CentOS 7 LAMP Server tutorial: modernized and explained [Part 1]

Welcome to another LowEndBox tutorial for Linux! In this publication, we will design and configure a high performance server that will allow you to run several websites using the latest available software. Our server will be based on CentOS 7. Linux Apache 2.4, SUBWAYariaDB (a bifurcation of MySQL) and PHP 7.3. This software combination is known as a "LAMP" stack.

Why would we want to manually configure a LAMP stack instead of installing a control panel like Virtualmin or cPanel that would do it for us? Sometimes we want to build a custom server with only the specific features we want. Or, we want to know how it works and all the software is configured. Maybe we want to save all the power of our server to serve the sites instead of devoting some overhead to the execution of a control panel. Whatever your reason, even a small low-end VPS can host several successful sites with a little configuration.

There are many LAMP stack tutorials around, of course. Some of them show you how to simply install Linux, Apache, MariaDB and PHP in a default configuration that is adequate to host a single website. In addition, many of them depend on the default installation of CentOS, which contains fairly obsolete software, such as PHP 5.4.

Let's intensify it a couple of steps. In this tutorial, we will show you how to perform a default installation of CentOS 7 and configure it with the latest software with a high performance configuration where you will be proud to host several websites. But we will not stop there. This tutorial will also help you understand. why we have made the design decisions that we are making and how All the components interact with each other.

In future publications, we will add features, so be sure to come back for more information later!

As mentioned, a LAMP server is simply Linux, Apache, PHP and MariaDB. To do it well, however, there are some things to keep in mind. One of the reasons why CentOS 7 is an incredible server operating system is that it promotes stability and security over everything else. As a result, the CentOS repositories provide PHP 5.4 and MariaDB 5.5, which is what was in effect when CentOS 7 was launched. These are very, very old versions of PHP and MariaDB. PHP 5.4 can no longer be used with modern software such as WordPress.

To solve these problems, we will configure our server to obtain the software from other repositories that make PHP 7.3 and MariaDB 10.3.15 (at the time of publication) available. For the sake of this tutorial, let's assume that the server has a unique IP address. Our own server is a 1-core VPS with 512 MB of memory and 15 GB of disk. Let us begin!

Log in to the control panel of your VPS provider and start by configuring the host name for your server. It has to be what is called "Full Domain Name" or FQDN. It will look like "server.your-domainname.tld". You must use a prefix as "server" before any name you choose. We will configure the hosting for "your-domainname.tld" later in the process.

Within the control panel of your VPS provider, they will provide you with the means to install the operating system of your choice. You will want to choose "CentOS 7 Minimal 64 bit" or something like that. This is what you see in our LowEndBox:

Record the root password and wait for the installation to complete. Once this is done, log in and configure your SSH keys. If you are not sure how to do it, do not worry. We have it covered in our other tutorial "Using SSH keys to connect to your VPS"

Now that you are connected, it is time to take care of some basic configuration needs. The first thing we have to do is disable SELinux. Use the following command to do that:

sed -i & # 39; s / SELINUX =. * $ / SELINUX = disabled / & # 39; / etc / selinux / config

Now restart the server (Simply type "restart" and press enter) and log in again. Let's make sure that SELinux is disabled with the "getenforce" command:

Disabled – perfect! Now we can continue with the following preparation: allow traffic on port 80 through the firewall. It is possible that your VPS provider has included "FirewallD", which is the built-in firewall of CentOS 7, but it is possible that they have not done so. Let's see first. Use the following command to determine if it is installed:

rpm -qa | grep firewalld

You should see the following result:

If it does not, then FirewallD must be installed with the following command:

yum - and install firewalld

Now you can open port 80 (http) and reload the firewall rules:

firewall-cmd --zone = public --add-service = http --permanent
firewall-cmd - upload

The last part of the preparation is to install software sources that will provide us with the most updated versions of PHP and MariaDB. Paste the following commands on your terminal:

curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | swipe
yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager - enable remi-php73
mmm fast makecache

Now that the initial configuration is done, we can start installing the things that will convert our minimal installation of CentOS 7 into a real LAMP server. To begin, we are going to install some basic utilities that we might need in the future, including the simple Linux nano text editor. Execute this command:

yum -and install sysstat lsof traceroute whois wget ftp nano yum-utils 

We are going to install Apache (the HTTP daemon, also called httpd) and MariaDB below:

yum -y install httpd mariadb-server mariadb mod_ssl

We want Apache and MariaDB to start automatically when the server is started, and we also want to start them now:

systemctl enable httpd.service
systemctl enable mariadb

systemctl start httpd.service
systemctl start mariadb

Now let's clean up the installation of MariaDB with the command "mysql_secure_installation". This is how it looked on our server:

Your current root password will be empty, so just press Enter. Now you will be asked to set a root password for MariaDB. This does do not It has to match the root password of the server. However, it is recommended to set a strong password just as you would for the Linux root user. Be sure to take note of the password you set, because it is vital to the operation and configuration of the server. Simply press Enter for the rest of the questions that the script does.

Your results should look like the following:

Apache is a modular program, but it does not know how to execute PHP scripts natively. A PHP script produces an output that Apache can pass to anyone who requests it, but PHP has to do the heavy lifting. For this, Apache has an interface called Common Gateway Interface, or CGI. The official Apache documentation explains it this way:

"The CGI (Common Gateway Interface) defines a way for a web server to interact with external programs that generate content, often referred to as CGI programs or CGI scripts."

Other methods came after CGI, including DSO, suPHP and FastCGI. For a deeper consideration of these technologies, we recommend this fantastic article by Chris Wiegman.

The PHP driver we are going to use is not mentioned in that article specifically, but the PHP FastCGI Process Manager (PHP-FPM) is an implementation of FastCGI. PHP-FPM is very fast, because PHP is always ready for Apache to give it something to do. It's safe, because PHP scripts run under the ownership of the website owner.

Now let's consider how we are going to configure Apache for hosting websites. There are two types of accommodation: virtual and non-virtual accommodation. Non-virtual hosting means that a website is directly linked to an IP address, so each website must have its own IP address. This is what you have if you load a website directly in / var / www / html after installing Apache. It also means that you are very limited to the number of websites that you can host on one server (one).

Virtual hosting means that the websites are linked to a domain name instead, and so all sites can use the same IP address. Each website will have its own Linux user, Apache configuration file and PHP-FPM configuration file. You can add as many virtual hosts as your server can handle, instead of being limited to just one website per server. We're going to go into the actual configuration job. We will explain it along the way.

We installed the Remi repository earlier because the Remi repository has everything we need to install PHP 7.3 with PHP-FPM. In addition to PHP-FPM, we will also install many of the most commonly needed modules, including the mysqlnd module that allows PHP to talk to MariaDB.

Paste this command in your SSH session:

yum -and install php73 php73-php-fpm php73-php-common php73-php-fpm php73-php-gd php73-php-json 
php73-php-mbstring php73-php-mysqlnd php73-php-xml php73-php-xmlrpc php73-php-opcache 
php73-php-pecl-ssh2 php73-php-gd php73-php-bcmath php-pear-Net-Curl.noarch php73-php-pecl-imagick 
php73-php-xml php73-php-xmlrpc php73-php-pecl-mcrypt

We also want to use PHP 7.3 from the command line, so we will invoke the utility of the software collection, which facilitates this task:

scl enable php73 bash

All the software is in place. Now is the time to add a new user to our server and set up a website for him, and then we will have our first virtual host fully configured and we can start hosting websites. Part 2 will be published soon, be sure to come back!