One place for hosting & domains


      How To Store WordPress Assets on DigitalOcean Spaces With Ubuntu 20.04


      DigitalOcean Spaces is an object storage service that can be used to store large amounts of diverse, unstructured data. WordPress sites, which often include image and video assets, can be good candidates for object storage solutions. Using object storage for these types of static resources can optimize site performance by freeing up space and resources on your servers. For more information about object storage and WordPress check out our tutorial on How To Back Up a WordPress Site to Spaces.

      In this tutorial, you’ll learn how to use a WordPress plugin that works directly with DigitalOcean Spaces as the primary asset store. The DigitalOcean Spaces Sync plugin routes the data of our WordPress media library to Spaces and provides you with various configuration options based on your needs, streamlining the process of using object storage with your WordPress instance.


      This tutorial assumes that you have a WordPress instance on a server you’ll use as a DigitalOcean Space. If you do not have this set up, you can complete the following:

      With these prerequisites in place, you’re ready to begin using this plugin.

      Modifying WordPress Permissions

      Throughout this tutorial, you will be working with the wp-content/uploads folder in your WordPress project, so it is important that this folder exists and has the correct permissions. You can create it with the mkdir command using the -p flag in order to create the folder if it doesn’t exist, and avoid throwing an error if it does:

      • sudo mkdir -p /var/www/html/wp-content/uploads

      You can now set permissions on the folder. First, set the ownership to your user (you will use sammy here, but be sure to use your non-root sudo user), and group ownership to the www-data group:

      • sudo chown -R sammy:www-data /var/www/html/wp-content/uploads

      Next, establish the permissions that will give the web server write access to this folder:

      • sudo chmod -R g+w /var/www/html/wp-content/uploads

      You will now be able to use our plugins to create a store in object storage for the assets in the wp-content/uploads folder, and to engage with your assets from the WordPress interface.

      Installing DigitalOcean Spaces Sync

      The first step in using DigitalOcean Spaces Sync will be to install it in your WordPress folder. You can navigate to the plugin folder within our WordPress directory:

      • cd /var/www/html/wp-content/plugins

      From here, install DigitalOcean Spaces Sync using the wp command:

      • wp plugin install do-spaces-sync

      To activate the plugin, you can run:

      • wp plugin activate do-spaces-sync

      From here, navigate to the plugins tab on the left-hand side of our WordPress administrative dashboard:

      WordPress Plugin Tab

      You should see DigitalOcean Spaces Sync in your list of activated plugins:

      Spaces Sync Plugin Screen

      To manage the settings for DigitalOcean Spaces Sync, navigate to our Settings tab, and select DigitalOcean Spaces Sync from the menu:

      Settings Tab

      DigitalOcean Spaces Sync will now give you options to configure your asset storage:

      DO Spaces Sync Configuration

      The Connection Settings field in the top half of the screen asks for your Spaces Access Key and Secret. It will then ask for your Container, which will be the name of your Space, and the Endpoint.

      You can determine the endpoint of your Space based on its URL. For example, if the URL of your Space is, then example-name will be your bucket/container, and will be your endpoint.

      In the plugin’s interface, the Endpoint section will be pre-filled with the default You should modify this endpoint if your Space lives in another region.

      Next, you will be asked for File & Path Settings. In the field marked Full URL-path to files, you can input either a storage public domain, if your files will be stored only on your Space, or a full URL path, if you will store them on your Space and server.

      For example, if your WordPress project is located in /var/www/html, and you want to store files on both your server and Space, then you would enter:

      • http://your_server_ip/wp-content/uploads in the Full URL-path to files field
      • /var/www/html/wp-content/uploads in the Local path field

      The Storage prefix and Filemask settings are prefilled, and do not need to be modified unless you would like to specify certain types of files for your sync.

      You will cover the specifics of storing files on your server and Space and on your Space alone in the following sections.

      Syncing and Saving Files in Multiple Locations

      DigitalOcean Spaces Sync offers the option of saving files to your server while also syncing them to your Space. This utility can be helpful if you need to keep files on your server, but would also like backups stored elsewhere. For this tutorial, you will go through the process of syncing a file to your Space while keeping it on your server. For the purposes of this example, you will assume that you have a file called sammy10x10.png that you would like to store in your media library and on your Space.

      First, navigate to the Settings tab on your WordPress administrative dashboard, and select DigitalOcean Spaces Sync from the menu of presented options.

      Next, in the Connections Settings field, enter your Spaces Key and Secret, followed by your Container and Endpoint. Remember, if the URL of your Space is, then example-name will be your Container, and will be your Endpoint. Test your connections by clicking the Check the Connection button at the bottom of the Connection Settings field:

      Check Connection Button

      Now you are ready to fill out the File & Path Settings.

      In the Full URL-path to files field you can enter our full URL path, since you are saving your file on your server and on your Space. You’ll use your server’s IP here, but if you have a domain, you can swap out the IP address for your domain name. For more about registering domains with DigitalOcean, see our tutorial on How To Set Up a Host Name with DigitalOcean. In this case, the Full URL-path to files will be http://your_server_ip/wp-content/uploads.

      Next, you will fill out the Local path field with the local path to the uploads directory: /var/www/html/wp-content/uploads.

      Because you are working with a single file, you do not need to modify the Storage prefix and Filemask sections. As your WordPress media library grows in size and variety, you can modify this setting to target individual file types using wildcards and extensions such as *.png in the Filemask field.

      Your final File & Path Settings will look like this:

      Sync Server and Cloud

      Be sure to save your configuration changes by clicking the Save Changes button at the bottom of the screen.

      Now you can add the file, sammy10x10.png, to our WordPress media library. You’ll use the wp media import command, which will import the file from your home directory to your WordPress media library. In this case, your home directory will belong to sammy, but in your case this will be your non-root sudo user. As you move the file, you will use the --path parameter to specify the location of our WordPress project:

      • wp media import --path=/var/www/html/ /home/sammy/sammy10x10.png

      Looking at the WordPress interface, you should now see the file in your Media Library. You can navigate there by following the Media Library tab on the left side of our WordPress administrative dashboard:

      Media Library Tab

      If you navigate to your Spaces page in the DigitalOcean control panel, you should also see the file in your Space.

      Finally, you can navigate to our wp-content/uploads folder, where WordPress will have created a sub-folder with the year and month. Within this folder you should see our sammy10x10.png file.

      Storing Files on Spaces

      The DigitalOcean Spaces Sync plugin has an additional option that will allow you to store files only on your Space, in case you would like to optimize space and resources on our server. You will work with another file, sammy-heart10x10.png, and set your DigitalOcean Spaces Sync settings so that this file will be stored only on your Space.

      First, let’s navigate back to the plugin’s main configuration page:

      DO Spaces Sync Configuration

      You can leave the Connection Settings information, but will modify the File & Path Settings. First, in the Full URL-path to files, you will write the storage public domain. Again, you will use your server IP, but you can swap this out for a domain if you have one: http://uploads.your_server_ip

      Next, navigate to Sync Settings, at the bottom of the page, and click the first box, which will allow you to “store files only in the cloud and delete after successful upload.” Your final File & Path Settings will look like this:

      Sync Cloud Only

      Be sure to save your changes by clicking the Save Changes button at the bottom of the screen.

      Back on the command line, move sammy-heart10x10.png from your user’s home directory to your Media Library using wp media import:

      • wp media import --path=/var/www/html/ /home/sammy/sammy-heart10x10.png

      If you navigate back to your WordPress interface, you will not see sammy-heart10x10.png or sammy10x10.png in your Media Library. Next, return to the command line and navigate to your wp-content/uploads directory — you should see that sammy-heart10x10.png is missing from your timestamped sub-folder.

      Finally, if you navigate to the Spaces page in the DigitalOcean control panel, you should see both files stored in your Space.


      This tutorial covered two different options you can use to store your WordPress media files to DigitalOcean Spaces using DigitalOcean Spaces Sync. This plugin offers additional options for customization, which you can learn more about by reading the developer’s article “Sync your WordPress media with DigitalOcean Spaces.”

      If you would like more general information about working with Spaces, check out our introduction to DigitalOcean Spaces and our guide to best practices for performance on Spaces.

      Source link

      How To Set Up WordPress Multisite with Nginx and LEMP on Ubuntu 20.04


      The WordPress multisite feature is a unique way to host and manage a suite of sites in one place, and is useful for projects or positions that call for the operation of several WordPress sites under one host. Multisite offers the ability to create multiple WordPress websites from a single installation of WordPress, with each site having a separate theme, set of plugins, and collection of content (typically posts and pages). This feature helps to reduce the overhead of maintaining and updating several installations of WordPress, while allowing you to host multiple sites which may be unrelated to one another.

      In this tutorial, you’ll set up a WordPress multisite on an Ubuntu 20.04 Droplet using subdomains. The WordPress sites that you’ll create will have a subdomain web address like, but your subdomain address can be mapped to an external domain like so that each site looks independent to users visiting your multisite suite of addresses.


      This tutorial requires you to have a basic knowledge of WordPress multisite. The following articles might be helpful in deepening your understanding of multisites:

      Step 1 — Installing WordPress

      For this tutorial, you’ll need to have access to a WordPress Droplet running the LEMP stack on Ubuntu 20.04. You can create a WordPress installation on a Droplet in the following ways:

      You can also follow this tutorial using a WordPress installation on a hosting provider, but keep in mind that the steps of this tutorial will reflect a WordPress multisite setup on a DigitalOcean Droplet.

      Before installing WordPress, you’ll need to set up DNS records for each intended WordPress site in your multisite installation. For this tutorial, create the following domain names:

      • Site 1:

        Domain: (Primary domain)

        This is the site that is created when WordPress is installed.

      • Site 2:

        External Domain:


      • Site 3:

        External Domain:


      The first domain is the primary domain name through which WordPress will be referenced. Make sure to set up DNS for all three domains to point to the IP address of the Droplet hosting WordPress.

      While installing, if you’ve chosen to use a Droplet with a LEMP stack, be sure to follow the instructions for setting up your database and users. For DigitalOcean WordPress 1-Click installations, this has already been configured for you.

      After installing WordPress on your Droplet, let’s assign file ownership to the user www-data. This is essential for media uploads and for core/plugin/theme updates to work in WordPress.

      Log in to your Droplet via the command line, then execute the following command, replacing the highlighted path with the full path to your WordPress installation:

      • chown -R www-data:www-data /var/www/wordpress/

      This command will grant read and write access to the www-data user for media uploads and necessary updates.

      In the next step, we’ll further configure the primary domain, then configure our multisite installation from there.

      Step 2 — Setting Up DNS Wildcard Records

      Let’s continue by adding a DNS wildcard record for the primary domain. Adding a wildcard record allows more WordPress sites to be added to your multisite installation at any time, without needing individual A records. Alternatively, you can choose to add a new A record for each subdomain.

      Log in to your DigitalOcean control panel and navigate to the Networking section. Edit the primary domain and create a wildcard A record for this domain pointing to the Droplet’s IP address. A wildcard record is created by entering an asterisk (*) in the hostname input box as shown in the following screenshot.

      DNS Control Panel - wildcard record

      If you host your domain’s DNS on a hosting provider, set the wildcard record using the registrar’s site.

      After setting the wildcard record, DNS queries for any should return the IP address of your Droplet.

      Step 3 — Enable Multisite and Create Additional Sites

      In this section, let’s now enable our WordPress multisite and create the two additional sites as mentioned in Step 1.

      To begin this process, a PHP constant has to be defined in the wp-config.php file to enable the Network Setup page.

      You can edit the wp-config.php file via the command line while logged into your WordPress Droplet. Open the file using your command line editor of choice. Here, we’ll use nano:

      • nano /var/www/wordpress/wp-config.php

      Add the following code before the comment /* That's all, stop editing! Happy blogging. */ or similar text:


          /* Multisite settings */
          define( 'WP_ALLOW_MULTISITE', true );

      Save and close the file. If you’re using nano, you can do that with CTRL+X, then Y and ENTER to confirm.

      Next, log in to the WordPress admin panel and navigate to Tools -> Network Setup. Choose the Subdomains option, modify the Network Title as desired, and then click Install.

      WordPress Network Setup

      You will be presented with two blocks of code to be added in the wp-config.php and .htaccess files. Because we are using Nginx, we won’t need to use the suggested .htaccess code, so you can ignore that for now.

      Copy the wp-config.php code which looks similar to the following:

          define('MULTISITE', true);
          define('SUBDOMAIN_INSTALL', true);
          define('DOMAIN_CURRENT_SITE', '');
          define('PATH_CURRENT_SITE', '/');
          define('SITE_ID_CURRENT_SITE', 1);
          define('BLOG_ID_CURRENT_SITE', 1);

      Next, open the wp-config.php file:

      • nano /var/www/wordpress/wp-config.php

      Include the code snippet you just copied, placing it before the comment that says /* That's all, stop editing! Happy blogging. */ (or a variation of text that advises not to write below it). Save the file when you’re done.

      Log out of the WordPress admin panel, and log in again. From the admin toolbar on the top left, navigate to the My Sites > Network Admin > Sites.

      WordPress Toolbar

      Click the Add New button to open the Add New Site form. The following screenshot shows the filled-in details for the shopping site in our example. The Site Address entered will form the subdomain of this site.

      Creating a new WordPress site

      Click Add Site and the created site will be accessible via

      Repeat these steps to create the second site ( in our example).

      The following three WordPress sites can now have its own content, theme, and active set of plugins:


      Step 4 — Setting Up Domain Mapping

      In this step, let’s enable multisite to use a separate domain name for each WordPress site by downloading and enabling the WordPress MU Domain Mapping plugin. This third-party plugin allows users of WordPress multisite to map their blog/site to another domain.

      To download this plugin,visit My Sites -> Network Admin -> Plugins from your dashboard and select Add New on your primary domain to find the WordPress MU Domain Mapping plugin.


      Install the plugin, then click the Network Activate link under the WordPress MU Domain Mapping plugin. Go to Settings -> Domain Mapping and make changes to the Domain Options as follows:

      • Uncheck Remote Login
      • Check Permanent Redirect
      • Uncheck Redirect administration pages to site’s original domain

      Domain mapping options

      Click Save once done. These settings redirect all requests for subdomains (like to their respective external domains (like including the administration pages (/wp-admin).

      In the next step, let’s map a domain name to each site based on its site ID. There are many ways to find the ID of a site, but for easier administration you’ll create a simple WordPress Must-use plugin that displays an additional ID column on the Sites page.

      Log in to your WordPress Droplet via SSH and create an mu-plugins directory.

      • mkdir /var/www/wordpress/wp-content/mu-plugins

      Create a PHP file inside this directory:

      nano /var/www/wordpress/wp-content/mu-plugins/wpms_blogid.php

      Next, copy the following content to your wpms_blogid.php file:


          add_filter( 'wpmu_blogs_columns', 'do_get_id' );
          add_action( 'manage_sites_custom_column', 'do_add_columns', 10, 2 );
          add_action( 'manage_blogs_custom_column', 'do_add_columns', 10, 2 );
          function do_add_columns( $column_name, $blog_id ) {
              if ( 'blog_id' === $column_name )
                  echo $blog_id;
              return $column_name;
          function do_get_id( $columns ) {
              $columns['blog_id'] = 'ID';
              return $columns;

      The Sites -> All Sites section should now show an additional ID column.


      Note down the ID values for each site and go to the Settings -> Domains page. Enter the site ID followed by the external domain for the site. For example, since companysite has an ID of 3, on this page, the Site ID should be 3, and the domain should be

      Mapping a site ID to a domain

      You may add a “www” prefix if you wish to set the site URL as Repeat these steps for the other domains. Click Save at the bottom of the page.

      Each site will now have its own domain name instead of a subdomain; i.e., entering in your browser will open the My Online Company site. You can check this now by visiting your additional domain names that are mapped. You should see the site title change in the upper left corner of the page.

      Now each site can be maintained separately through its own WordPress admin panel:

      - ``
      - ``
      - ``

      Updates to the core/plugins/themes and installation of plugins/themes should be done from the network admin page of the primary domain:

      - ``


      In this tutorial, you learned how to set up the multisite feature on a WordPress website running on Ubuntu 20.04 with Nginx (LEMP stack). The multisite feature enables you to host multiple WordPress sites on one WordPress installation on your droplet. You also learned how to set up domain mapping, which allows each of your subsites to be reached through a custom domain name.

      For an alternate process to install the WordPress multisite feature, visit our tutorial, Setting up WordPress Multisite on Apache.

      Source link

      How To Use Telepresence on Kubernetes for Rapid Development on Ubuntu 20.04

      The author selected the Tech Education Fund to receive a donation as part of the Write for DOnations program.


      Application developers building microservices on Kubernetes often encounter two major problems that slow them down:

      • Slow feedback loops. Once a code change is made, it must be deployed to Kubernetes to be tested. This requires a container build, push to a container registry, and deployment to Kubernetes. This adds minutes to every code iteration.
      • Insufficient memory and CPU locally. Developers attempt to speed up the feedback loop by running Kubernetes locally with minikube or the equivalent. However, resource-hungry applications quickly exceed the compute and memory available locally.

      Telepresence is a Cloud-Native Computing Foundation project for fast, efficient development on Kubernetes. With Telepresence, you run your service locally, while you run the rest of your application in the cloud. Telepresence creates a bi-directional network connection between your Kubernetes cluster and your local workstation. This way, the service you’re running locally can communicate with services in the cluster, and vice versa. That allows you to use the compute and memory resources of the cluster, but without having to go through a complete deployment cycle for each change.

      In this tutorial, you’ll configure Telepresence on your local machine running Ubuntu 20.04 to work with a Kubernetes cluster. You’ll intercept traffic to your cluster and redirect it to your local environment.

      To complete this tutorial, you will need:

      Step 1 — Installing Telepresence

      In this step, you’ll install Telepresence and connect it to your Kubernetes cluster. First, make sure that you have kubectl configured and that you can connect to your Kubernetes cluster from your local workstation. Use the get services command to check your cluster’s status:

      The output will look like this, with your own cluster’s IP address listed:


      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP <none> 443/TCP 116m

      Next you’ll install Telepresence locally. Telepresence comes as a single binary.

      Use curl to download the latest binary for Linux (around 50 MB):

      • sudo curl -fL -o /usr/local/bin/telepresence

      Then use chmod to make the binary executable:

      • sudo chmod a+x /usr/local/bin/telepresence

      Now that you have Telepresence installed locally, you can verify that it worked by connecting to your Kubernetes cluster:

      You’ll see the following output:


      Launching Telepresence Daemon ... Connected to context default (https://<cluster public IP>)

      If Telepresence doesn’t connect, check your kubectl configuration.

      Verify that Telepresence is working properly by connecting to the Kubernetes API server with the status command:

      You will see the following output. Telepresence Proxy: ON indicates that Telepresence has configured a proxy to access services on the cluster.


      Root Daemon: Running Version : v2.1.4 (api 3) Primary DNS : "" Fallback DNS: "" User Daemon: Running Version : v2.1.4 (api 3) Ambassador Cloud : Logged out Status : Connected Kubernetes server : Kubernetes context: <your_kubernetes_context> Telepresence proxy: ON (networking to the cluster is enabled) Intercepts : 0 total Connected Context: do-tor1-k8s-bg-telepresence ( Proxy: ON (networking to the cluster is enabled) Intercepts: 0 total

      When you use telepresence connect, on the server side, Telepresence creates a namespace called ambassador and runs a traffic manager. On the client side, Telepresence sets up DNS to enable local access to remote servers. That means you do not have to use kubectl port-forward to manually configure access to local services. When you access a remote service the DNS resolves to a specific IP address. For more details, see the Telepresence architecture documentation.

      You can now connect to the remote Kubernetes cluster from your local workstation, as if the Kubernetes cluster were running on your laptop. Next you’ll try out a sample application.

      Step 2 — Adding a Sample Node.js Application

      In this step, you’ll use a simple Node.js application to simulate a complex service running on your Kubernetes cluster. Instead of creating the file locally, you’ll access it from DockerHub and deploy it to your cluster from there. The file is called hello-node, and returns a text string:

      var http = require('http');
      var handleRequest = function(request, response) {
        console.log('Received request for URL: ' + request.url);
        response.writeHead(200, {'Content-Type': 'text/plain'});
        response.write('Hello, Node!');
      console.log('Use curl <hostname>:9001 to access this server...');

      Use the kubectl create deployment command to create a deployment called hello node:

      • kubectl create deployment hello-node --image=docommunity/hello-node:1.0

      You will see the following output:


      deployment.apps/hello-node created

      Use the get pod command to confirm that the deployment has occurred and the app is now running on the cluster:

      The output will show a READY status of 1/1.


      NAME READY STATUS RESTARTS AGE hello-node-86b49779bf-9zqvn 1/1 Running 0 11s

      Use the expose deployment command to make the application available on port 9001:

      • kubectl expose deployment hello-node --type=LoadBalancer --port=9001

      The output will look like this:


      service/hello-node exposed

      Use the kubectl get svc command to check that the load balancer is running:

      The output will look like this, with your own IP addresses:


      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-node LoadBalancer <pending> 9001:30682/TCP 4s kubernetes ClusterIP <none> 443/TCP 6d

      If you are using local Kubernetes without load balancer support, then the external IP value for LoadBalancer will show as <pending> permanently. That is fine for the purposes of this tutorial. If you are using DigitalOcean Kubernetes, you should see the external IP value will display the IP address after a delay.

      Next, verify that the application is running by using curl to access the load balancer:

      If you’re not running a load balancer, you can use curl to access the service directly:

      • curl <servicename>.<namespace>:9001

      The output will look like this:


      Hello, Node!

      Next, use the telepresence connect command to connect Telepresence to the cluster:

      This allows you to access all remote services as if they were local, so you can access the service by name:

      • curl hello-node.default:9001

      You’ll receive the same response as you did when you accessed the service via its IP:


      Hello, Node!

      The service is up and running on the cluster, and you can access it remotely. If you make any changes to the hello-node.js app, you’d need to take the following steps:

      • Modify the app.
      • Rebuild the container image.
      • Push it to a container registry.
      • Deploy to Kubernetes.

      That is a lot of steps. You could use tooling (automated pipelines, such as Skaffold) to reduce the manual work. But the steps themselves cannot be bypassed.

      Now you’ll build another version of our hello-node app, and use Telepresence to test it without having to build the container image or push it to registry or even deploy to Kubernetes.

      Step 3 — Running a New Version of the Service Locally

      In this step, you’ll modify the existing hello-node application on your local machine. You’ll then use Telepresence to route traffic to the local version with a Telepresence intercept. The intercept takes traffic intended for your cluster and reroutes it to your local version of the service, so you can continue working in your development environment.

      Create a new file containing a modified version of the sample application:

      Add the following code to the new file:


      var http = require('http');
      var handleRequest = function(request, response) {
        console.log('Received request for URL: ' + request.url);
        response.writeHead(200, {'Content-Type': 'text/plain'});
        response.write('Hello, Node V2!');

      Save and exit the file.

      Start the service with Node:

      Leave the service running, then open a new terminal window and access the service:

      The output will look like this:


      Hello, Node V2!

      This service is only running locally, however. If you try to access the remote server, it is currently running version 1 of hello-node. To fix that, you’ll enable an intercept to route all traffic going to the hello-node service in the cluster to the local version of the service.

      Use the intercept command to set up the intercept:

      • telepresence intercept hello-node --port 9001

      The output will look like this:


      Using deployment hello-node intercepted Intercept name : hello-node State : ACTIVE Destination : Volume Mount Error: sshfs is not installed on your local machine Intercepting : all TCP connections

      Check that the intercept has been set up correctly with the status command:

      The output will look like this:


      Root Daemon: Running Version : v2.1.4 (api 3) Primary DNS : "" Fallback DNS: "" User Daemon: Running Version : v2.1.4 (api 3) Ambassador Cloud : Logged out Status : Connected Kubernetes server : Kubernetes context: <your_kubernetes_context> Telepresence proxy: ON (networking to the cluster is enabled) Intercepts : 1 total hello-node: brian@telepresence-tutorial

      Now access the remote service with curl as you did previously:

      The output will look like this:


      Hello, Node V2!

      Now, any messages sent to the service on the cluster are redirected to the local service. This is useful in the development stage, because you can avoid the deployment loop (build, push, deploy) for every individual change to your code.


      In this tutorial, you’ve installed Telepresence on your local machine, and demonstrated how to make code changes in your local environment without having to deploy to Kubernetes every time you make a change. For more tutorials and information about Telepresence, see the Telepresence documentation.

      Source link