Wednesday, February 01, 2023

AppleScript to SSH

Create a file called ssh_server_name.scpt in a desired folder with the contents:

do shell script "open -a Terminal /bin/bash ~/Documents/server.sh"

To create an icon that you can click to run an AppleScript file. Here are the steps to do it:

  1. Save the AppleScript file with a .scpt extension to your desired location.
  2. Right-click on an empty area of your Desktop and select "New" > "Script".
  3. A new file with a .scpt extension will be created on your Desktop.
  4. Open the newly created file in the AppleScript Editor.
  5. Copy and paste the contents of your original AppleScript file into this new file.
  6. Save the new file.
  7. Right-click on the newly created file and select "Get Info".
  8. In the Info window, click on the icon in the top left corner.
  9. Press "Cmd + V" to paste the copied icon, or select a new icon from your computer.
  10. Close the Info window.
  11. Your new script file should now have the custom icon you selected.

Now you can double-click the icon on your Desktop to run the script.






Script to SSH into Servers

 Here is an example of a bash script that uses the ssh command to connect to a remote server at a specified IP address and password:


#!/bin/bash


# define the variables for IP and password

ip="192.168.1.100"

password="mypassword"


# use the ssh command to connect to the server

sshpass -p "$password" ssh -o StrictHostKeyChecking=no user@$ip


This script uses the sshpass command to pass the password to the ssh command. The -p flag specifies the password, and the -o StrictHostKeyChecking=no option is used to disable host key checking, which allows the script to connect to the server without prompting for confirmation.


You can replace the "user" with the username you want to use to connect to the remote server and replace the IP address and password with the actual values you want to use.


It's important to note that, hardcoding the password in a script is not a good practice, as it can be easily accessed by someone with access to the script. You should consider using ssh-key based authentication or storing the password in an encrypted file, and decrypting it only when needed.


You should also be careful when running scripts like this, as it can pose a security risk if used improperly.


The script I provided uses the sshpass command, which is not installed by default on macOS. sshpass is a command-line utility that allows you to provide the password for the ssh command non-interactively. Therefore, the script will not work as is on macOS.


However, the script can be modified to work on macOS by using the -A flag of the ssh command, which enables agent forwarding. This allows your local ssh-agent to handle the ssh-authentication and forwards your ssh-key to the remote host. This way you don't need to provide the password.


#!/bin/bash


# define the variables for IP

ip="192.168.1.100"


# use the ssh command to connect to the server

ssh -A user@$ip


But this approach has its own security risks, for instance, it requires the ssh-agent to be running and your ssh-key to be added to the ssh-agent. Also, you should be sure that you trust the remote host and it's network, as the agent forwarding exposes your ssh-key to the remote host and its network.


You should also consider using ssh-key based authentication, which is more secure and eliminates the need to use a password or a script that passes the password.


Hardcoding the password in a script is generally not considered a good practice, as it can be easily accessed by someone with access to the script. If the script falls into the wrong hands, the password could be used maliciously.


Additionally, hardcoding the password in the script can also pose a security risk if the password is not changed frequently, or if the password is used for other purposes as well.


That being said, if you still want to run the script on Mac OS and you are comfortable with the security risks involved, you can use the expect command in the script to automatically enter the password when prompted by the ssh command.


Here is an example of how you could use expect to run the ssh command and provide the password automatically:


#!/bin/bash


# define the variables for IP and password

ip="192.168.1.100"

password="mypassword"


# use the expect command to connect to the server

expect -c "

    spawn ssh user@$ip

    expect \"password:\"

    send \"$password\r\"

    interact

"


This script uses the expect command to spawn the ssh command and wait for the "password:" prompt. When prompted, it sends the value of the password variable to the server. The interact command allows the user to interact with the shell once the password has been sent.


Keep in mind that this script still has security risks, as the password is visible in plaintext and anyone who has access to the script will be able to see it.


It's important to note that, hardcoding the password in a script is not a good practice, as it can be easily accessed by someone with access to the script. You should consider using ssh-key based authentication or storing the password in an encrypted file, and decrypting it only when needed.


Here is an example of a bash script that uses the expect command to run the ssh command and provide the password automatically on macOS:


#!/bin/bash


# define the variables for IP and password

ip="192.168.1.100"

password="mypassword"


# use the expect command to connect to the server

expect -c "

    spawn ssh user@$ip

    expect \"password:\"

    send \"$password\r\"

    interact

"


As you mentioned, you have accepted the security risk of having the password hardcoded in the script, for the purpose of logging from your development machine to a staging server. But, you should be aware that this script can pose a significant security risk if it is shared with others or if the server's security is compromised.


It's important to remember to keep the script in a secure location and to limit access to it to only those who need it. It is also important to change the password frequently and to use a different password for other services.


Also, consider disabling the script or removing the password when it is no longer needed.


As an extra security measure, you can also use a command like chmod 700 script.sh to change the permissions of the script to only allow you, the owner, to execute and read the script.


Also, you should be aware that logging and monitoring the usage of the script is important, as it can give you an idea of who, when and how it was used, this can help you detect any malicious activity or misuse.



Using grep UNIX Command

 The UNIX command to search for a string in a log file is grep.


The basic syntax for using grep to search for a string in a file is:


grep "string" file.log


Where "string" is the text you want to search for, and "file.log" is the name of the log file.


grep is a powerful command and has many options that you can use to customize your search, some useful options are:


-i : case-insensitive search

-v : invert the match, it shows the lines that doesn't match the string

-n : shows the line number where the match occurred

-c : shows the number of matches

-r : search recursively through all subdirectories


You can also use the grep command to search for a string in multiple files at once by specifying multiple file names separated by a space.


grep "string" file1.log file2.log file3.log


It's also possible to use regular expressions with grep command, this allows you to search for patterns in the log file and not just a specific string.


grep -E "pattern" file.log


It's recommended to use the man command to read the manual page of grep and learn more about its functionalities and options.


Compare bugsnag and honeybadger

 Bugsnag and Honeybadger are both error monitoring and management tools that help developers identify and resolve issues in their applications. However, there are some differences between the two:

  1. Error tracking: Both Bugsnag and Honeybadger track errors in real-time, but Honeybadger provides additional features such as detailed error reports and the ability to categorize errors into different projects.

  2. Notification and alerting: Both tools offer notifications via email, SMS, and other channels, but Honeybadger provides additional alerting options such as Slack and PagerDuty.

  3. Integrations: Bugsnag integrates with a wide range of platforms and tools, including popular frameworks such as Ruby on Rails and React, as well as services like GitHub and Jira. Honeybadger, on the other hand, offers a smaller set of integrations but provides a more flexible API for custom integrations.

  4. Pricing: Both Bugsnag and Honeybadger offer flexible pricing plans, but Bugsnag tends to be more expensive for high-volume usage.

  5. Support: Bugsnag provides a comprehensive support package with email, live chat, and telephone support, while Honeybadger offers email support and a knowledge base.

These are some of the key differences between Bugsnag and Honeybadger. The choice between the two will depend on the specific needs and requirements of your project and organization.

How to monitor background jobs?

 Here are some ways to monitor background jobs:

  1. Job management tools: There are many job management tools available that can monitor your background jobs, manage their execution, and send notifications in case of any issues. Some popular tools include Sidekiq, Resque, and Celery.

  2. Monitoring tools: You can use monitoring tools such as Nagios, New Relic, or Datadog to monitor your background jobs and receive notifications in case of any issues.

  3. Logging: You can log the output of your background jobs and check the logs regularly for any errors or unexpected results. This can be done by redirecting the output of your job to a file, or by using a logging library in your application.

  4. Job status tracking: You can track the status of your background jobs by storing the status in a database and periodically checking the status. This can be done by writing a custom script or using a job management tool.

  5. Health checks: You can implement health checks for your background jobs to monitor their status and receive notifications in case of any issues. This can be done by writing a custom script or using a monitoring tool.

These are some of the ways you can monitor your background jobs to ensure they are running correctly and alert you of any issues. The exact method you choose will depend on your specific needs and environment.

How to monitor CRON jobs?

 Here are some ways to monitor CRON jobs:

  1. Logging: You can log the output of your CRON jobs to a file and check the file regularly for any errors or unexpected results. This can be done by appending >> /path/to/logfile.log to the end of your CRON command.

  2. Email notifications: You can have the output of your CRON jobs sent to you via email by appending | mail -s "Cron job output" your@email.com to the end of your CRON command.

  3. Monitoring tools: There are many tools available that can monitor your CRON jobs and send notifications in case of any issues. Some popular tools include Monit, Supervisor, and New Relic.

  4. System logs: You can also monitor system logs to check for any errors or problems with your CRON jobs. On most systems, you can view the logs by running the cat /var/log/syslog command.

  5. Scripts: You can write a script to monitor your CRON jobs and send notifications in case of any issues. This script can be run on a regular basis as a CRON job itself.

These are some of the ways you can monitor your CRON jobs to ensure they are running correctly and alert you of any issues. The exact method you choose will depend on your specific needs and environment.

How to troubleshoot Too many connections error in MySQL?

The "Too many connections" error in MySQL occurs when the maximum number of connections to the MySQL server has been reached. Here are some steps to troubleshoot this error:


Check the maximum number of connections: You can check the maximum number of connections that MySQL is configured to allow by running the following SQL query:


SHOW VARIABLES LIKE 'max_connections';


Monitor current connections: You can see how many connections are currently open by running the following SQL query:


SHOW STATUS LIKE 'Threads_connected';


Increase the maximum number of connections: If the number of connections is close to the maximum, you can increase the maximum number of connections in the my.cnf file by changing the max_connections value.


Check for idle connections: Some connections may remain open but inactive. You can check for these connections by running the following SQL query:


SHOW PROCESSLIST;


Kill idle connections: If you have a large number of idle connections, you can kill them by running the following SQL query:


KILL [connection_id];


Check for slow queries: Slow running queries can also cause a high number of connections. You can check for slow queries by running the following SQL query:


SHOW SLOW QUERIES;


Optimize slow queries: If you find slow running queries, you can optimize them by using indexes, reducing the number of joins, and optimizing the SQL.


Connection pooling: If you are using connection pooling in your application, consider increasing the number of connections in the connection pool to reduce the number of new connections to the database.

Check if you can find the specific cause of the error.

    Tuesday, January 31, 2023

     def substitute(search, replace, text)

      text.gsub(search, replace)

    end


    text = "Hello World, this is a sample text."

    search = "sample"

    replace = "example"


    puts substitute(search, replace, text)

    # Output: "Hello World, this is a example text."

    def replace_keys_with_values(hash, text)

      hash.each do |key, value|

        text.gsub!(key, value)

      end

      text

    end

    replace_keys_with_values({ "key1" => "value1", "key2" => "value2" }, "key1 and key2")

    # returns "value1 and value2"

     

     

    In this example, the substitute method uses the gsub method, which stands for "global substitution", to replace all occurrences of the search string in the text input with the replace string. The gsub method returns a new string with the replacements, and this new string is then returned by the substitute method.

    Monday, January 23, 2023

    How to troubleshoot nil exceptions in Ruby on Rails codebase?

    Troubleshooting nil exceptions in a Ruby on Rails codebase can be a challenging task, but there are several strategies that can help you to find and fix the problem:

    1. Use a debugger: A debugger is a powerful tool that allows you to step through the code line by line and inspect the state of the variables at each step. This can help you to identify the line of code that is causing the exception and the variable that is returning nil.

    2. Check the stack trace: The stack trace is a list of the method calls that led to the exception. It can help you to identify the method that is causing the exception and the arguments that were passed to it.

    3. Check the logs: The Rails logs can provide more information about the exception and can help you to identify the request that caused the exception.

    4. Use a linter or static analysis tool: There are several linters and static analysis tools that can be used in a Ruby on Rails project, such as RuboCop, Brakeman, and Reek. These tools can help you to find potential issues and vulnerabilities in your codebase.

    5. Use the byebug gem: byebug is a powerful gem that provides an interactive debugger for Ruby. It can be used to check the state of the variables and navigate through the code.

    6. Use the binding.pry gem: pry is a powerful gem that provides an interactive shell for Ruby. It can be used to check the state of the variables and navigate through the code.

    7. Test your code: By writing tests and running them you can ensure that the code is working correctly and the test will catch any exception in the future.

    8. Check the documentation and the source code: Sometimes the exception is caused by a bug in a gem or a library that you are using. Check the documentation and the source code of the gem or library to see if there is a fix or a workaround.

    It's important to note that these are just some of the strategies that can be used to troubleshoot nil exceptions in a Ruby on Rails codebase and the approach that you choose will depend on the specific circumstances of the exception.

    Thursday, December 15, 2022

    TRIZ books

     1. Engineering of Creativity Introduction to TRIZ Methodology of Inventive Problem Solving (Semyon D. Savransky)

    2. TRIZ For Dummies (Lilly Haines-Gadd)

    3. Innovation AlgorithmTRIZ, systematic innovation and technical creativity (Genrich Altshuller)

    4. Lean TRIZ how to dramatically reduce product-development costs with this innovative problem-solving tool (Harrington, H. James)

    5. TRIZ for Engineers: Enabling Inventive Problem Solving (Karen Gadd)

    6. Advances and Impacts of the Theory of Inventive Problem Solving The TRIZ Methodology, Tools and Case Studies (Sebastian Koziołek, Leonid Chechurin etc

    7. Innovation on Demand New Product Development Using TRIZ (Victor Fey, Eugene Rivin)

    8. Inventive Thinking through TRIZ A Practical Guide, Second Edition (Michael A. Orloff)

    9. Modern TRIZ A Practical Course with EASyTRIZ Technology (Michael A. Orloff

    10. Modern TRIZ Modeling in Master Programs - Introduction to TRIZ Basics at University and Industry (Orloff, Michael A)

    11. Research and Practice on the Theory of Inventive Problem Solving (TRIZ) Linking Creativity, Engineering and Innovation (Leonid Chechurin)

    12. Simplified TRIZ New Problem Solving Applications for Technical and Business Professionals, 3rd Edition (Kalevi Rantanen, David W. Conley, Ellen R. Domb)

    13. Trimming, Miniaturization and Ideality via Convolution Technique of TRIZ A Guide to Lean and High-level Inventive Design (Saurabh Kwatra, Yuri Salamatov)

    14. TRIZ POWER TOOLS Job 1 Discovering Markets Carving out New Turf in Saturated Markets (Larry Ball and others

    15. TRIZ POWER TOOLS Job 2 Choosing Features What Features Will Excite the Target Market (Larry Ball and others

    16. TRIZ POWER TOOLS Skill 1 Resolving Contradictions The Skill that Will Give You the Confidence to Do the Rest

    17. TRIZ. Theory of Inventive Problem Solving Level 1 (Vladimir Petrov)

    18. Trizics Teach yourself TRIZ, how to invent, innovate and solve impossible technical problems systematically (Gordon Cameron)

    19. Triz the Right Solution at the Right Time A Guide to Innovative Problem Solving - Yuri Salamatov

    Monday, December 12, 2022

    Software

     Just like nature does not have any distinct fields like Physics, Chemistry, Biology etc. The software does not really have distinctions like front end, backend, machine learning etc. The examples used in this book will not have such arbitrary distinctions. So the concepts will be illustrated using devops such as Kubernetes. Because in reality the software is just software and the chosen example illustrate the principle really well. 

    The evolution might have occurred without being aware of these principles in action. The purpose of this book to bring those concepts from the realm of experts and make it available to anyone at any skill level.

    Trends of Technical Evolution

     Migration of function to super systems. Side car in Kubernetes was extracted into the Linux operating system. This is an example of the function migrating from system to super system over time. 

    Sunday, December 11, 2022

    pnpm

     Appended new lines to /Users/bparanj/.zshrc


    Next configuration changes were made:

    export PNPM_HOME="/Users/bparanj/Library/pnpm"

    export PATH="$PNPM_HOME:$PATH"


    To start using pnpm, run:

    source /Users/bparanj/.zshrc

    Saturday, December 10, 2022

    Physical Contradiction in Software

     The web app began with a simple UI with no buttons on the home page. After a few years, it had lot of buttons, similar to how Microsoft Word looks like. Not so good! How to design a product that is having the buttons and at the same time not having any buttons but provides all the features we need? Can we remove all the buttons to make the design simple and at the same time provide business value?

    The general form of physical contradiction looks like:

    X must have A and X must have -A

    The thing X must have some property and the opposite property. We can break this contradiction by asking:

    1. Do we need both A and -A at the same time?

    2. Do we need both A and -A in the same space?

    In the web app design case, we can choose the time as a way to separate the opposing properties. We can apply the Separation in Time principle to resolve this physical contradiction.

    The design must be modified by removing all the buttons or as many buttons as possible on the home page. The button should appear only when the context is right during the use of the product. One of the reasons why the product became messy page with many buttons is that the app was very CRUD based.

    It lacked clear messaging to the users when using the product and did not provide any next action to take during the workflow. By making the messages actionable, we can include the links that provides them a clear action to take to complete their task.

    Tuesday, November 01, 2022

    Prism of TRIZ

    Step 1

    Describe the problem in simple language covering all the main points.

    Step 2

    Re-describe the problem in a more general, conceptual way, stripping out the detail.

    Step 3

    Locate existing answers to the very general problem using the TRIZ Solution Catalog

    Step 4

    Use the solution triggers + your knowledge and experience to find pragmatic solutions.

    Theory of Inventive Problem Solving

    1. Systematic ways for defining and understanding problems

    2. Using the four solution catalogs to solve them


    1. Inventive Principles - For solving contradictions (conflicting requirements)

    2. TRIZ Trends - Predict the likely evolution of products

    3. Standard Solutions - For dealing with harms, inefficiencies and problems to do with measurement

    4. Effects - Answer how to questions using the Effects Database


    Sunday, September 18, 2022

    apitome ruby 3 compatibility

     https://github.com/jejacks0n/apitome/issues/121

    Based on some local testing, the apitome gem works fine on ruby 3.

    PR merged: https://github.com/jejacks0n/apitome/pull/122


    Thursday, September 08, 2022

    Action Oriented vs Object Oriented

    • Distribute system intelligence horizontally as uniformly as possible, that is, the top-level classes in a design should share the work uniformly.
    • Do not create god classes/objects in your system. Be very suspicious of a class whose name contains Driver, Manager, System, or Subsystem.
    • Beware of classes that have many accessor methods defined in their public interface. Having many implies that related data and behavior are not being kept in one place.
    • Beware of classes that have too much noncommunicating behavior, that is, methods that operate on a proper subset of the data members of a class. God classes often exhibit a great deal of noncommunicating behavior.
    • In applications that consist of an object-oriented model interacting with a user interface, the model should never be dependent on the interface. The interface should be dependent on the model.
    • Model the real world whenever possible. (This heuristic is often violated for reasons of system intelligence distribution, avoidance of god classes, and the keeping of related data and behavior in one place.)
    • Eliminate irrelevant classes from your design. Heuristic 3.8 Eliminate classes that are outside the system.
    • Do not turn an operation into a class. Be suspicious of any class whose name is a verb or is derived from a verb, especially those that have only one piece of meaningful behavior (i.e., do not count sets, gets, and prints). Ask if that piece of meaningful behavior needs to be migrated to some existing or undiscovered class.
    • Agent classes are often placed in the analysis model of an application. During design time, many agents are found to be irrelevant and should be removed.

    Wednesday, September 07, 2022

    The Building Blocks of Object Oriented Paradigm

    • All data should be hidden within its class.
    • Users of a class must be dependent on its public interface, but a class
    • should not be dependent on its users.
    • Minimize the number of messages in the protocol of a class.
    • Implement a minimal public interface that all classes understand [e.g., operations such as copy (deep versus shallow), equality testing, pretty printing, parsing from an ASCII description, etc.].
    • Do not put implementation details such as common-code private functions into the public interface of a class.
    • Do not clutter the public interface of a class with things that users of that class are not able to use or are not interested in using.
    • Classes should only exhibit nil or export coupling with other classes, that is, a class should only use operations in the public interface of another class or have nothing to do with that class.
    • A class should capture one and only one key abstraction. Heuristic 2.9 Keep related data and behavior in one place.
    • Spin off non-related information into another class (i.e., noncommunicating behavior).
    • Be sure the abstractions that you model are classes and not simply the roles objects play.


    Wednesday, July 06, 2022

    Start with the Ideal Outcome

     Start with the Ideal Outcome


    Capture


    1. All the benefits you want

    2. The primary output of your system (the reason it exists)


    Prioritize


    3. What are the primary benefits?

    4. Sort other benefits into 'must haves' and 'nice to haves'.


    Action Item


    Fill out the Ideal Outcome for Scoping New Inventions worksheet


    What benefits do we want from an ideal provisioning and deployment system?

    What benefits would an ideal system deliver?

    Wave a magic wand over it and write down all the things you want.


    Ideal Thinking


    Imagine all the things you want without worrying about the constraints of any kind.


    What are the downsides of the current systems in the market?


    Context


    Who needs to use this sytem?

    In what circumstances?


    Wednesday, June 22, 2022

    Heroku Reviews - June 22, 22

     



    WHAT


    Deploy full stack apps (FE + BE + DB)

    Deploy full stack apps without the need of all the technical skills needed for AWS

    Prototyping - quick deployment

    Build an entire pipeline (dev, test and prod)

    Ship web apps without a lot of effort

    Build app very quickly

    Build, deploy and run your app very easily

    Very helpful to build highly large data apps

    Easy to deploy full stack applications fast without worrying about configuring


    HOW


    Connect your app using a Git repo and it will handle the deployment


    USE


    Simple and intuitive interface

    Simple and easy to use, even for users with minimal knowledge of application architecture


    EASY


    Easy to setup

    You can set up an entire environment very fast


    DEPLOYMENT SPEED


    Instant deployment

    One-step deployment process

    Their auto-maintenance and auto-deploy services saves a lot of time and effort


    DEPLOYMENT EASE


    Makes it easy to deploy apps without having the knowledge of managing a server

    CLI tool - easy to deploy

    Quick and easy deployment


    INTEGRATIONS


    Seamless integration with Git

    Ease with which we can deliver updated code and new features

    Add ons

    Marketplace

    Easy installation of plugins and add-ons

    Integrate third-party website with Salesforce

    Connect database with a single click with the help of plug in



    LEARNING CURVE


    Less to learn for developers


    COMPLEXITY


    Complexity < (AWS or GCP)


    SCALING


    Scales with you

    Autoscale based on usage

    Autoscale our platform


    TOOLS


    Migration tool

    Powerful metrics to monitor the app


    ZERO DOWNTIME


    No downtime

    Rolling restarts (to fix delays in requests during deploy)

    Perform a rollback to a previous version with just one click


    TIME SAVINGS


    Saves a lot of time in creating and deploying new apps


    COST SAVINGS


    Streamline the process for developers and saves costs on app development

    Reduced the dependence small teams have on Devops (saves costs)


    DOCUMENTATION


    for:

      using several environments

      tuning memory usage

      deploying from Dropbox

    Detailed sample apps and code for starting a new app


    SECURITY


    Secure and protected ecosystem



    Dev / Prod Environment Parity


    Being able to switch from local to remote environment

    You can work locally with remote database


    WHO


    Great for small teams and if you need to validate your product

    Single developer or small teams can focus on the project and get it launched, without too much hassle








    CONS


    Once you get substantial traffic, you have to ask yourself whether your budget should focus on:


    more dynos

    code optimization

    different platform


    Support

    Contract trap

    License cose

    Expensive

    Gets expensive quickly

    Non traditional server environment

    Deploy fixed number of apps

    Apps go to sleep if there is no user activity

    Environment configuration setup is slightly complex (vs Netlify)

    CI service is fairly limited (works fine with CircleCI & Travis)

    Minimal language support

    Low network performance

    Upsell on features you may not need

    To the uneducated, they will opt into unnecessary features that are otherwise free

    Security add-ons like AWS would be nice

    Need a separate service for repo like Github, rather than having everything inclusive

    30 seconds restriction (not compatible with OS libraries)

    Request gets stuck behind slow request

    Hard to gauge the capacity needed

    Hit by downtimes (not much to do once it goes down)

    If AWS goes down Heroku will go down


    SSH Basics

     We learned a little bit about the SSH protocol and how to use the ssh program to connect to a remote server.

    SSH protocol was introduced for secure communication using the pub- lic key encryption on the network. OpenSSH is a collection of programs implementing this protocol and available to us.

    Connecting to a remote server can be as easy as running ssh $USER@$HOST. In the case we create a server with password authentication, we can use ssh-copy-id to put the public key to the server and take advantage of SSH-keys only access.

    We learned about SSH keys management. We can find our keys in ~/.ssh, generate new ones with ssh-keygen. We explored how ~/.ssh/authorized_keys is used for authorizing access using these keys and how SSH host keys are stored in ~/.ssh/known_hosts.

    scp and sftp are the go-to tools for secure file transfer over SSH. Although using scp has some security implications given its original design, it’s safe to use in simple commands. rsync is another popular option.

    Monday, June 13, 2022

    Create a Node on VPS

    1. Signup for VPS provider such as Linode
    2. Create a node














    Provisioning, Booting, Running