New World - Strapi - Part 1

calendar_month September 1, 2020

The “New World” series finds its technical beginning here. In this article I will operate Strapi as a Docker container/stack.

What was Strapi again?

Strapi is a Headless CMS, meaning Strapi provides all requirements that apply to a backend. Data storage, web service, and administration are a few of these requirements.

The presentation of content etc. must be provided separately by the operator/developer. For example, I’ll use GatsbyJS.

What can Strapi do?

Ghost, for example, is a system I now like very much. Ghost can also be operated as a Headless CMS. If Ghost offered the creation of custom “content types”, I wouldn’t write this post.

ContentTypes / Fields

With Strapi I can create custom content types. Additionally, various field types are offered, with which the content type can be modeled.

The relationship/relation field is worth its own mention here. For someone who has been modeling ContentTypes for over 10 years - I can do SharePoint and actually quite well - the lookup field was always such a half-finished thing. With MOSS 2007 that was cool, over the years less so. The lookup field can still do 1->1 or 1->n relations today… Strapi can do more: here are also 1->1, 1->n, but also n->n possible… and then the whole inverse :)

GraphQL

Strapi can do GraphQL and quite well! In my opinion, Strapi can also be used for quick showcases or small to medium PoCs.

I model my (relational) data model at the interface, I assign the required permissions for the API via an interface, and can then query/develop against it. That’s simple, simple :)

The Technological Stack

Strapi is written in Node.js. For me, this part is actually very uninteresting, as I see languages and/or frameworks as tools that I should be able to use.

What is interesting again, however, is the fact that I can programmatically respond at various points and adjust the service, controller, or model for a content type. The latter - Models - even offer the ability to react to various events during entity management. Something like SharePoint ListEventReceivers - I love it :)

These are a few points that made Strapi interesting for me.

What can’t Strapi do?

Strapi can’t do a lot OOTB, most can be implemented/integrated programmatically. The question should rather be: What does Strapi do badly or what don’t I like?

Admin interface bääh

What I don’t like so much, for example, is the admin interface - it’s better than some other Headless CMS systems, but still darn ugly. I wouldn’t want to subject an editor or a client to this view for pure content maintenance. Try setting a date in a date field that is before 2012…

I haven’t decided yet, but I’d like to build an editor interface - preferably similar to Ghost’s - for editorial activities. We’ll see, maybe I’ll do it.

No ContentType Hierarchy

further up I listed what Strapi does better than SharePoint in my opinion. There are also functions that I’m used to from SharePoint and actually miss in Strapi. Hierarchical ContentType structure!

If Strapi offered something like this, it would be the ideal platform for me to build small ontologies and with a bit of logic set up a semantic web environment. That’s difficult when you don’t have ContentType inheritance.

I don’t have more right now - with productive use, more points will surely follow. So that this article doesn’t get too long, I’m cutting it here and coming to the actual topic: commissioning a Strapi environment with an external MongoDB instance.

Commissioning a Strapi Environment with an External MongoDB Instance

This project is actually very simple, as the makers of Strapi provide both a Docker image and partly good documentation.

For the documentation go here… I took the MongoDB example, modified it a bit and successfully deployed it via my nginx-proxy network.

Since I’m currently deploying many instances - I’m testing - I control the Docker Compose stack via an environment file. For me it looks like this:

TAG=alpine
DATABASE_CLIENT=mongo
DATABASE_HOST=<mongohost>
DATABASE_PORT=<port>
DATABASE_NAME=<db_name>
DATABASE_USERNAME=<user>
DATABASE_PASSWORD=<pass>
DATABASE_AUTHENTICATION_DATABASE=<aut_db>
VIRTUAL_HOST=<url>
LETSENCRYPT_HOST=<url>
LETSENCRYPT_EMAIL=<mailaddr>

The associated docker-compose.yml then looks like this:

version: '3'

services:
  strapi:
    container_name: strapi
    image: strapi/strapi:${TAG}
    environment:
      - DATABASE_CLIENT=${DATABASE_CLIENT}
      - DATABASE_HOST=${DATABASE_HOST}
      - DATABASE_PORT=${DATABASE_PORT}
      - DATABASE_NAME=${DATABASE_NAME}
      - DATABASE_USERNAME=${DATABASE_USERNAME}
      - DATABASE_PASSWORD=${DATABASE_PASSWORD}
      - DATABASE_AUTHENTICATION_DATABASE=${DATABASE_AUTHENTICATION_DATABASE}
      - VIRTUAL_HOST=${VIRTUAL_HOST}
      - LETSENCRYPT_HOST=${LETSENCRYPT_HOST}
      - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
    ports:
      - 1337:1337
    volumes:
      - strapi_data:/srv/app

volumes:
  strapi_data:

networks:
  default:
    external:
      name: nginx-proxy

This YAML structure should already be familiar. A container named strapi is created. Based on the tag, the image is pulled, the required parameters for the database as well as for the automatic Let’s Encrypt certificate request are read from the .env file. Strapi uses port 1337 by default.

A volume is created and linked, as is the standard network - this allows jwilder’s companion to work and we get an SSL certificate.

That’s actually it - the .env and docker-compose.yml should be placed in a folder on the filesystem, then Strapi can be started with

docker-compose up

After that, modeling can begin.

For continuing, the Strapi tutorial series is recommended, which can be accessed here.

How Does It Continue?

That’s a good question - I’m honestly not sure if I should go into data modeling or not. What will definitely follow at some point is a guide - description of an approach - how to set up Strapi as a development environment locally via package manager, make adjustments, and build a Docker image from it… Oh, and how to (relatively) easily import articles from Ghost. So we have at least 2 more articles about Strapi.