Step 4: Add additional Services

Let’s add another service to our project. Wordpress stores most of its data in the database, which can slow the system down if the database is hit frequently. We will improve performance by using memory caching. The first time a request is made, the data is pulled from the database and stored in memory. If the same data is accessed again, the caching service uses the copy in memory.

Redis and Memcached are both in-memory data storage systems. Memcached is a high-performance distributed memory cache service, and Redis is an open-source key-value store. Similar to Memcached, Redis stores most of the data in memory. These services keep data in memory because it is faster than reading it from the database. We’ll add Redis from Docker Hub.

Install Redis Server

  1. Add the Redis service to our Wordpress docker-compose.yml file.

    1. Edit file docker-compose.yml.

    2. Add a new section called redis between sections db and wordpress.

    redis:
      image: redis
      restart: always
    
  2. We need to link it to Wordpress so it can make use it.

    1. Add the reference to redis under the depends_on property.

    wordpress:
      depends_on:
        - db
        - redis
    
  3. Let’s restart the project and configure Redis.

    • We can do this in a one-line command

    • Use && is to separate the commands

    docker-compose down && docker-compose up -d
    
    Output
    root@vps298933:~/wordpress-docker# docker-compose down && docker-compose up -d
    Stopping wordpressdocker_wordpress_1 ... done
    Stopping wordpressdocker_db_1        ... done
    Removing wordpressdocker_wordpress_1 ... done
    Removing wordpressdocker_db_1        ... done
    Removing network wordpressdocker_default
    Creating network "wordpressdocker_default" with the default driver
    Pulling redis (redis:latest)...
    latest: Pulling from library/redis
    27833a3ba0a5: Already exists
    cde8019a4b43: Pull complete
    97a473b37fb2: Pull complete
    c6fe0dfbb7e3: Pull complete
    39c8f5ba1240: Pull complete
    cfbdd870cf75: Pull complete
    Digest: sha256:000339fb57e0ddf2d48d72f3341e47a8ca3b1beae9bdcb25a96323095b72a79b
    Status: Downloaded newer image for redis:latest
    Creating wordpressdocker_redis_1 ...
    Creating wordpressdocker_db_1 ...
    Creating wordpressdocker_redis_1
    Creating wordpressdocker_db_1 ... done
    Creating wordpressdocker_wordpress_1 ...
    Creating wordpressdocker_wordpress_1 ... done
    root@vps298933:~/wordpress-docker#
    
    • As you can see, Docker Compose downloaded image redis:latest and then created a new container called wordpressdocker_redis_1.

    • We can’t test Redis easily because we did not configure an outside port. You can see that it is running on an internal port only. Other Docker containers can access it, but we can’t.

    Output
    root@vps298933:~/wordpress-docker# docker ps
    CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                     NAMES
    61dc491c1749        wordpress:latest     "docker-entrypoint.s…"   12 seconds ago      Up 10 seconds       0.0.0.0:20851->80/tcp      wordpressdocker_wordpress_1
    6f5367faa44c        mariadb              "docker-entrypoint.s…"   13 seconds ago      Up 12 seconds       3306/tcp                   wordpressdocker_db_1
    aa6c82e67ffc        redis                "docker-entrypoint.s…"   13 seconds ago      Up 12 seconds       6379/tcp                   wordpressdocker_redis_1
    2175f0a86466        nextcloud            "/entrypoint.sh apac…"   7 days ago          Up 6 days           0.0.0.0:20850->80/tcp      condescending_agnesi
    root@vps298933:~/wordpress-docker#
    
  4. So, let’s configure Redis to run on a public port to se can test it.

    Once we do this, any service on the VPS can then access this specific Redis container.

    1. Redis runs on port 6379 by default.

    2. Edit file docker-compose.yml and add port 6379.

    Note

    We would want to use a standalone Redis container for multiple projects. Otherwise, all other running services lose access to Redis when we stop our Wordpress project.

    redis:
      image: redis
      restart: always
      ports:
        - "6379:6379"
    
  5. Restart the project and view the running containers

    Output
    root@vps298933:~/wordpress-docker# nano docker-compose.yml
    root@vps298933:~/wordpress-docker# docker-compose down && docker-compose up -d
    Stopping wordpressdocker_wordpress_1 ... done
    Stopping wordpressdocker_db_1        ... done
    Stopping wordpressdocker_redis_1     ... done
    Removing wordpressdocker_wordpress_1 ... done
    Removing wordpressdocker_db_1        ... done
    Removing wordpressdocker_redis_1     ... done
    Removing network wordpressdocker_default
    Creating network "wordpressdocker_default" with the default driver
    Creating wordpressdocker_redis_1 ...
    Creating wordpressdocker_db_1 ...
    Creating wordpressdocker_redis_1
    Creating wordpressdocker_redis_1 ... done
    Creating wordpressdocker_wordpress_1 ...
    Creating wordpressdocker_wordpress_1 ... done
    root@vps298933:~/wordpress-docker#
    root@vps298933:~/wordpress-docker# docker ps
    CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                     NAMES
    8e8872cef4be        wordpress:latest     "docker-entrypoint.s…"   5 seconds ago       Up 3 seconds        0.0.0.0:20851->80/tcp     wordpressdocker_wordpress_1
    fbfc30021dda        mariadb              "docker-entrypoint.s…"   6 seconds ago       Up 5 seconds        3306/tcp                  wordpressdocker_db_1
    8f92c97b8b7c        redis                "docker-entrypoint.s…"   6 seconds ago       Up 4 seconds        0.0.0.0:6379->6379/tcp    wordpressdocker_redis_1
    2175f0a86466        nextcloud            "/entrypoint.sh apac…"   7 days ago          Up 6 days           0.0.0.0:20850->80/tcp     condescending_agnesi
    root@vps298933:~/wordpress-docker#
    
  6. Now we can test Redis using redis-cli because Redis is available on port 6379. But, we need to install the package first.

    apt install -y redis-tools
    
    Output
    root@vps298933:~/wordpress-docker# redis-cli ping
    
    Command 'redis-cli' not found, but can be installed with:
    
    apt install redis-tools
    
    root@vps298933:~/wordpress-docker#
    root@vps298933:~/wordpress-docker# apt install redis-tools -y
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    The following additional packages will be installed:
      libjemalloc1
    Suggested packages:
      ruby-redis
    The following NEW packages will be installed:
      libjemalloc1 redis-tools
    0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
    Need to get 599 kB of archives.
    After this operation, 2,835 kB of additional disk space will be used.
    Get:1 http://nova.clouds.archive.ubuntu.com/ubuntu bionic/universe amd64 libjemalloc1 amd64 3.6.0-11 [82.4 kB]
    Get:2 http://nova.clouds.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 redis-tools amd64 5:4.0.9-1ubuntu0.1 [516 kB]
    Fetched 599 kB in 0s (2,740 kB/s)
    Selecting previously unselected package libjemalloc1.
    (Reading database ... 132723 files and directories currently installed.)
    Preparing to unpack .../libjemalloc1_3.6.0-11_amd64.deb ...
    Unpacking libjemalloc1 (3.6.0-11) ...
    Selecting previously unselected package redis-tools.
    Preparing to unpack .../redis-tools_5%3a4.0.9-1ubuntu0.1_amd64.deb ...
    Unpacking redis-tools (5:4.0.9-1ubuntu0.1) ...
    Setting up libjemalloc1 (3.6.0-11) ...
    Processing triggers for libc-bin (2.27-3ubuntu1) ...
    Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
    Setting up redis-tools (5:4.0.9-1ubuntu0.1) ...
    root@vps298933:~/wordpress-docker#
    
  7. First of all, let’s test the connection using ping. The expected output is pong.

    redis-cli ping
    
    Expected Output
    root@vps298933:~/wordpress-docker# redis-cli ping
    PONG
    root@vps298933:~/wordpress-docker#
    

    Error

    • You will get a Connection refused message if something is misconfigured.

    Output
    root@vps298933:~/wordpress-docker# redis-cli ping
    Could not connect to Redis at 127.0.0.1:6379: Connection refused
    
  8. We can use the redis-cli tool to look at all of the information available.

    redis-cli info
    
    Output
    root@vps298933:~/wordpress-docker# redis-cli info
    # Server
    redis_version:5.0.4
    redis_git_sha1:00000000
    redis_git_dirty:0
    redis_build_id:c6d7e1572d62bb79
    redis_mode:standalone
    os:Linux 4.15.0-46-generic x86_64
    arch_bits:64
    multiplexing_api:epoll
    atomicvar_api:atomic-builtin
    gcc_version:6.3.0
    process_id:1
    run_id:21c1137b7c733b539977f3a7f6646a0b95a15654
    tcp_port:6379
    uptime_in_seconds:60
    uptime_in_days:0
    hz:10
    configured_hz:10
    lru_clock:10422992
    executable:/data/redis-server
    config_file:
    
    # Clients
    connected_clients:1
    client_recent_max_input_buffer:0
    client_recent_max_output_buffer:0
    blocked_clients:0
    
    # Memory
    used_memory:853896
    used_memory_human:833.88K
    .
    .
    .
    
    • We can look at individual sections of the info that are separated by the # symbol, such as server or memory.

    redis-cli info server
    redis-cli info memory
    
    Output
    root@vps298933:~/wordpress-docker# redis-cli info server
    # Server
    redis_version:5.0.4
    redis_git_sha1:00000000
    redis_git_dirty:0
    redis_build_id:c6d7e1572d62bb79
    redis_mode:standalone
    os:Linux 4.15.0-46-generic x86_64
    arch_bits:64
    multiplexing_api:epoll
    atomicvar_api:atomic-builtin
    gcc_version:6.3.0
    process_id:1
    run_id:21c1137b7c733b539977f3a7f6646a0b95a15654
    tcp_port:6379
    uptime_in_seconds:72
    uptime_in_days:0
    hz:10
    configured_hz:10
    lru_clock:10423004
    executable:/data/redis-server
    config_file:
    root@vps298933:~/wordpress-docker#
    root@vps298933:~/wordpress-docker# redis-cli info memory
    # Memory
    used_memory:852920
    used_memory_human:832.93K
    used_memory_rss:4444160
    used_memory_rss_human:4.24M
    used_memory_peak:853896
    used_memory_peak_human:833.88K
    used_memory_peak_perc:99.89%
    used_memory_overhead:840694
    used_memory_startup:791000
    used_memory_dataset:12226
    used_memory_dataset_perc:19.74%
    allocator_allocated:1027896
    allocator_active:1220608
    allocator_resident:3497984
    total_system_memory:4035948544
    total_system_memory_human:3.76G
    used_memory_lua:37888
    used_memory_lua_human:37.00K
    used_memory_scripts:0
    used_memory_scripts_human:0B
    number_of_cached_scripts:0
    maxmemory:0
    maxmemory_human:0B
    maxmemory_policy:noeviction
    allocator_frag_ratio:1.19
    allocator_frag_bytes:192712
    allocator_rss_ratio:2.87
    allocator_rss_bytes:2277376
    rss_overhead_ratio:1.27
    rss_overhead_bytes:946176
    mem_fragmentation_ratio:5.62
    mem_fragmentation_bytes:3653144
    mem_not_counted_for_evict:0
    mem_replication_backlog:0
    mem_clients_slaves:0
    mem_clients_normal:49694
    mem_aof_buffer:0
    mem_allocator:jemalloc-5.1.0
    active_defrag_running:0
    lazyfree_pending_objects:0