Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Develop with Django 2 and Python 3 in a container with Red Hat Enterprise Linux

 

September 11, 2019
Rob Terzi
Related topics:
ContainersLinux
Related products:
Red Hat Enterprise Linux

Share:

    In my previous article, Run Red Hat Enterprise Linux 8 in a container on RHEL 7, I showed how to start developing with the latest versions of languages, databases, and web servers available with Red Hat Enterprise Linux 8 even if you are still running RHEL 7. In this article, I’ll build on that base to show how to get started with Django 2 using the current RHEL 8 application stream versions of Python 3 and PostgreSQL 10.

    From my perspective, using Red Hat Enterprise Linux 8 application streams in containers is preferable to using software collections on RHEL 7. While you need to get comfortable with containers, all of the software installs in the locations you’d expect. There is no need to use scl commands to manage the selected software version. Instead, each container gets an isolated user space. You don’t have to worry about conflicting versions.

    In this article, I show you how to create a Red Hat Enterprise Linux 8 Django container with Buildah, and run it with Podman. The code is stored on your local machine and mapped into the container when it runs. You can edit the code on your local machine as you would any other application. Because it is mapped via a volume mount, the changes you make to the code are immediately visible from the container, which is convenient for dynamic languages that don’t need to be compiled.

    While this method isn’t the way you’d want to do things for production, you get essentially the same development inner loop you’d have developing locally without containers. The article also shows how you can use Buildah to build an image with your completed application that you could use for production. Additionally, you’ll set up the RHEL 8 PostgreSQL application stream in a container that is managed by systemd. You’ll be able to use systemctl to start and stop the container just as you would for a non-container installation.

    Prepping Red Hat Enterprise Linux 7

    Before we create our Red Hat Enterprise Linux 8 container on our RHEL 7 system, we need to ensure that we have the necessary software installed, and then either select an example Django app or create our own. Let's walk through this preparation phase.

    Installing Podman and Buildah on RHEL 7

    First, we need to install Podman, which is in the Red Hat Enterprise Linux 7 extras repo. The extras repo isn’t enabled by default. It is recommended that developers also enable the rhscl (Red Hat Software Collections), devtools, and optional repos. To enable all of these at once:

    $ sudo subscription-manager repos --enable rhel-7-server-extras-rpms \
        --enable rhel-7-server-optional-rpms \
        --enable rhel-server-rhscl-7-rpms \
        --enable rhel-7-server-devtools-rpms

    Now install Podman and Buildah:

    $ sudo yum install podman buildah

    Tip: If sudo isn’t set up on your system, see How to enable sudo on Red Hat Enterprise Linux.

    Later, we’ll run containers with systemd. If SELinux is enabled on your system (it is by default), you must turn on the container_manage_cgroup boolean to run containers with systemd:

    $ sudo setsebool -P container_manage_cgroup on

    For more information, see the container running systemd solution.

    Note: The Red Hat ID that was created when you joined Red Hat Developer gives you access to content on the Red Hat Customer Portal.

    Setting up a Django example app

    We need some Django code to run. We’ll use the Polls app from the Writing your first Django app tutorial. Rather than recreating all of the files manually, we’ll pull the code from GitHub. The Django project doesn’t make the example app available for an easy download, but a few users have created repos containing it. I picked monim67/django-polls because the code for each chapter of the tutorial is tagged in the repo.

    Run these commands to create a source directory:

    $ sudo mkdir /opt/src
    $ sudo chown $USER:$USER /opt/src
    $ cd /opt/src
    $ git clone https://github.com/monim67/django-polls.git
    $ cd polls-app
    $ git tag  # see what tags are available
    $ git checkout d2.1t7 # optionally checkout the code for the last chapter

    We now have an example Django app at /opt/src/django-polls.

    Creating your Red Hat Enterprise Linux 8 container image

    Now that our Red Hat Enterprise Linux 7 prep is complete, we can create our custom RHEL 8 container image. Using an existing Red Hat Universal Base Image (UBI) speeds up this process.

    Understanding Red Hat Universal Base Images

    Universal Base Images are universal base images from Red Hat that you can use as a base for your container images. From Mike Guerette’s article, "Red Hat Universal Base Image: How it works in 3 minutes or less:"

    “Red Hat Universal Base Images (UBI) are OCI-compliant container base operating system images with complementary runtime languages and packages that are freely redistributable. Like previous RHEL base images, they are built from portions of Red Hat Enterprise Linux. UBI images can be obtained from the Red Hat Container Catalog and be built and deployed anywhere.

    "And, you don’t need to be a Red Hat customer to use or redistribute them. Really.”

    With the release of Red Hat Enterprise Linux 8 in May, Red Hat announced that all RHEL 8 base images would be available under the new Universal Base Image End User License Agreement (EULA). This fact means that you can build and redistribute container images that use Red Hat’s UBI images as your base, instead of having to switch to images based on other distributions, like Alpine. In other words, you won’t have to switch from using yum to using apt-get when building containers.

    There are three base images for RHEL 8. The standard one is called ubi, or more precisely, ubi8/ubi. This is the image used above and is the one you might use most often. The other two are minimal containers. They have very little supporting software in them for when image size is a high priority and a multi-service image that allows you to run multiple processes inside the container managed by systemd.

    Note: There are also UBI images for RHEL 7 under ubi7 if you want to build and distribute containers running on an RHEL 7 image. For this article, we only use the ubi8 images.

    If you are just starting out with containers, you might not need to delve into UBI details right now. Just use the ubi8 images to build containers based off of RHEL 8. However, you need to understand UBI details when you start distributing container images or have questions about support. For more information, see the references at the end of this article.

    Adding Python 3.6 and Django to a RHEL 8 container (manually)

    Now we need Python 3.6 and Django. We’ll set up a container with the dependencies manually installed and then run the app to see how it’s done.

    Let's use the Red Hat Enterprise Linux 8 Universal Base Image (UBI). But first, log into the new Red Hat Container Registry, which supports authentication, registry.redhat.io. If you don’t log in when you try to pull an image, you’ll get a verbose error message containing the message:

    ...unable to retrieve auth token: invalid username/password

    Use your Red Hat Developer username and password to log into the registry:

    $ sudo podman login registry.redhat.io

    Note: Podman was designed so that it can run without root. However, the support for that feature isn’t there with RHEL 7.6. For more information, see Scott McCarty’s A preview of running containers without root in RHEL 7.6.

    Now, run the container and make the source directory (/opt/src) available inside the container, then expose port 8000 so you can connect to the Django app with a browser on the host system:

    $ sudo podman run -it -v /opt/src:/opt/src:Z -p 8000:8000 registry.redhat.io/ubi8/ubi /bin/bash

    Inside the container, see what application streams are available with Red Hat Enterprise Linux 8:

    # yum module list

    Note: You might notice an extra group of application streams labeled "Universal Base Image."

    Next, install Python 3.6:

    # yum -y module install python36

    Python 3.6 is now installed in our container and is in our path as python3, not python. If you want to know why, see Petr Viktorin’s article, Python in RHEL 8.

    Next use pip to install Django:

    # pip3 install django

    You’ll get a warning about running pip as root. Running pip as root on a real system is generally a bad idea. However, we’re running in a dedicated container that is isolated and disposable, so we can do whatever we want with files in/usr.

    Let’s check where the django-admin command-line interface (CLI) got installed:

    # which django-admin

    The pip command installed the CLI into /usr/local/bin. Now, let’s run the example app inside the container:

    # cd /opt/src/django-polls
    # python3 manage.py runserver 0:8000

    Note: When you run the app, you might see an error message about unapplied migrations. You can ignore this message if you used the above repo, which included a pre-populated SQLite database. If you used a different source or need to create the database, see "Running DB migrations and Django admin inside the container" below.

    Using a browser on the host system, go to http://localhost:8000/admin/. The username and password for the SQLite database that came from the GitHub repo is admin and admin. After logging in, you should get a screen like this:

    Now, you’ve got a container, configured by hand, that will run Django using Red Hat Enterprise Linux 8’s Python 3.6 application stream on your RHEL 7 system. You could treat this container like a pet, and use podman restart -l and podman attach -l when you want to run it again, as long as you don’t delete it. We didn’t name the container, but the -l conveniently selects the last running container. Although this information is handy to know for testing, it’s rarely reproducible.

    An additional problem with this container is that it runs as root in order to be able to install software. Any files created by the container in /opt/src will be owned by root. 

    Creating a Django container image with Buildah

    To make things easier, we’ll create a container image that has Django installed, and will start the Django app any time the container is created. The container won’t have a copy of the app, we’ll still map it into the container from the host system. The code will be stored on your local machine where you can edit it as you would any other application source. Since it is mapped via a volume mount, the changes you make to the code will be immediately visible inside the container.

    When creating images with Buildah, you can use Dockerfiles or Buildah command lines. For this article, we’ll use the Dockerfile approach since other tutorials often use this method.

    Since we're working with files that are shared between your host system and the container, we’ll run the container using the same numeric user ID (UID) as your regular account. When inside the container, any files created in the source directory will be owned by your host system user ID. Find out your UID with the id command:

    $ id

    Make a note of the number after UID= and GID= at the very start of the line. On my system, my UID and GID are both 1000. In the Dockerfile and other examples below, change the USER line to match your UID:GID.

    In /opt/src/django-polls, create Dockerfile with the following content:

    FROM registry.redhat.io/ubi8/python-36
    
    RUN pip3 install django gunicorn psycopg2
    
    # This is primarily a reminder that we need access to port 8000
    EXPOSE 8000
    
    # Change this to UID that matches your username on the host
    # Note: RUN commands before this line will execute as root in the container
    # RUN commands after will execute under this non-privileged UID
    USER 1000:1000
    
    # Default cmd when container is started
    # Default directory was already set by Python container to /opt/app-root/src
    # Get Django to listen on all interfaces so we can connect from outside the container
    CMD python3 manage.py runserver 0:8000
    
    

    A few notes on the Dockerfile. Instead of installing Python 3.6, I used a UBI image from Red Hat that already had Python 3.6 on top of the UBI 8 image. During the build, pip will run inside the container as root because it is above the USER line that changes to a non-privileged user.

    Next, build the Django container:

    $ sudo buildah bud -t myorg/mydjangoapp .

    (Don’t forget the trailing . )

    Now, run the Django container, which should start the Polls app:

    $ sudo podman run --rm -it -p 8000:8000 -v /opt/src/django-polls:/opt/app-root/src:Z myorg/mydjangoapp

    The Django polls app should now be running, which you can verify by using a browser on the host system and going to http://localhost:8000/admin.

    You can now edit the code in /opt/src/django-polls like you would any regular source code. When you need to restart, CTRL+C the container. Note the --rm in the run command, which will automatically remove the container when it exits. To start the container again, use the above podman run command again, which will create a fresh container.

    Setting up your database

    Now to set up a persistent, full-featured database that won't vanish when you shut off the container, and then connect it to Django.

    Running DB migrations and Django admin inside the container

    Since the environment to run Django exists in the container, you’ll need to run any Django admin commands inside it. You can either run a single command or launch a shell inside the container. To apply any DB migrations:

    $ sudo podman run --rm -it -p 8000:8000 -v /opt/src/django-polls:/opt/app-root/src:Z myorg/mydjangoapp python3 manage.py migrate

    Or, to work interactively inside the container, start a shell:

    $ sudo podman run --rm -it -p 8000:8000 -v /opt/src/django-polls:/opt/app-root/src:Z myorg/mydjangoapp /bin/bash

    Note: The shell prompt is set to (app-root) by the Python base image.

    If you wanted to initialize a fresh database:

    (app-root) python3 rm db.sqlite3
    (app-root) python3 manage.py migrate
    (app-root) python3 manage.py createsuperuser

    You can stay in the shell and run the app with:

    (app-root) python3 manage.py runserver 0:8000

    Ensuring database persistence

    By default, the Django polls app uses an SQLite database in the file db.sqlite3, which is in the django-polls directory along with the source code. Because we’ve set up the container to map in a directory from the host, the database will persist between container runs along with our source code.

    Because containers are ephemeral, if the database was stored outside of the /opt/app-root/src directory, it wouldn’t persist between runs of the container. You could fix this issue by applying another volume mount -v to the podman run command.

    Instead of using SQLite, you might want to use a full database server that runs separately from the Django app container.

    Running PostgreSQL 10 in a container

    In this section, we’ll get the Red Hat Enterprise Linux 8 PostgreSQL 10 application stream running in a container managed by systemd on the host system. Searching the Red Hat Container Catalog, we can look for PostgreSQL images. At the time this article was written, there wasn’t a PostgreSQL image based on UBI 8 in the catalog, but there was one based on RHEL 8. We’ll pull the image before running to make it easier to inspect:

    $ sudo podman pull registry.redhat.io/rhel8/postgresql-10

    Since containers are designed to be ephemeral, we need to set up permanent storage for the database. We’ll set up a directory on the host’s system and map it into the container. First, inspect the image to find out the user ID we’ll need for the directories. Alternatively, we could also get information about this image from its Red Hat Container Catalog page:

    $ sudo podman inspect postgresql-10 | grep -A 1 User

    Now that we’ve got the User ID the container will run under, create a directory on the host, give that User ID ownership, and set the context for SELinux:

    $ sudo mkdir -p /opt/dbdata/django-polls-db
    $ sudo chown 26:26 /opt/dbdata/django-polls-db
    $ sudo setfacl -m u:26:-wx /opt/dbdata/django-polls-db
    $ sudo semanage fcontext -a -t container_file_t /opt/dbdata/django-polls-db
    $ sudo restorecon -v /opt/dbdata/django-polls-db

    Let’s test PostgreSQL by hand:

    $ sudo podman run -it --name django-polls-pgsql -e POSTGRESQL_USER=polls -e POSTGRESQL_PASSWORD=mysecret -e POSTGRESQL_DATABASE=django-polls -p 5432:5432 -v /opt/dbdata/django-polls-db:/var/lib/pgsql/data:Z registry.redhat.io/rhel8/postgresql-10

    You should see output that looks like this:

    Success. You can now start the database server using:
    
    pg_ctl -D /var/lib/pgsql/data/userdata -l logfile start
    
    waiting for server to start....
    2019-08-18 21:10:08.545 UTC [31] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
    2019-08-18 21:10:08.554 UTC [31] LOG: redirecting log output to logging collector process
    2019-08-18 21:10:08.554 UTC [31] HINT: Future log output will appear in directory "log".
    done
    server started
    /var/run/postgresql:5432 - accepting connections
    => sourcing /usr/share/container-scripts/postgresql/start/set_passwords.sh ...
    ALTER ROLE
    waiting for server to shut down....
    server stopped
    Starting server...
    2019-08-18 21:10:09.136 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
    2019-08-18 21:10:09.136 UTC [1] LOG: listening on IPv6 address "::", port 5432
    2019-08-18 21:10:09.139 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
    2019-08-18 21:10:09.142 UTC [1] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
    2019-08-18 21:10:09.160 UTC [1] LOG: redirecting log output to logging collector process
    2019-08-18 21:10:09.160 UTC [1] HINT: Future log output will appear in directory "log".

    PostgreSQL started correctly, so you can CTRL+C. Then clean up by removing the container:

    $ sudo podman rm django-polls-pgsql

    Next, create a systemd unit file to manage PostgreSQL. As root, use an editor or cat > to create /etc/systemd/system/django-polls-pgsql.service with the following contents:

    [Unit]
    Description=Django Polls PostgreSQL Database
    After=network.target
    
    [Service]
    Type=simple
    TimeoutStartSec=5m
    ExecStartPre=-/usr/bin/podman rm "django-polls-pgsql"
    
    ExecStart=/usr/bin/podman run --name django-polls-pgsql -e POSTGRESQL_USER=polls -e POSTGRESQL_PASSWORD=mysecret -e POSTGRESQL_DATABASE=django-polls -p 5432:5432 -v /opt/dbdata/django-polls-db:/var/lib/pgsql/data registry.redhat.io/rhel8/postgresql-10
    
    ExecReload=-/usr/bin/podman stop "django-polls-pgsql"
    ExecReload=-/usr/bin/podman rm "django-polls-pgsql"
    ExecStop=-/usr/bin/podman stop "django-polls-pgsql"
    Restart=always
    RestartSec=30
    
    [Install]
    WantedBy=multi-user.target
    
    

    Next, tell systemd to reload, start the PostgreSQL service, and then check the output:

    $ sudo systemctl daemon-reload
    $ sudo systemctl start django-polls-pgsql
    $ sudo systemctl status django-polls-pgsql

    You can check the container logs with:

    $ sudo podman logs django-polls-pgsql

    The PostgreSQL port, 5432, is exposed to the host system. So if you have the client installed, you should be able to connect to the database.

    There are a couple of things to note about the podman run command inside the systemd unit file. Don’t use a -d option to detach from the running container like you would from the command line. Since systemd is managing the process, podman run should not exit until the container dies. If you have a -d, systemd will think the container has failed and will restart it.

    The --rm option to podman run that automatically removed the containers when it exits isn’t used. Instead, systemd is configured to run a podman rm command just before starting the container. This gives you the opportunity to check the state of files inside the stopped container after it exits.

    Configuring Django to use PostgreSQL

    You need to change the settings for the Django site that contains the Polls app to use the PostgreSQL database instead of SQLite. Edit /opt/src/django-polls/mysite/settings.py and change the DATABASES section to:

    DATABASES = {
      'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django-polls',
        'USER': 'polls',
        'PASSWORD': 'mysecret',
        'HOST': 'localhost',
      }
    }
    
    

    Using Buildah to create an image with your Django app

    After you’ve developed your app, you can use Buildah to create a distributable container image with your Django app. We’ll use Buildah command lines instead of a Dockerfile. This method is much more flexible for complex builds and automation. You can use shell scripts or whatever tools you use for your build environment:

    #!/bin/sh
    # Build our Django app and all the dependencies into a container image
    # Note: OOTB on RHEL 7.6 this needs to be run as root.
    MYIMAGE=myorg/mydjangoapp
    USERID=1000
    
    IMAGEID=$(buildah from ubi8/python-36)
    buildah run $IMAGEID pip3 install django gunicorn psycopg2
    
    # any build steps above this line run as root
    # after this build steps run as $USERID
    buildah config --user $USERID:$USERID $IMAGEID
    
    buildah copy $IMAGEID . /opt/app-root/src
    
    # Any other prep steps go here. you could apply migrations, etc.
    buildah config --cmd 'python3 manage.py runserver 0:8000' $IMAGEID
    
    buildah commit $IMAGEID $MYIMAGE
    
    

    Now, make app-image-buils.sh executable, then build the image:

    $ chmod +x app-image-build.sh
    $ sudo ./app-image-build.sh

    Now you can run and test the new image:

    $ sudo podman run --rm -it --net host myorg/mydjangoapp

    The run command no longer needs the volume mount, because the code is now inside the container, and the data is managed by the PostgreSQL container’s volume.

    When you are ready, you can distribute your application to others by pushing it to a container registry like Red Hat’s Quay.io.

    Managing your Django app with systemd

    You can manage your new Django app with systemd so it will start on system boot. As root, create the systemd unit file /etc/systemd/system/django-polls-app.service with the following contents:

    [Unit]
    Description=Django Polls App
    
    After=django-polls-pgsql.service
    
    [Service]
    Type=simple
    TimeoutStartSec=30s
    ExecStartPre=-/usr/bin/podman rm "mydjangoapp"
    
    ExecStart=/usr/bin/podman run --name mydjangoapp --net host myorg/mydjangoapp
    
    ExecReload=-/usr/bin/podman stop "myorg/mydjangoapp"
    ExecReload=-/usr/bin/podman rm "myorg/mydjangoapp"
    ExecStop=-/usr/bin/podman stop "myorg/mydjangoapp"
    Restart=always
    RestartSec=30
    
    [Install]
    WantedBy=multi-user.target

    Tell systemd to reload, then start the app.

    $ sudo systemctl daemon-reload
    $ sudo systemctl start django-polls-app

    Next steps

    By now, you should see that it is pretty easy to get the software components you need running in containers so you can focus on development. It shouldn’t feel too different from developing without containers. Hopefully, you can see how to build on these instructions for your own apps.

    You should check out what other UBI 8 images are available for you to use in the Red Hat Container Catalog. If the language, runtime, or server isn't available as a UBI image, you can build your own using the UBI 8 base image. Then, you can add the application streams and other RPMs you need with yum commands in a Dockerfile, or with buildah run.

    The setup in this article has a number of drawbacks as it was intended to be a quick and easy to digest demo. There are many ways one could improve the setup. For example, the Django container with the packaged app is configured to share the host’s network with --net host, which made it simple for the Django process to connect to the database via localhost. While this setup is quick and easy for development, you don’t get the network isolation that containers offer.

    One of the ways the network configuration could be improved is to use Podman’s pod capabilities to put the web and database containers in the same pod where they share namespaces. See Brent Baude’s article Podman: Managing pods and containers in a local container runtime.

    More information

    Related articles:

    • Run Red Hat Enterprise Linux 8 in a container on RHEL 7 (Covers PHP 7.2, MariaDB, and WordPress running in containers.)
    • Setting up a Django application on RHEL 8 Beta

    Cheat sheets:

    • Podman Basics Cheat Sheet
    • Red Hat Enterprise Linux 8 Cheat Sheet

    Podman and Buildah:

    • Podman and Buildah for Docker Users
    • Managing containerized system services with podman
    • Podman: Managing pods and containers in a local container runtime
    • Getting Started with Buildah
    • Building, Running, and Managing Containers - RHEL 8 Documentation
    • Getting Started with Containers - RHEL 7 Documentation

    UBI: 

    • Red Hat Universal Base Image: How it works in 3 minutes or less
    • The UBI page on Red Hat Developers
    • UBI FAQ
    Last updated: April 3, 2023

    Recent Posts

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    • How to integrate vLLM inference into your macOS and iOS apps

    What’s up next?

     

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue