• Members 153 posts
    Feb. 14, 2023, 10:40 p.m.

    This is provided as an example, on the off-chance it might be useful to someone, and it does not claim to be authoratative. No warranty is implied or given. Use at your own risk. This may not be the best way to do this, and it may have unforseen failings.

    requirements: podman, git

    The use case here is to install an opinionated production ready misago in a podman pod, with an external postgresql database (ie in another pod, or externally provisioned - one can also add a postgresql container to this pod), and behind a reverse-proxy that handles certificates and access authentication. In my case this is caddy2, but it should work with the usual suspects. Backup, in my case, is handled by the excellent borgmatic which dumps the database and de-duplicate and backups that and the static files. So you should note that this guide does not address backup.

    Building


    Move to your build host and git clone the latest misago-docker

    git clone https://github.com/rafalp/misago_docker.git --depth=1
    

    then cd into the misago directory within the cloned repository, and build the misago container

    podman build -t localhost/misago:0.29 -f Dockerfile
    

    This example is for the current (at the time of writing) version 0.29. Amend this tag on the container to reflect the version actually built.

    Backup the image

    This can be useful in the case that you are building the image to use it on a different machine (without pushing it to a repository), or to include in your backup sets to rebuild your stack.

    podman save -m -o misago.0.29.tar \
    localhost/misago:0.29
    

    to load this image on another machine, or to restore it as part of a backup restore.

    podman load -i misago.0.29.tar
    

    Define the image to use

    Tag this image as the latest image. This will allow us the facility to build future versions and tag as latest the image that we wish our deployment to use, as well as the option for automatic updates controlled by podman.

    podman image tag localhost/misago:0.29 localhost/misago:latest
    

    Preparing the installation

    Choose the preferred location for your containers persistent files. I tend to use /var/lib/misago for systems level installations, but you don't have to. You may prefer something in the user home directory if you are running the containers rootless (you are on your own there, I'm keeping this simple by way of example). Let's call this location [app]

    create directory structure

    This is the file structure your containers will need to persist values.

    mkdir -p [app]/{logs,misago,nginx,redis}
    mkdir -p [app]/nginx/vhost.d
    mkdir -p [app]/logs/{nginx,misago,celery}
    mkdir -p [app]/misago/{avatargallery,media,static,theme,userdata}
    mkdir -p [app]/misago/theme/{static,template}
    

    Add the nginx configuration

    Into the [app]/nginx directory put the custom nginx.conf to serve misago to the reverse proxy of your choice. In the server block, this needs to reflect the pod name that you create for the install. In this case myinstance (see server_name myinstance; # substitute your machine's IP address or FQDN). Note that the location alias of /media and /static refers to within the container, and does not require changing.

    # nginx.conf
    
    events {}
    
    http {
    
        include /etc/nginx/mime.types;
    
        upstream misago {
        # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
        server 127.0.0.1:3031; # for a web port socket (we'll use this first)
        }
    
        server {
            # the port your site will be served on
            listen      80;
            # the domain name it will serve for
            server_name myinstance; # substitute your machine's IP address or FQDN
            charset     utf-8;
    
            # max upload size
            client_max_body_size 75M;   # adjust to taste
    
            # Django media
            location /media  {
                alias /misago/media;  # your Django project's media files - amend as required
    
                uwsgi_param Host $host;
                uwsgi_param X-Real-IP $remote_addr;
                uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
                uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
    
            }
    
            location /static {
                alias /misago/static; # your Django project's static files - amend as required
    
                uwsgi_param Host $host;
                uwsgi_param X-Real-IP $remote_addr;
                uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
                uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
    
            }
    
            # Finally, send all non-media requests to the Django server.
            location / {
                uwsgi_pass  misago;
                include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
    
                uwsgi_param Host $host;
                uwsgi_param X-Real-IP $remote_addr;
                uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
                uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
    
            }
        }
    }
    

    create [your.domain.com]_location in the nginx/vhost.d directrory

    # your.domain.com_location
    
    # Additional Nginx configuration for Misago vhost
    
    # Set max upload size at 16 megabytes
    client_max_body_size 16M;
    
    # Enable GZIP
    gzip  on;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_min_length 1100;
    gzip_buffers     4 8k;
    gzip_proxied any;
    gzip_types
        # text/html is always compressed by HttpGzipModule
        text/css
        text/javascript
        text/xml
        text/plain
        text/x-component
        application/javascript
        application/json
        application/xml
        application/rss+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;
    
    location /static/ {
        root /misago;
        expires max;
    
        # Enable GZIP
        gzip  on;
        gzip_http_version 1.0;
        gzip_comp_level 2;
        gzip_min_length 1100;
        gzip_buffers     4 8k;
        gzip_types
            # text/html is always compressed by HttpGzipModule
            text/css
            text/javascript
            text/xml
            text/plain
            text/x-component
            application/javascript
            application/json
            application/xml
            application/rss+xml
            font/truetype
            font/opentype
            application/vnd.ms-fontobject
            image/svg+xml;
    }
    
    location /media/ {
        root /misago;
        expires max;
    
        # Enable GZIP
        gzip  on;
        gzip_http_version 1.0;
        gzip_comp_level 2;
        gzip_min_length 1100;
        gzip_buffers     4 8k;
        gzip_types
            # text/html is always compressed by HttpGzipModule
            text/css
            text/javascript
            text/xml
            text/plain
            text/x-component
            application/javascript
            application/json
            application/xml
            application/rss+xml
            font/truetype
            font/opentype
            application/vnd.ms-fontobject
            image/svg+xml;
    
    
  • Members 153 posts
    Feb. 14, 2023, 10:42 p.m.

    Deploying the service

    Modify the volume mounts, and the env variables, (along with any pod/container name changes) below to suit your own installation. The label --label io.containers.autoupdate=local is included to allow for podman autoupdate of images. Omit if not required. All images not built are pulled from docker hub and labelled locally (not covered, but eg podman pull nginx:1.23.3-alpine-slim - then use podman image tag nginx:1.23.3-alpine-slim localhost/nginx:latest to label for locally upgradeable images).

    Create the pod

    podman pod create --name myinstance
    

    In the following containers, the label --pod=myinstance ensures that they are created in this pod.

    Create the redis container

    podman run \
      -d --pod=myinstance \
      --name=myinstance-redis --label io.containers.autoupdate=local \
      -v [app]/myinstance/redis:/data \
      localhost/redis:latest \
      redis-server  --port 6379 --save 600 1 --loglevel warning
    

    Create the misago container

    podman run -d --pod=myinstance --name=myinstance-misago \
        -v [app]/misago/media:/misago/media \
        -v [app]/misago/static:/misago/static \
        -v [app]/misago/avatargallery:/misago/avatargallery \
        -v [app]/misago/theme:/misago/theme \
        -v [app]/logs/misago:/misago/logs \
        -e MISAGO_ADDRESS=https://[your.domain.com]/ \
        -e MISAGO_DAILY_BACKUP=no \
        -e MISAGO_DEBUG=no \
        -e MISAGO_DEFAULT_FROM_EMAIL='Your Forum <youradmin@yourmail.domain>' \
        -e MISAGO_EMAIL_PROVIDER=smtp \
        -e MISAGO_EMAIL_USE_TLS=yes \
        -e MISAGO_EMAIL_USE_SSL=no \
        -e MISAGO_EMAIL_HOST=[yourmail_server] \
        -e MISAGO_EMAIL_PASSWORD=[your_email_server.password] \
        -e MISAGO_EMAIL_USER=[your_email_server.login] \
        -e MISAGO_EMAIL_PORT=587 \
        -e MISAGO_LANGUAGE_CODE=en-gb \
        -e MISAGO_TIME_ZONE=Europe/London \
        -e MISAGO_SEARCH_CONFIG=english \
        -e MISAGO_SECRET_KEY=[your_misago_secret] \
        -e POSTGRES_USER=[postgres_user] \
        -e POSTGRES_PASSWORD=[postgres_password] \
        -e POSTGRES_DB=[postgres_database] \
        -e POSTGRES_HOST=[postgres_host] \
        -e VIRTUAL_HOST=[your.domain.com] \
        -e VIRTUAL_PROTO=uwsgi \
        --label io.containers.autoupdate=local localhost/misago:latest
    

    Create the celery container

    podman run -d --pod=myinstance --name=myinstance-celery \
        -v [app]/misago/media:/misago/media \
        -v [app]/misago/static:/misago/static \
        -v [app]/misago/theme:/misago/theme \
        -v [app]/logs/misago:/misago/logs \
        -e MISAGO_ADDRESS=https://[your.domain.com]/ \
        -e MISAGO_DAILY_BACKUP=no \
        -e MISAGO_DEBUG=no \
        -e MISAGO_DEFAULT_FROM_EMAIL='Your Forum <youradmin@yourmail.domain>' \
        -e MISAGO_EMAIL_PROVIDER=smtp \
        -e MISAGO_EMAIL_USE_TLS=yes \
        -e MISAGO_EMAIL_USE_SSL=no \
        -e MISAGO_EMAIL_HOST=[yourmail_server] \
        -e MISAGO_EMAIL_PASSWORD=[your_email_server.password] \
        -e MISAGO_EMAIL_USER=[your_email_server.login] \
        -e MISAGO_EMAIL_PORT=587 \
        -e MISAGO_LANGUAGE_CODE=en-gb \
        -e MISAGO_TIME_ZONE=Europe/London \
        -e MISAGO_SEARCH_CONFIG=english \
        -e MISAGO_SECRET_KEY=[your_misago_secret] \
        -e POSTGRES_USER=[postgres_user] \
        -e POSTGRES_PASSWORD=[postgres_password] \
        -e POSTGRES_DB=[postgres_database] \
        -e POSTGRES_HOST=[postgres_host] \
        -e VIRTUAL_HOST=[your.domain.com] \
        -e VIRTUAL_PROTO=uwsgi \
        --label io.containers.autoupdate=local localhost/misago:latest  celery -A misagodocker worker --loglevel=info
    

    Create the nginx container

    podman run \
      -d --pod=myinstance \
      --name=myinstance-nginx --label io.containers.autoupdate=local \
      -e ENABLE_IPV6=true \
      -v [app]/misago/media:/misago/media \
      -v [app]/misago/static:/misago/static \
      -v [app]/logs/nginx:/var/log/nginx \
      -v [app]/nginx/nginx.conf:/etc/nginx/nginx.conf \
      -v [app]/nginx/vhost.d:/etc/nginx/vhost.d \
      localhost/nginx:latest
    

    Finalise the Installation

    Essential migration/setup

    use podman exec to access the misago container, and setup the application.

    podman exec -it myinstance-misago bash
    

    initialise the database

    ./.run initialize_default_database
    

    add the superuser credentials when prompted

    SUPERUSER_USERNAME=[admin]
    SUPERUSER_EMAIL=[admin_email]
    SUPERUSER_PASSWORD=[admin_password]

    Complete

    You now should have a working misago installation, which you can view successfully via your reverse proxy. Configuration of that is out of scope here, but you should configure it to produce certificates for the site, forward to https, and pass on the X-Forwarded headers.

    In caddy that is as simple as adding to the caddyfile:

    your.domain.com {
            reverse_proxy myinstance:80
    }
    
  • Members 153 posts
    Feb. 14, 2023, 10:43 p.m.

    Optional Setup

    these commands can be accessed by exec'ing into bash in the container

    podman exec -it myinstance-misago bash
    

    email test

    You can check the site email with a test

    python manage.py sendtestemail test@email.address
    

    maintennance tasks

    Perform regular maintennance tasks manually

    ./cron
    

    You should see an output similar to this:

    Deleted users: 0
    
    
    Categories were pruned
    
    Building active posters ranking...
    Finished after 0.05s
    
    
    No unused attachments were cleared
    
    
    No expired entries were found
    Bans invalidated: 0
    Ban caches emptied: 0
    IP addresses older than 90 days have been removed.
    Automatic deletion of inactive user accounts is currently disabled.
    Data downloads expired: 0
    Data downloads prepared: 0
    

    you can also automate this directly without exec'ing bash in the container. This allows you to create a system level cron job, or a systemctl timer to automate maintennance.

    podman exec -it myinstance-misago ./cron
    

    additional maintenance options

    these scripts are the standard scripts that the wizard uses in the dockler-compose install, and are mentioned here as they are accessible through bash in the container.

    to migrate database

    python manage.py migrate
    

    load avatar gallery

    python manage.py loadavatargallery
    

    to setup admin account

    python manage.py createsuperuser
    

    to collect static assets after that you will have to run

    python manage.py collectstatic
    

    something something versioned caches

    python manage.py invalidateversionedcaches 
    

    Using systemctl to control the pod/containers

    The containers created will not restart if stopped, nor on reboot. They will have to be manually started and stopped. Which is fine while testing. Once you are happy with your installation you may wish to choose automating the handling of the service using systemctl (you may not, but you are on your own with that).

    create systemctl files

    ...in a scratch directory (or in your backup path), create the necessary systemd files.

    podman generate systemd --files --new --name myinstance
    

    this should output something like:

    [working_directory]/container-myinstance-nginx.service
    [working_directory]/pod-myinstance.service
    [working_directory]/container-myinstance-misago.service
    [working_directory]/container-myinstance-celery.service
    [working_directory]/container-redis.service
    

    In order to work with misago the redis service is just called 'redis' within the pod, but to avoid overwriting any other container services just named 'redis' in our systemd folder, we need to rename the systemd file.

    mv container-redis.service container-myinstance-redis.service
    

    then we need to update the configurations to refer to myinstance-redis instead of redis.

    in pod-myinstance.service change

    Wants=container-redis.service container-myinstance-celery.service container-myinstance-misago.service container-myinstance-nginx.service
    Before=container-redis.service container-myinstance-celery.service container-myinstance-misago.service container-myinstance-nginx.service
    

    to be

    Wants=container-myinstance-redis.service container-myinstance-celery.service container-myinstance-misago.service container-myinstance-nginx.service
    Before=container-myinstance-redis.service container-myinstance-celery.service container-myinstance-misago.service container-myinstance-nginx.service
    

    Then in container-myinstance-redis.service change

    Description=Podman container-redis.service
    

    to be

    Description=Podman container-myinstance-redis.service
    

    (repeat for # container-redis.service at the top of the file for tidyness, not required for functionality)

    This will still start the container as redis in the myinstance pod, but it will stop other container-redis systemd files from conflicting with myinstance, in the event that you have other services running that also need redis containers simply named as redis.

    The systemd configuration files are now prepared to enable the service

    enable systemctl autostart

    Copy these files to your /etc/systemd/system/ directory, to enable the pod as a service.

    cp pod-myinstance.service /etc/systemd/system/pod-myinstance.service
    cp container-myinstance-nginx.service /etc/systemd/system/container-myinstance-nginx.service
    cp container-myinstance-redis.service /etc/systemd/system/container-myinstance-redis.service
    cp container-myinstance-misago.service /etc/systemd/system/container-myinstance-misago.service
    cp container-myinstance-celery.service /etc/systemd/system/container-myinstance-celery.service
    

    Now we can control our misago service using systemctl

    Stop and delete the containers that you have built in your myinstance pod, and delete the myinstance pod. The data will be persisted in the database and in the volume mounts. Now re-enable the service using systemctl.

    systemctl enable pod-myinstance.service
    systemctl start pod-myinstance.service
    
    

    You should now see that the myinstance pod, and the containers, have rebuilt, and it will automatically restart on reboot.

    as well as enable we can use start,stop,status, and disable.

    Note: If you do want to stop the containers you need to do so with systemctl (not with podman), or it will auto-restart them. Which is what enabling them as a service is for.

    Auto-updating containers

    Because we have labelled the containers with --label io.containers.autoupdate=local To update the container images, all we need to do is pull, or build, the new images, and tag them as with the :latest tag for the image in question. Then use

    podman auto-update --dry-run
    

    if you are happy to proceed, then just run

    podman auto-update
    

    Note on backups

    To backup an instance there are two aspects that we need to consider. One is the database, and one the static files.

    The database should be achieved using a dump of the database. borgmatic has database hooks that can automate this as part of the backup process. Depending on the nature of your postgresql provision, there are various options for that, which are not in scope here.

    The static files should be backed up when there is no chance of a conflicting write during the process. It may be possible to snapshot the storage, and thus perform an uninterrupted backup. This will depend on the storage provision on your individual setup. If this is not possible, then it is best to temporarily stop the service, backup, and then restart the service. For example you might use a script like this (which could be run by cron or systemctl timer):

    #!/bin/bash
    /bin/systemctl stop pod-myinstance
    rsync -avzh /[app] /backup/[app]
    /bin/systemctl start pod-myinstance
    
  • Members 153 posts
    Feb. 15, 2023, 2:13 p.m.

    I think it's a process/scheme that should work equally well with kubernetes and even docker (without compose). It's useful, I hope, for people who want a custom setup on a server not dedicated to just misago (my use case). For self-hosters, this should make misago a bit more accessible. Should they want/need that sort of thing.

    I'm not 100% convinced about the nginx setup (I don't really use it much, and never except in this sort of serving an application within a namespace/pod)...but it seems to work, and it works behind a reverse proxy...so hopefully I've got the bits it needs, but not the bits it doesn't (related to certificate production).

    ...oh, and while I think about it. because the misago container can be entirely built and configured (using env variables, and volume mounts) without any user/installation specific elements, there's no reason that it couldn't be published (eg to docker hub). I didn't want to do this. The worry is that it triggers support requests not related to the application itself.

    ..but you might be for it?

  • Feb. 15, 2023, 3:54 p.m.

    Making official docker image for Misago is something that I both should do and absolutely have no time or energy to maintain on top of rest of things I have to do to keep Misago running :D

    But having community-maintained image would be okay.

  • Members 153 posts
    Feb. 15, 2023, 4:16 p.m.

    I haven't done that...and I've only built for my target platform....but I can do it I think. So I might as well.

    It might only be manual limited builds to start with, until I work out what I'm doing with it.

  • Members 153 posts
    Feb. 19, 2023, 1:26 p.m.

    I would like to be able to run more than one installation, on the same server, in different pods (use case: check new version before deploying; multiple installations for different purposes; production and development installation).

    Currently the deployment expects to find a service called redis in localhost. but I can't run multiple containers called the same thing (redis) on the same podman installation.

    So I would like to be able to set the redis location as myinstance-redis, ideally using an environment variable at runtime. I think all of the required settings are in the settings.py file in misago/misagodocker/settings.py but I can't work out what and how.

    Might you have some pointers as to how that might be achieved?

  • Feb. 19, 2023, 4:17 p.m.

    Redis URL is hardcoded in Misago Docker:

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://redis/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        }
    }
    
    CELERY_BROKER_URL = "redis://redis/0"
    

    You can make it configurable through env vars (CACHE_REDIS_URL, CELERY_BROKER_URL) by replacing those two lines:

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": os.environ.get("CACHE_REDIS_URL", "redis://redis/1"),
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        }
    }
    
    CELERY_BROKER_URL =  os.environ.get("CELERY_BROKER_URL", "redis://redis/0")
    

    If those env vars are not set, Misago will default to old urls.

  • Members 153 posts
    Feb. 25, 2023, 12:21 p.m.

    I've had a go at that, and it seems like there are other places where the redis location is hardcoded.....ie this doesn't work.

    Migrating database
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, misago_acl, misago_cache, misago_categories, misago_conf, misago_core, misago_icons, misago_legal, misago_menus, misago_oauth2, misago_readtracker, misago_socialauth, misago_themes, misago_threads, misago_users, sessions, social_django
    Running migrations:
      No migrations to apply.
    Loading default avatar gallery
    New galleries have been loaded.
    Creating first superuser account
    Traceback (most recent call last):
      File "/usr/local/lib/python3.11/site-packages/django_redis/cache.py", line 31, in _decorator
        return method(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/django_redis/cache.py", line 98, in _get
        return self.client.get(key, default=default, version=version, client=client)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/django_redis/client/default.py", line 260, in get
        raise ConnectionInterrupted(connection=client) from e
    django_redis.exceptions.ConnectionInterrupted: Redis ConnectionError: Error -2 connecting to redis:6379. Name or service not known.
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/misago/manage.py", line 23, in <module>
        execute_from_command_line(sys.argv)
      File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
        utility.execute()
      File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 413, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 354, in run_from_argv
        self.execute(*args, **cmd_options)
      File "/usr/local/lib/python3.11/site-packages/misago/users/management/commands/createsuperuser.py", line 73, in execute
        return super().execute(*args, **options)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 398, in execute
        output = self.handle(*args, **options)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/misago/users/management/commands/createsuperuser.py", line 84, in handle
        settings = get_dynamic_settings()
                   ^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/misago/conf/shortcuts.py", line 7, in get_dynamic_settings
        return DynamicSettings(cache_versions)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/misago/conf/dynamicsettings.py", line 9, in __init__
        self._settings = get_settings_cache(cache_versions)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/misago/conf/cache.py", line 9, in get_settings_cache
        return cache.get(key)
               ^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/django_redis/cache.py", line 91, in get
        value = self._get(key, default, version, client)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/django_redis/cache.py", line 38, in _decorator
        raise e.__cause__
      File "/usr/local/lib/python3.11/site-packages/django_redis/client/default.py", line 258, in get
        value = client.get(key)
                ^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/redis/commands/core.py", line 1705, in get
        return self.execute_command("GET", name)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 1235, in execute_command
        conn = self.connection or pool.get_connection(command_name, **options)
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 1387, in get_connection
        connection.connect()
      File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 617, in connect
        raise ConnectionError(self._error_message(e))
    redis.exceptions.ConnectionError: Error -2 connecting to redis:6379. Name or service not known.
    
  • Members 153 posts
    Feb. 25, 2023, 6:07 p.m.

    The above is a mistake of my making. I hadn't correctly passed the redis cache env variables to the misago container.

    Having done that, it now looks like it's working.

    This is a very good thing for me, as it means I can run multiple instances on the same server (eg, production, development). Would it be possible to request this as a permanent change for upcoming versions?

  • Feb. 25, 2023, 6:31 p.m.
  • Members 153 posts
    Feb. 25, 2023, 7 p.m.

    Is there a reason you wouldn't want to add it to the official release? I don't think it changes anything on the official build, it just formalises an option to over-ride it with env variable.

  • Feb. 27, 2023, 2:42 p.m.

    I just don't understand your approach to misago-docker. Is your podman setup just re-using misagodocker directory from it?

    But I guess I can make this part of standard.

  • Members 153 posts
    Feb. 27, 2023, 5 p.m.

    I build a misago image exactly the same way that your docker-compose build script does. It's just that how I deploy the containers to have a functioning application is different. Because my container platform requires each container to have a unique name (this is used by local dns to address the container), that means that installing multiple instances of misago is not possible because the local address for redis conflicts for multiple instances.

    This change would mean that as default, nothing changes for your official build process...but for building multiple deployments, on the same server, it is possible to have redis servers (named/addressed differently) for each deployment. I think it is the only change necessary.

    This means that it is possible to run misago on a wider range of containerised targets, and allows people to run different instances for different domain names, as well as production and development installations on the same container environment.

  • Members 153 posts
    March 20, 2023, 2:26 p.m.

    To upgrade to a new image:

    Run cron to update the container status to current

    podman exec -it myinstance-misago ./cron
    

    Pull the image, and tag it as your local latest image.

    podman pull docker.io/tetricky/misago-image:0.30
    
    podman image tag docker.io/tetricky/misago-image:0.30 localhost/misago:latest
    

    Update the image in the running containers. Checking first

    podman auto-update --dry-run
    

    Then applying if happy with the changes

    podman auto-update
    

    Access the bash shell in the container

    podman exec -it myinstance-misago bash
    

    Run the upgrade procedure

    first collectstatic

    python manage.py collectstatic
    

    run migrate

    python manage.py migrate
    

    finally invalidateversionedcaches

    python manage.py invalidateversionedcaches
    

    Exit the bash shell, and then restart the pod/containers

    systemctl restart pod-myinstance.service