Note: This configuration can be applied on any server running Ubuntu.
I was recently redesigning an app I developed a while ago with Node.js, React and GraphQL because, apparently, its design was "too stretched" and "didn't look so good" (I low-key agree). So, I dove into dribbble to look for an awesome design I could borrow. Sidebar: I really appreciate all the awesome open source designs created by the super talented UI/UX designers out there. After a bit of digging, I found a design by Ricardo Salazar. It was simple and easily implementable. With a few color changes, I managed to recreate the design and implement my React front-end using data from my GraphQL API.
During this process, I realized that to get the data I wanted, I needed to make a lot of requests to the external API I was using. Despite the API being free and without rate limits, I felt like I was abusing the resources that were provided. To solve this problem, I thought about using a database to store the data then performing the requests from my own server but I realized this would be highly inefficient due to the dynamic nature of the data from the external API. So, I decided to look at other options, that is when I remembered Redis.
I had done some storage with Redis before to perform authentication and session management with Express.js. After a bit of research, I came to the conclusion that redis was the way to go. Another issue was that, since I was using shared hosting with a cpanel, I could not install and use redis on my host. I had to find a way.
Then comes Github Student Pack. Github provides a bunch of resources to help students use services like DigitalOcean by providing coupons and other options. I highly recommend if for students getting into or already developing awesome stuff. I was able to get a coupon for $50 on DigitalOcean and set up my droplet. I also did the initial set-up which has been provided in detail in this article.
Installing Redis on a DigitalOcean droplet
To install redis, run the following commands
$ sudo apt update
$ sudo apt install redis-server
This will download and install Redis and its dependencies. We will then make some modifications to the Redis config file to add authentication and secure our Redis database.
Open the config file by writing this command.
$ sudo nano /etc/redis/redis.conf
In the config file, we will locate and modify the following areas:
- supervised
- security
- bind
Setting supervised to systemd
Locate the line which contains supervised
option and change it to systemd
# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
# supervised no - no supervision interaction
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous liveness pings back to your supervisor.
supervised systemd
Modifying Password
Since we need to set a secure password for the Redis, we will need to use openssl to generate a strong password. To generate a password, open a new tab on the terminal and run the command below.
$ openssl rand 60 | openssl base64 -A
The command above generates a strong password made up of random characters.
vWHK8OXixGiUU1kimf+Bo4WM+vu8t7Bpdk7VZHvtBc7caNeCDBK1Etazy/1Hho+/Uou4Mr1/gXk0hdNM
The security section of the Redis config file provides us with an area to specify the password of our Redis server. To set the password, in the config file, locate the security section and uncomment the #requirepass foobared
then change the password from foobared
to the password we generated above.
#/etc/redis/redis.conf
################################## SECURITY ###################################
# Require clients to issue AUTH <PASSWORD> before processing any other
# commands. This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
requirepass vWHK8OXixGiUU1kimf+Bo4WM+vu8t7Bpdk7VZHvtBc7caNeCDBK1Etazy/1Hho+/Uou4Mr1/gXk0hdNM
Modifying bind
To make our redis database accessible, we will have to bind it to an external IP address which is not very secure. In this tutorial, we will bind it to 0.0.0.0 which makes it available everywhere
In the config file we opened above, locate the line below and make sure it is uncommented(by removing the #
at the beginning if it exists) and change the IP address to 0.0.0.0
.
#/etc/redis/redis.conf
bind 127.0.0.1 ::1 # change this line to bind 0.0.0.0
After modifying the config file, press ctrl+x
on Windows or Linux
or command+x
on Mac
then press y
then enter
to save the file then restart Redis by running the command below.
$ sudo systemctl restart redis.service
We can then test our Redis. To test the password, access the Redis command line by running:
$ redis-cli
We then write a series of commands to check if the Redis password works. At first, we try to set a key and value before authentication:
127.0.0.0:6379> set hello "Hello World"
This produces an error because we need to set the password:
#Output
(error) NOAUTH Authentication Required
We then specify the password we added above in the config file:
127.0.0.1:6379> auth <redis-password>
Redis will produce a message, OK
, to inform you that the password has been accepted. We can then try to store the key and value as we tried above.
# setting value
127.0.0.1:6379> set hello "Hello World"
#getting value
127.0.0.1:6379> get hello
#output "Hello World"
We can then exit the Redis client with the command quit
.
Using Remote Redis on your local Express Application
Note: If you are using a firewall on your DigitalOcean server, you need to enable access for port 6379
in order to use it on your local application. To enable the port for external access:
$ ufw allow 6379/tcp
#checking if port has been added to ufw list
$ ufw status
We then initialize a simple express app by installing a few packages.
# Initialize Express app
$ npm init -y
# Installing packages - Express and Redis
$ npm install express redis
Create an index.js
file on the root of your project then write the code below:
const express = require('express');
const redis = require('redis');
const app = express();
// These should be environment variables, use a package like dotenv to store these data
const REDIS_PORT = 6379;
const REDIS_HOST = "<DO_IP_ADDRESS>" // This is the IP address of your DigitalOcean droplet
const REDIS_PASSWORD = "vWHK8OXixGiUU1kimf+Bo4WM+vu8t7Bpdk7VZHvtBc7caNeCDBK1Etazy/1Hho+/Uou4Mr1/gXk0hdNM" // This is the password we created above for our Redis database.
const redisClient = redis.createClient({
host: REDIS_HOST,
port: REDIS_PORT,
password: REDIS_PASSWORD
});
// Log errors in case of Redis connection failure
redisClient.on('error', error => {
console.log('Redis Error', error);
});
// Set Express server PORT
const PORT = process.env.PORT || 5000;
app.listen(PORT, () =>
console.log(`App running in on port ${PORT}`),
);
With this, you can use the remote Redis to store and access your data.
To get more details on securely configuring Redis on your DigitalOcean server, you can check out the link below:
Top comments (3)
i think rather than changing the bind command you have to comment them out
in order to connect to redis on digitalocean ,
i tried your method it didnt work then i commented bind as per instructions on the conf file it worked
Thanks for the feedback. I'll try it out and update the article
NOTE there is two bind commands in config you have to comment both of them out