Wagtail on Docker

Wagtail on Docker


This article explains the steps I had taken to set up Wagtail along with PostgreSQL using containerization techniques.

As part of a commitment to a friend in the middle of the year, and to enhance my Python skills, ventured into learning, understanding, and customizing Wagtail CMS. I have had bits of Python experience and Docker during recent years and also have some knowledge on WordPress websites. Learning and improving my skills on Wagtail was a wonderful experience during my spare time over the last few months.

In this article, I’m sharing (or rather journaling) some of the things that I feel could be useful for others. Feel free to share your comments and/or feedback on how it can be improved.

Wagtail – is a leading open-source Content Management System built using Python. Read more here: [https://wagtail.org]



Why Wagtail on Docker?

As you might be aware, standard Python practice is to use virtualenvs to isolate different development environments, as I was trying out different stuff on my PC it was getting a bit annoying to switch in and out of virtualenvs and often spend time and realizing using the wrong environments.



Why this blog/article?

As I started, I did come across quite a few blog/websites explaining the process/steps, however I felt they required Python and/or Wagtail be installed on their PC or where addressing use cases that were not simple. As part of learning Docker as well, I decided to embark to see if this can be done; I succeeded with that and sharing here in case if anyone might need it.



Let’s get to it

Here is the TOC

  • Dockerfile
  • Changing the Database
  • compose.yaml
  • VS Code extensions



Preparing the Dockerfile

  • As my aim was to get Wagtail fully self-contained, the first step was to create a Docker image that would have Python and other libraries required for Wagtail/Django installed. This was fairly straightforward.
  • Below is the basic Dockerfile
## Install system dependencies
RUN apt-get update && apt-get install -y 
    build-essential 
    libpq-dev 
    && rm -rf /var/lib/apt/lists/*

## Install the dependencies and create the image with Wagtail!
RUN pip install --no-cache-dir wagtail==6.2.3 psycopg2>=2.9,<3
Enter fullscreen mode

Exit fullscreen mode



Changing database from SQLite to PostgreSQL

  • While the above worked perfectly using SQLite as the database, I wanted to use PostgreSQL!
  • Database parameters are defined under settings/base.py within the Wagtail site.
  • I Initially started writing a bash script to modify the settings/base.py, but it later struck me that I could easily do this with a simple Python script.
  • This script will be executed by the entry point scripts when the composer launches the services. Below is the Python function that I used to modify the database parameters with settings/base.py.
def replace_sqlite_with_postgres(settings_file_path):
    # Define the new PostgreSQL DATABASES configuration
    new_databases_config = """
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('POSTGRES_DB', 'mydatabase'),
        'USER': os.getenv('POSTGRES_USER', 'myuser'),
        'PASSWORD': os.getenv('POSTGRES_PASSWORD', 'mypassword'),
        'HOST': os.getenv('POSTGRES_HOST', 'localhost'),
        'PORT': os.getenv('POSTGRES_PORT', '5432'),
    }
}
"""
    # Read in the original base.py file
    with open(settings_file_path, "r") as file:
        content = file.read()

    # Use regex to find and replace the DATABASES block
    content = re.sub(
        r"DATABASESs*=s*{.*?n}", # Match DATABASES block
        new_databases_config.strip(), # Replace with the new config
        content,
        flags=re.DOTALL
    )

    # Write the modified content back to base.py
    with open (settings_file_path, "w") as file:
        file.write(content)
Enter fullscreen mode

Exit fullscreen mode

  • Observe closely, I’ve used environment variables to get the Database configuration params, which made it easier to share between the services
  • with the Python script defined, had to modify the Dockerfile to copy this as well, below is the complete Dockerfile
FROM python:3.11-slim
WORKDIR /app
RUN apt-get update && apt-get install -y 
    build-essential 
    libpq-dev 
    libjpeg62-turbo-dev 
    zlib1g-dev 
    libwebp-dev 
    && rm -rf /var/lib/apt/lists/*

COPY replace_sqlite.py .

RUN pip install --no-cache-dir wagtail==6.2.3 "psycopg2>=2.9,<3"
EXPOSE 8000
Enter fullscreen mode

Exit fullscreen mode



Preparing the compose.yaml

  • As I wanted to segregate both the App and DB separately, chose to create two separate services.
  • Setting up the database service was straightforward, had to make some changes to handle database configurations for the Web App. Below is the source for compose.yaml
services:
  web:
    build: .
    container_name: wagtail_web
    volumes:
      - .:/app
    ports:
      - "58000:8000"
    depends_on:
      - db
    env_file:
      - .env
    entrypoint: ["/bin/bash", "/app/entrypoint.sh"]

  db:
    image: postgres:13
    container_name: wagtail_db
    env_file:
      - .env
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "55432:${POSTGRES_PORT}"

volumes:
  postgres_data:

Enter fullscreen mode

Exit fullscreen mode

  • entrypoint directive was very handy to achieve what I intended to do. – Wrote a small bash script that repeats most of the commands required to start a new Wagtail website, the entrypoint.sh Bash script provided below was called using the entrypoint directive.
#!/bin/bash

# Check if the Wagtail project directory exists
if [ ! -d "/app/$SITE_NAME" ]; then

    wagtail start $SITE_NAME
    cd /app/$SITE_NAME
    pip3 install -r requirements.txt
    python ../replace_sqlite.py ./$SITE_NAME/settings/base.py
    python manage.py migrate
    echo "Creating superuser..."
    echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('$SITE_ADMIN_USER', '$SITE_ADMIN_USER', '$SITE_ADMIN_PASSWORD')" | python manage.py shell
fi

cd /app/$SITE_NAME
python manage.py runserver 0.0.0.0:8000
Enter fullscreen mode

Exit fullscreen mode

  • I also introduced a few commands to automate most of the stuff that you will have to do when starting a new website.
  • This script does the following when launched for the first time:
  • Creates a fresh Wagtail website using the name provided in .env file
  • Installs the necessary requirements for Wagtail
  • Calls the replace_sqlite.py script to change to PostgreSQL
  • Runs the initial database migrations required for Wagtail
  • Creates the super user for the Wagtail website based on the variables defined in .env file
  • On subsequent starts, it will just launch the existing Wagtail website.



Working with VS Code

  • At this point, I managed to get the default Wagtail site up and running, but open VS Code and face with this issue 🙁
    ! Squiggles due to missing Python environment
  • The Dev Containers and the Remote Development extensions came in handy to achieve this. Below is the basic devcontainer.json configuration that helped me with this.
{
    "name": "Docker Wagtail Web Workspace",
    "dockerComposeFile": "../compose.yaml",
    "service": "web",
    "workspaceFolder": "/app/mysite"
}
Enter fullscreen mode

Exit fullscreen mode

  • And with this when I open Reopen in Container the Squiggles are gone!

! Working VS Code with the environment from Container



Conclusion

  • While I’m still learning and experimenting with Wagtail and Python, I was happy to learn and create a fully self-contained working environment
  • This will allow anyone to share their Wagtail project easily without having to give any specific instructions on setting this up.
  • Apart from that, with Dev Containers it is also going to be easier to work with any Containers that are deployed remotely too
  • All of the code referenced in this article is available in my repo (Wagtail-Docker) [https://github.com/shariharan1/wagtail_docker], feel free to pull/edit/customize to your needs. Let me know in the comments if any feedback or queries.
     



    References

  • Dockerizing Wagtail

  • Install Wagtail in Docker



Source link
lol

By stp2y

Leave a Reply

Your email address will not be published. Required fields are marked *

No widgets found. Go to Widget page and add the widget in Offcanvas Sidebar Widget Area.