Skip to content

From AWS to DIY: Building a Cost-Effective ๐Ÿ’ธ Home Server with Ubuntu Server, Docker, Portainer, Traefik & CrowdSec on a High-Performance Mini PC! ๐Ÿš€

As a software engineer, Iโ€™ve relied on AWS for cloud computing for some time, but the rising costs finally pushed me to rethink things ๐Ÿ’ธ. During Black Friday, I jumped on a deal I couldnโ€™t resist ๐ŸŽ‰ and built a home setup around a GMKtec mini PC with an AMD Ryzen 7 8845HS, paired with 2 x 48GB of DDR5 5600MHz Crucial RAM and two 4TB Samsung 990 PRO PCIe 4.0 NVMe M.2 SSDs. The whole setup cost me โ‚ฌ1,100 (about $1,200 USD) and runs at only 35W โšกโ€”thatโ€™s roughly โ‚ฌ4.30 ($4.60 USD) a month in electricity here in France ๐Ÿ‡ซ๐Ÿ‡ท. Compare that to the $517 per month Iโ€™d pay to run an AWS EC2 m8g.4xlarge instance. Now, Iโ€™ve got 16 CPUs (8 cores, 16 threads) ๐Ÿ’ป, 96GB of speedy RAM โš™๏ธ, and 8TB of PCIe 4.0 NVMe storage ๐Ÿ’พ for demanding workloads. Itโ€™s a massive money-saver ๐Ÿ’ฐ and the perfect base for a home lab running Ubuntu Server ๐Ÿง. Tools like Portainer make container management easy ๐Ÿ› ๏ธ, and Traefik with CrowdSec enhances reverse proxying & security ๐Ÿ”’. If cloud costs are draining your budget, making the switch is well worth it ๐Ÿš€!

Ubuntu Server, Docker, Portainer, Traefik & CrowdSec

๐Ÿค” Ubuntu Server, Docker, Portainer, Traefik & CrowdSec?

What are Ubuntu Server, Docker, Portainer, Traefik, and CrowdSec? Quickly:

  • ๐Ÿง Ubuntu Server: Ubuntu Server is a robust and popular Linux-based operating system designed for server environments, providing the foundation for building reliable and secure web applications and services.
  • ๐Ÿณ Docker: Docker is a platform that allows developers to automate the deployment of applications inside lightweight, portable containers, simplifying environment management and ensuring consistency across different systems.
  • ๐Ÿ› ๏ธ Portainer: Portainer is a simple and easy-to-use management interface for Docker, providing a graphical dashboard for managing containers, images, and volumes, which helps streamline container operations for developers.
  • ๐Ÿ”„ Traefik: Traefik is a modern and powerful reverse proxy and load balancer designed for dynamic container environments. It integrates seamlessly with Docker, automatically discovering and routing requests to services while supporting Let's Encrypt SSL, middleware, and advanced traffic management.
  • ๐Ÿ›ก๏ธ CrowdSec: CrowdSec is an open-source security tool that analyzes logs to detect and prevent malicious activity. It uses community-driven threat intelligence to block attackers in real-time, enhancing server security through behavioral detection and IP reputation filtering.

At the end of this guide, you should be able to set up a home server environment with Ubuntu Server, Docker, Portainer, Traefik, and CrowdSecโ€”enabling efficient container management, secure reverse proxying, and proactive threat defense. Let's get started! ๐Ÿš€

๐Ÿ”Œ Create a Bootable USB Key

In this part, we are going to create a bootable USB key using Rufus.

Create a bootable USB key with Rufus
Create a bootable USB key with Rufus

The goal is to set up a USB drive that will allow us to easily install Ubuntu Server on a system.

Go to rufus.ie to download and install Rufus.

Install Rufus
Install Rufus

Do the same for Ubuntu Server at ubuntu.com/download/server.

Download Ubuntu Server ISO
Download Ubuntu Server ISO

Now it's time to create a bootable USB key with the Ubuntu Server ISO. Plug in your USB key, open Rufus, and for Boot selection, select the downloaded Ubuntu Server ISO. Hereโ€™s what your configuration should look like:

Rufus Configuration
Rufus Configuration

Click on START, and now all you have to do is wait ๐Ÿ‘. Congratulations, you've set up a bootable USB key! Let's use it to install Ubuntu Server on our machine!

๐Ÿง Install Ubuntu Server OS

The goal now is to use the USB key containing our Ubuntu Server ISO to install Ubuntu Server on our machine.

Install Ubuntu Server OS
Install Ubuntu Server OS

The ultimate goal is to have a machine that we can connect to via SSH, just like one rented from any cloud provider ๐Ÿ˜‰.

Start by plugging the USB key, then turn ON the machine and open the BIOS. To open the BIOS, restart your PC and press the designated key (commonly F2, F12, Delete, or Esc), which depends on your PC's manufacturer.

The USB key is set as the first boot option
The USB key is set as the first boot option

As explained on the screen, the USB key is set as the first boot option. Then restart the machine, you should be welcomed with the choice: Try or install Ubuntu Server.

Try or install Ubuntu Server
Try or install Ubuntu Server

Select this choice, and then you will follow a series of instructions. Here are some tricky parts (obvious parts will not be detailed; regarding the few screens that will appear, I am not the original author. If you wish for a more detailed explanation, please check out SavvyNik's video ๐Ÿ‘).

  • Choose the basic installation.
Choose the basic installation
Choose the basic installation
  • Set up the internet connection via Ethernet or WiFi.
Network connections
Network connections

On your side, you may have more interfaces. It can also be via WiFi ๐Ÿ‘! The important thing is to have one set up because internet will be needed for package downloads and updates, and, of course, for the SSH connection through the home network.

  • Use an entire disk and Set up this disk as LVM group.
Guided storage configuration
Guided storage configuration
  • Set the storage configuration to utilize all the disk space.

For the storage configuration part, by default, it does not utilize all the disk space. You can see this in the free space field in the DEVICE section:

Storage configuration - Before
Storage configuration - Before

So the goal is to allocate all this unconfigured free space to ubuntu-lv. This will allow you to utilize all your disk space for your files, packages, etc.

Storage configuration - Editing logical volumne ubuntu-lv of ubuntu-vg
Storage configuration - Editing logical volumne ubuntu-lv of ubuntu-vg
Storage configuration - After
Storage configuration - After
  • Install OpenSSH server.
Install OpenSSH server
Install OpenSSH server
  • Regarding Featured Server Snaps, do not select anything and select Done; it will start installing packages, be patient, and then just click Reboot Now.
Install complete!
Install complete!
  • You can now login!

Let it boot, and you should encounter an error because the USB key is still plugged in, and the server tries to boot from it. Turn off the server, remove the USB key, and then boot up the server. If you end up with the following screen, congratulations, you've successfully installed Ubuntu Server ๐Ÿ˜!

You can now login!
You can now login!

Final thing, let's check if we can connect to the server from another machine via SSH. First, find the server's IP by logging in and running the following command on the server:

From server
ip a

It should give you a list of interfaces. Find the one that has an inet address formatted as 192.168.1.X:

From server
...
4: wlp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.X/24 metric 600 brd 192.168.1.255 scope global dynamic wlp4s0
       valid_lft 38554sec preferred_lft 38554sec
    inet6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 86165sec preferred_lft 86165sec
    inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
       valid_lft forever preferred_lft forever
...

Let's connect via SSH.

From work machine
ssh myuser@192.168.1.X

If it connects:

From work machine
...
Last login: Mon Jan 13 05:49:37 2025 from 192.168.1.Y
myuser@myserver:~$

Then, congratulations! You've successfully set up a server similar to the ones you can rent from AWS or any other cloud provider ๐Ÿคฉ. All the following commands will be executed from the work machine on behalf of the server via SSH from now on!

๐ŸŒ Prepare DNS and ISP Router settings to forward HTTP/HTTPS requests

In this section, we will prepare our DNS provider and ISP router to expose our services to the outside world. Depending on your ISP and domain name provider, it is highly likely that you will not have the exact same screens.

Prepare DNS and ISP Router settings to forward HTTP/HTTPS requests
Prepare DNS and ISP Router settings to forward HTTP/HTTPS requests

Let's start by forwarding ports 80 and 443 requests from our ISP router to our server's ports 80 and 443:

Forwarding ports 80 and 443 requests
Forwarding ports 80 and 443 requests

Let's now get the CNAME or router's Internet IP:

Getting CNAME or router Internet IP
Forwarding ports 80 and 443 requests

Note

You can also go to sites like whatismyip.com to get your IP.

Now let's buy a domain name. In my case I choosed namecheap.com. After buying the domain name, let's configure it to be routed to our ISP router.

Domain routing
Domain routing

Note

You can also route to your ISP router using the IP address instead of the CNAME.

Note

Host means the subdomain name. For example, with a host of traefik, it will route the domain traefik.mydomain.topdomain to your ISP router.

Let's check if our DNS is correctly forwarding to our ISP router:

nslookup traefik.mydomain.topdomain
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
traefik.mydomain.topdomain       canonical name = ispsubdomain.ispdomain.topdomain.
Name:   ispsubdomain.ispdomain.topdomain
Address: XXX.XXX.XXX.XXX
Name:   ispsubdomain.ispdomain.topdomain
Address: XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX

Congratulations, you've learned how to set up your DNS provider to forward requests to your ISP router! ๐ŸŽ‰

๐Ÿ‹ Set Up Docker, Portainer, Traefik, and CrowdSec to Expose Your Services to the Internet Securely

Now, it's time to set up all the necessary tools to deploy, maintain, and expose our services/applications: Docker, Portainer, Traefik, and CrowdSec.

Docker, Portainer, Traefik, and CrowdSec
Docker, Portainer, Traefik, and CrowdSec

Let's first install Docker (official link, if necessary):

# Add Docker's official GPG key
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

You can verify the Docker installation using the following command:

sudo docker version
docker compose version
Client: Docker Engine - Community
 Version:           27.4.1
 API version:       1.47
 Go version:        go1.22.10
 Git commit:        b9d17ea
 Built:             Tue Dec 17 15:45:46 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          27.4.1
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.22.10
  Git commit:       c710b88
  Built:            Tue Dec 17 15:45:46 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.24
  GitCommit:        88bf19b2105c8b17560993bee28a01ddc2f97182
 runc:
  Version:          1.2.2
  GitCommit:        v1.2.2-0-g7cb3632
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
Docker Compose version v2.32.1

Then install the Portainer, Traefik, and CrowdSec stack:

  • The Docker Compose stack
docker-compose.yml
services:
  traefik:
    build:
      dockerfile_inline: |
        # https://hub.docker.com/_/traefik/tags
        FROM traefik:v3.3
        RUN mkdir -p /etc/traefik/ && \
          echo "http:" > /etc/traefik/dynamic.yml && \
          echo "  middlewares:" >> /etc/traefik/dynamic.yml && \
          echo "    crowdsec-bouncer-traefik-plugin:" >> /etc/traefik/dynamic.yml && \
          echo "      plugin:" >> /etc/traefik/dynamic.yml && \
          echo "        crowdsec-bouncer-traefik-plugin:" >> /etc/traefik/dynamic.yml && \
          echo "          enabled: true" >> /etc/traefik/dynamic.yml && \
          echo "          crowdsecAppsecEnabled: true" >> /etc/traefik/dynamic.yml && \
          echo "          crowdsecLapiKey: ${CROWDSEC_BOUNCER_KEY_TRAEFIK}" >> /etc/traefik/dynamic.yml
        ENTRYPOINT ["/entrypoint.sh"]
    command: >-
      --providers.docker=true
      --providers.docker.exposedByDefault=false
      --providers.docker.network=docker_default
      --providers.file.filename=/etc/traefik/dynamic.yml
      --entryPoints.http.address=:80
      --entryPoints.https.address=:443
      --entryPoints.stream-minecraft.address=:25565/tcp
      --api=true
      --ping=true
      --certificatesresolvers.letsencrypt.acme.email=ilovedata.jjia@gmail.com
      --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
      --certificatesresolvers.letsencrypt.acme.caserver=${TRAEFIK_TLS_CASERVER}
      --certificatesresolvers.letsencrypt.acme.tlschallenge=true
      --certificatesresolvers.letsencrypt.acme.httpchallenge=true
      --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http
      --accesslog=true
      --accesslog.addinternals=true
      --accesslog.filepath=/var/log/traefik/access.log
      --experimental.plugins.crowdsec-bouncer-traefik-plugin.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
      --experimental.plugins.crowdsec-bouncer-traefik-plugin.version=v1.4.1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - traefik_letsencrypt:/letsencrypt/
      - traefik_var_log_traefik:/var/log/traefik/
    ports:
      - "80:80"
      - "443:443"
      - "25565:25565"
    networks:
      - default
    labels:
      - traefik.enable=true
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.tls=${TRAEFIK_TLS}
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.tls.certresolver=letsencrypt
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.entryPoints=http,https
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.rule=Host(`${TRAEFIK_HOST}`)
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.service=api@internal
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.middlewares=crowdsec-bouncer-traefik-plugin@file,${COMPOSE_PROJECT_NAME}-traefik-basicauth
      - traefik.http.middlewares.${COMPOSE_PROJECT_NAME}-traefik-basicauth.basicauth.users=${TRAEFIK_USER}:${TRAEFIK_PASSWORD_HASHED}
    healthcheck:
      test: traefik healthcheck --ping
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  traefik_accesslog_logrotate:
    build:
      dockerfile_inline: |
        # https://hub.docker.com/_/alpine/tags
        FROM alpine:3.21.3
        RUN apk add --no-cache logrotate docker-cli
        RUN mkdir -p /etc/logrotate.d && \
          echo "/var/log/traefik/access.log {" > /etc/logrotate.d/traefik && \
          echo "  size ${TRAEFIK_ACCESSLOG_LOGROTATE_SIZE}" >> /etc/logrotate.d/traefik && \
          echo "  rotate ${TRAEFIK_ACCESSLOG_LOGROTATE_ROTATE}" >> /etc/logrotate.d/traefik && \
          echo "  maxage ${TRAEFIK_ACCESSLOG_LOGROTATE_MAXAGE}" >> /etc/logrotate.d/traefik && \
          echo "  compress" >> /etc/logrotate.d/traefik && \
          echo "  missingok" >> /etc/logrotate.d/traefik && \
          echo "  notifempty" >> /etc/logrotate.d/traefik && \
          echo "  postrotate" >> /etc/logrotate.d/traefik && \
          echo "    docker kill --signal=\"USR1\" \$(docker ps --filter \"name=^${COMPOSE_PROJECT_NAME}-traefik-1$\" --format \"{{.ID}}\")" >> /etc/logrotate.d/traefik && \
          echo "  endscript" >> /etc/logrotate.d/traefik && \
          echo "}" >> /etc/logrotate.d/traefik && \
          echo "${TRAEFIK_ACCESSLOG_LOGROTATE_CRON_EXPRESSION} logrotate -v /etc/logrotate.d/traefik" | crontab -
        ENTRYPOINT ["crond", "-f"]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - traefik_var_log_traefik:/var/log/traefik/
    depends_on:
      traefik:
        condition: service_healthy
    healthcheck:
      test: pgrep crond
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  crowdsec:
    build:
      dockerfile_inline: |
        # https://hub.docker.com/r/crowdsecurity/crowdsec/tags
        FROM crowdsecurity/crowdsec:v1.6.5 AS crowdsec_builder
        ENV DISABLE_ONLINE_API="true"
        ENV NO_HUB_UPGRADE="true"
        RUN ./docker_start.sh > /dev/null 2>&1 & \
          for i in {1..5}; do cscli hub update || sleep 10; done && \
          cscli hub upgrade && \
          cscli collections install \
            crowdsecurity/traefik \
            crowdsecurity/http-cve \
            crowdsecurity/base-http-scenarios \
            crowdsecurity/http-dos \
            crowdsecurity/sshd \
            crowdsecurity/linux \
            crowdsecurity/appsec-crs \
            crowdsecurity/appsec-generic-rules \
            crowdsecurity/appsec-virtual-patching \
          && \
          kill $(pgrep -f "crowdsec -c /etc/crowdsec/config.yaml") && \
          rm /etc/crowdsec/local_api_credentials.yaml
        WORKDIR /etc/crowdsec/acquis.d/
        RUN echo "filenames:" > ./traefik.yml && \
          echo "  - /var/log_traefik/access.log" >> ./traefik.yml && \
          echo "labels:" >> ./traefik.yml && \
          echo "  type: traefik" >> ./traefik.yml  && \
          echo "appsec_config: crowdsecurity/appsec-default" > ./appsec.yml && \
          echo "labels:" >> ./appsec.yml && \
          echo "  type: appsec" >> ./appsec.yml && \
          echo "listen_addr: 0.0.0.0:7422" >> ./appsec.yml && \
          echo "source: appsec" >> ./appsec.yml

        # https://hub.docker.com/r/crowdsecurity/crowdsec/tags
        FROM crowdsecurity/crowdsec:v1.6.5
        RUN mkdir -p /etc/crowdsec/acquis.d/
        COPY --from=crowdsec_builder /etc/crowdsec/ /etc/crowdsec/
        COPY --from=crowdsec_builder /etc/crowdsec/acquis.d/ /etc/crowdsec/acquis.d/
        ENTRYPOINT ["/bin/bash", "-c", "/docker_start.sh & for i in {1..5}; do cscli bouncers list > /dev/null 2>&1 && break || sleep 10; done && cscli bouncers remove TRAEFIK > /dev/null 2>&1 || true && cscli bouncers add TRAEFIK --key ${CROWDSEC_BOUNCER_KEY_TRAEFIK} > /dev/null 2>&1 && tail -f /dev/null"]
    environment:
      DISABLE_ONLINE_API: "true"
      NO_HUB_UPGRADE: "true"
    volumes:
      - crowdsec_var_lib_crowdsec_data:/var/lib/crowdsec/data/
      - traefik_var_log_traefik:/var/log_traefik/:ro
    networks:
      - default
    healthcheck:
      test: "cscli metrics"
      interval: 10s
      timeout: 5s
      retries: 5
    depends_on:
      traefik:
        condition: service_healthy
    restart: unless-stopped

  portainer:
    # https://hub.docker.com/r/portainer/portainer/tags
    image: portainer/portainer-ce:2.26.1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data/
    networks:
      - default
    labels:
      - traefik.enable=true
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-portainer.tls=${TRAEFIK_TLS}
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-portainer.tls.certresolver=letsencrypt
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-portainer.entryPoints=http,https
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-portainer.rule=Host(`${PORTAINER_HOST}`)
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-portainer.service=${COMPOSE_PROJECT_NAME}-portainer
      - traefik.http.services.${COMPOSE_PROJECT_NAME}-portainer.loadbalancer.server.port=9000
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-portainer.middlewares=crowdsec-bouncer-traefik-plugin@file
    restart: unless-stopped

volumes:
  traefik_letsencrypt:
  traefik_var_log_traefik:
  crowdsec_var_lib_crowdsec_data:
  portainer_data:

networks:
  default:
  • The command-line interface (CLI) command to run
sudo COMPOSE_PROJECT_NAME='docker' TRAEFIK_TLS=true TRAEFIK_TLS_CASERVER='https://acme-v02.api.letsencrypt.org/directory' TRAEFIK_HOST='traefik.mydomain.topdomain' TRAEFIK_USER='myuser' TRAEFIK_PASSWORD_HASHED='myhashedpassword' TRAEFIK_ACCESSLOG_LOGROTATE_SIZE='200M' TRAEFIK_ACCESSLOG_LOGROTATE_ROTATE='14' TRAEFIK_ACCESSLOG_LOGROTATE_MAXAGE='30' TRAEFIK_ACCESSLOG_LOGROTATE_CRON_EXPRESSION='0 0,12 * * *' CROWDSEC_BOUNCER_KEY_TRAEFIK=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c50) PORTAINER_HOST='portainer.mydomain.topdomain' docker compose -p docker -f docker-compose.yml up -d --remove-orphans --build && sudo docker image prune -f

Once completed, you can navigate to https://portainer.mydomain.topdomain. You should be prompted to create the administrator account. Once completed and logged in, the following screen should be presented to you:

Portainer ready!
Portainer ready!

Congratulations, you've successfully installed Portainer! You can now deploy, maintain, and monitor containerized applications through a Web UI.

You can also navigate to http://traefik.mydomain.topdomain. The login and password are the ones set by Traefik environment variables. Passwords must be hashed using MD5, SHA1, or BCrypt; to achieve that, you can use the Bcrypt Hash Generator online or, for a safer option, the htpasswd command from the apache2-utils package. Once logged in, you should see the following screen:

Traefik ready!
Treafik ready!

Congratulation! you've successfully installed Traefik! ๐Ÿค—

Warning

Beware, exposing Traefik and Portainer allows people to attempt to crack your login/password. If they succeed, they will have control over the deployed applications. So, if working from home is the only thing you do, it might be wise not to expose these two services and to access them only from your home network. To achieve this, you should expose extra ports for Traefik and Portainer and remove the corresponding Traefik labels that route to the services. The extra ports will allow you to access Traefik and Portainer via 192.168.1.X.

Lastly, about CrowdSecโ€”it's an internal service that acts as middleware between Traefik and the services. To access it, you will need to use basic Docker CLI and Bash CLI:

sudo docker exec -it $(sudo docker ps --filter name="docker-crowdsec-1" --format "{{.ID}}") /bin/bash

Then you will be prompted to the CrowdSec container:

myuser@myserver:~$ sudo docker exec -it $(sudo docker ps --filter name="docker-crowdsec-1" --format "{{.ID}}") /bin/bash
bcae0c3dccd6:/#

From there, you will be able to run several cscli commands:

  • The currently active decisions, including active IP bans
bcae0c3dccd6:/# cscli decisions list
โ•ญโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  ID โ”‚  Source  โ”‚   Scope:Value   โ”‚           Reason           โ”‚ Action โ”‚ Country โ”‚             AS            โ”‚ Events โ”‚ expiration โ”‚ Alert ID โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 336 โ”‚ crowdsec โ”‚ Ip:45.148.10.34 โ”‚ crowdsecurity/http-probing โ”‚ ban    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited โ”‚ 11     โ”‚ 3h35m36s   โ”‚ 342      โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
1 duplicated entries skipped
  • The alerts, including IP bans
60dcca3bcedc:/# cscli alerts list
โ•ญโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  ID โ”‚        value       โ”‚                 reason                โ”‚ country โ”‚                      as                     โ”‚ decisions โ”‚                created_at               โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 342 โ”‚ Ip:45.148.10.34    โ”‚ crowdsecurity/http-probing            โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 06:51:25.711705966 +0000 UTC โ”‚
โ”‚ 341 โ”‚ Ip:45.148.10.34    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 06:51:26.235906638 +0000 UTC โ”‚
โ”‚ 340 โ”‚ Ip:45.148.10.35    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 02:49:34.925254325 +0000 UTC โ”‚
โ”‚ 339 โ”‚ Ip:45.148.10.35    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 01:43:30.620059821 +0000 UTC โ”‚
โ”‚ 338 โ”‚ Ip:34.204.174.174  โ”‚ crowdsecurity/vpatch-git-config       โ”‚ US      โ”‚ 14618 AMAZON-AES                            โ”‚           โ”‚ 2025-03-07 01:18:21 +0000 UTC           โ”‚
โ”‚ 337 โ”‚ Ip:195.178.110.163 โ”‚ crowdsecurity/http-probing            โ”‚ BG      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 01:17:18.527430962 +0000 UTC โ”‚
โ”‚ 336 โ”‚ Ip:195.178.110.163 โ”‚ crowdsecurity/http-sensitive-files    โ”‚ BG      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 01:17:23.925647127 +0000 UTC โ”‚
โ”‚ 335 โ”‚ Ip:172.212.103.85  โ”‚ crowdsecurity/CVE-2022-41082          โ”‚ US      โ”‚ 8075 MICROSOFT-CORP-MSN-AS-BLOCK            โ”‚ ban:1     โ”‚ 2025-03-07 00:38:04.857829837 +0000 UTC โ”‚
โ”‚ 334 โ”‚ Ip:195.178.110.163 โ”‚ crowdsecurity/http-sensitive-files    โ”‚ BG      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-07 00:11:13.169639366 +0000 UTC โ”‚
โ”‚ 333 โ”‚ Ip:47.83.150.190   โ”‚ crowdsecurity/thinkphp-cve-2018-20062 โ”‚ HK      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 23:38:58.80656314 +0000 UTC  โ”‚
โ”‚ 332 โ”‚ Ip:47.83.150.190   โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ HK      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 23:38:57.743199532 +0000 UTC โ”‚
โ”‚ 331 โ”‚ Ip:47.83.150.190   โ”‚ crowdsecurity/http-probing            โ”‚ HK      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 23:37:50.77369468 +0000 UTC  โ”‚
โ”‚ 330 โ”‚ Ip:47.83.150.190   โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ HK      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 23:37:54.704898287 +0000 UTC โ”‚
โ”‚ 329 โ”‚ Ip:47.83.150.190   โ”‚ crowdsecurity/http-cve-2021-41773     โ”‚ HK      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 23:37:50.773618378 +0000 UTC โ”‚
โ”‚ 328 โ”‚ Ip:34.204.174.174  โ”‚ crowdsecurity/vpatch-git-config       โ”‚ US      โ”‚ 14618 AMAZON-AES                            โ”‚           โ”‚ 2025-03-06 22:01:32 +0000 UTC           โ”‚
โ”‚ 327 โ”‚ Ip:45.148.10.34    โ”‚ crowdsecurity/http-probing            โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 20:01:08.946235719 +0000 UTC โ”‚
โ”‚ 326 โ”‚ Ip:45.148.10.34    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 20:01:09.464984839 +0000 UTC โ”‚
โ”‚ 325 โ”‚ Ip:34.204.174.174  โ”‚ crowdsecurity/vpatch-git-config       โ”‚ US      โ”‚ 14618 AMAZON-AES                            โ”‚           โ”‚ 2025-03-06 17:41:43 +0000 UTC           โ”‚
โ”‚ 324 โ”‚ Ip:195.178.110.163 โ”‚ crowdsecurity/http-sensitive-files    โ”‚ BG      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 16:59:39.111415964 +0000 UTC โ”‚
โ”‚ 323 โ”‚ Ip:34.204.174.174  โ”‚ crowdsecurity/vpatch-git-config       โ”‚ US      โ”‚ 14618 AMAZON-AES                            โ”‚           โ”‚ 2025-03-06 16:58:00 +0000 UTC           โ”‚
โ”‚ 322 โ”‚ Ip:45.148.10.35    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 16:51:18.086862468 +0000 UTC โ”‚
โ”‚ 321 โ”‚ Ip:34.204.174.174  โ”‚ crowdsecurity/vpatch-git-config       โ”‚ US      โ”‚ 14618 AMAZON-AES                            โ”‚           โ”‚ 2025-03-06 16:26:44 +0000 UTC           โ”‚
โ”‚ 320 โ”‚ Ip:45.148.10.34    โ”‚ crowdsecurity/http-probing            โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 14:11:13.035448355 +0000 UTC โ”‚
โ”‚ 319 โ”‚ Ip:45.148.10.34    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 14:11:13.56899664 +0000 UTC  โ”‚
โ”‚ 318 โ”‚ Ip:8.222.172.249   โ”‚ crowdsecurity/thinkphp-cve-2018-20062 โ”‚ SG      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 13:45:57.230230638 +0000 UTC โ”‚
โ”‚ 317 โ”‚ Ip:8.222.172.249   โ”‚ crowdsecurity/http-probing            โ”‚ SG      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 13:45:34.989475157 +0000 UTC โ”‚
โ”‚ 316 โ”‚ Ip:8.222.172.249   โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ SG      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 13:45:37.820707681 +0000 UTC โ”‚
โ”‚ 315 โ”‚ Ip:8.222.172.249   โ”‚ crowdsecurity/http-cve-2021-41773     โ”‚ SG      โ”‚ 45102 Alibaba US Technology Co., Ltd.       โ”‚ ban:1     โ”‚ 2025-03-06 13:45:34.989421638 +0000 UTC โ”‚
โ”‚ 314 โ”‚ Ip:78.153.140.224  โ”‚ crowdsecurity/http-probing            โ”‚ GB      โ”‚ 202306 Hostglobal.plus Ltd                  โ”‚ ban:1     โ”‚ 2025-03-06 13:26:10.789683174 +0000 UTC โ”‚
โ”‚ 313 โ”‚ Ip:78.153.140.224  โ”‚ crowdsecurity/http-sensitive-files    โ”‚ GB      โ”‚ 202306 Hostglobal.plus Ltd                  โ”‚ ban:1     โ”‚ 2025-03-06 13:26:10.789440914 +0000 UTC โ”‚
โ”‚ 312 โ”‚ Ip:78.153.140.179  โ”‚ crowdsecurity/http-probing            โ”‚ GB      โ”‚ 202306 Hostglobal.plus Ltd                  โ”‚ ban:1     โ”‚ 2025-03-06 11:06:07.846945115 +0000 UTC โ”‚
โ”‚ 311 โ”‚ Ip:78.153.140.179  โ”‚ crowdsecurity/http-sensitive-files    โ”‚ GB      โ”‚ 202306 Hostglobal.plus Ltd                  โ”‚ ban:1     โ”‚ 2025-03-06 11:06:07.846818179 +0000 UTC โ”‚
โ”‚ 310 โ”‚ Ip:192.168.1.254   โ”‚ crowdsecurity/vpatch-env-access       โ”‚         โ”‚                                             โ”‚           โ”‚ 2025-03-06 06:46:48 +0000 UTC           โ”‚
โ”‚ 309 โ”‚ Ip:45.148.10.35    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 04:54:44.045808147 +0000 UTC โ”‚
โ”‚ 308 โ”‚ Ip:45.148.10.90    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-06 04:39:40.9902859 +0000 UTC   โ”‚
โ”‚ 307 โ”‚ Ip:31.210.213.230  โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ RU      โ”‚ 43727 Jsc Kvant-telekom                     โ”‚ ban:1     โ”‚ 2025-03-06 03:45:33.005141454 +0000 UTC โ”‚
โ”‚ 306 โ”‚ Ip:31.210.213.230  โ”‚ crowdsecurity/http-cve-2021-41773     โ”‚ RU      โ”‚ 43727 Jsc Kvant-telekom                     โ”‚ ban:1     โ”‚ 2025-03-06 03:45:16.048775589 +0000 UTC โ”‚
โ”‚ 305 โ”‚ Ip:8.134.196.56    โ”‚ crowdsecurity/thinkphp-cve-2018-20062 โ”‚ CN      โ”‚ 37963 Hangzhou Alibaba Advertising Co.,Ltd. โ”‚ ban:1     โ”‚ 2025-03-05 15:33:13.404183934 +0000 UTC โ”‚
โ”‚ 304 โ”‚ Ip:8.134.196.56    โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ CN      โ”‚ 37963 Hangzhou Alibaba Advertising Co.,Ltd. โ”‚ ban:1     โ”‚ 2025-03-05 15:33:12.786613671 +0000 UTC โ”‚
โ”‚ 303 โ”‚ Ip:8.134.196.56    โ”‚ crowdsecurity/http-probing            โ”‚ CN      โ”‚ 37963 Hangzhou Alibaba Advertising Co.,Ltd. โ”‚ ban:1     โ”‚ 2025-03-05 15:31:51.222022344 +0000 UTC โ”‚
โ”‚ 302 โ”‚ Ip:8.134.196.56    โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ CN      โ”‚ 37963 Hangzhou Alibaba Advertising Co.,Ltd. โ”‚ ban:1     โ”‚ 2025-03-05 15:32:10.366378223 +0000 UTC โ”‚
โ”‚ 301 โ”‚ Ip:8.134.196.56    โ”‚ crowdsecurity/http-cve-2021-41773     โ”‚ CN      โ”‚ 37963 Hangzhou Alibaba Advertising Co.,Ltd. โ”‚ ban:1     โ”‚ 2025-03-05 15:31:51.221935472 +0000 UTC โ”‚
โ”‚ 300 โ”‚ Ip:45.148.10.35    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-05 13:57:15.586178679 +0000 UTC โ”‚
โ”‚ 299 โ”‚ Ip:45.148.10.35    โ”‚ crowdsecurity/http-sensitive-files    โ”‚ NL      โ”‚ 48090 Techoff Srv Limited                   โ”‚ ban:1     โ”‚ 2025-03-05 08:31:15.415798442 +0000 UTC โ”‚
โ”‚ 298 โ”‚ Ip:141.147.6.15    โ”‚ crowdsecurity/thinkphp-cve-2018-20062 โ”‚ DE      โ”‚ 31898 ORACLE-BMC-31898                      โ”‚ ban:1     โ”‚ 2025-03-05 07:27:20.692453456 +0000 UTC โ”‚
โ”‚ 297 โ”‚ Ip:141.147.6.15    โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ DE      โ”‚ 31898 ORACLE-BMC-31898                      โ”‚ ban:1     โ”‚ 2025-03-05 07:26:19.227214095 +0000 UTC โ”‚
โ”‚ 296 โ”‚ Ip:141.147.6.15    โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ DE      โ”‚ 31898 ORACLE-BMC-31898                      โ”‚ ban:1     โ”‚ 2025-03-05 07:25:17.170348689 +0000 UTC โ”‚
โ”‚ 295 โ”‚ Ip:141.147.6.15    โ”‚ crowdsecurity/http-probing            โ”‚ DE      โ”‚ 31898 ORACLE-BMC-31898                      โ”‚ ban:1     โ”‚ 2025-03-05 07:24:02.458370769 +0000 UTC โ”‚
โ”‚ 294 โ”‚ Ip:141.147.6.15    โ”‚ crowdsecurity/CVE-2017-9841           โ”‚ DE      โ”‚ 31898 ORACLE-BMC-31898                      โ”‚ ban:1     โ”‚ 2025-03-05 07:24:15.607530994 +0000 UTC โ”‚
โ”‚ 293 โ”‚ Ip:141.147.6.15    โ”‚ crowdsecurity/http-cve-2021-41773     โ”‚ DE      โ”‚ 31898 ORACLE-BMC-31898                      โ”‚ ban:1     โ”‚ 2025-03-05 07:24:02.458262457 +0000 UTC โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Congratulations! You've successfully installed CrowdSec! ๐Ÿค— It also shows how scary the Internet can be ๐Ÿ˜ฃ.

๐ŸŽฏ Example Use Case: Open WebUI and Ollama Setup

This section aims to demonstrate how to properly install a stack of containers for a given application and expose it to the Internet. LLMs are hot topics nowadays, so let's use the Open WebUI and Ollama stack as an example.

Open WebUI and Ollama Setup
Open WebUI and Ollama Setup

Let's start by running the LLM container stack on our server. Here are the steps:

  • Navigate to the Portainer home page.
  • Select the Local environment, go to Stacks, and click on Add stack.
  • Input a Name for the stack, for example, llm.
  • Select Web editor and paste the following Docker Compose file.
services:
  openwebui:
    # https://github.com/open-webui/open-webui
    image: ghcr.io/open-webui/open-webui:v0.5.17
    environment:
      OLLAMA_BASE_URL: http://ollama:11434
    volumes:
      - openwebui_app_backend_data:/app/backend/data
    networks:
      - default
      - docker_default
    labels:
      - traefik.enable=true
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-openwebui.tls=${TLS}
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-openwebui.tls.certresolver=letsencrypt
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-openwebui.entryPoints=http,https
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-openwebui.rule=Host(`${OPENWEBUI_HOST}`)
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-openwebui.service=${COMPOSE_PROJECT_NAME}-openwebui
      - traefik.http.services.${COMPOSE_PROJECT_NAME}-openwebui.loadbalancer.server.port=8080
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}-openwebui.middlewares=crowdsec-bouncer-traefik-plugin@file
    healthcheck:
      test: "curl -f http://localhost:8080"
      interval: 10s
      timeout: 5s
      retries: 5
    depends_on:
      ollama:
        condition: service_healthy
    restart: unless-stopped

  ollama:
    # https://hub.docker.com/r/ollama/ollama/tags
    image: ollama/ollama:0.5.12
    volumes:
      - ollama_root_ollama:/root/.ollama
    networks:
      - default
    healthcheck:
      test: "ollama --version && ollama ps || exit 1" # https://github.com/ollama/ollama/issues/1378#issuecomment-2436650823
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  openwebui_app_backend_data:
  ollama_root_ollama:

networks:
  default:
  docker_default:
    external: true
  • In the Environment variables section, add the following environment variables:
Environment variable Value
TLS true
OPENWEBUI_HOST llm.mydomain.topdomain

You should end up with a configuration that looks like this:

Configuring the Open WebUI and Ollama stack
Configuring the Open WebUI and Ollama stack

Make sure your DNS provider has llm.mydomain.topdomain routed to your ISP router, just like Portainer and Traefik were set up in the previous section. After that, you should be able to navigate to 'llm.mydomain.topdomain', and by configuring your admin account (mandatory on first page load), you should end up on the following page:

Open WebUI
Open WebUI

Let's now download the latest Phi-4 with its 14 billion parameters, rumored to rival OpenAI's GPT-4o mini, which everyone is talking about. You can also try other LLMs instead; models are available in the Ollama Models section.

The Phi-4 model
The Phi-4 model
Downloading the Phi-4 model
Downloading the Phi-4 model

Here is an example result of prompting:

An example of a prompt result
An example of a prompt result

The latest Phi is running on our server, though it's currently best suited for background tasks due to its slower performance. ๐ŸŽ‰ Congratulations! You've successfully self-hosted your own private LLM platform! ๐Ÿš€

๐Ÿ”ฎ What's next?

My thoughts are that self-hosting is ideal for ephemeral computation or data. It's great because, as we can see, itโ€™s more than doable, and when compared to cloud prices, it's less costly. However, running a full business on a self-hosted lab isn't ideal. My home isnโ€™t "secure". So, if user data is critical to the application, I would rent persistent services like RDS, S3, etc. But for all the application logic and computation, since it's ephemeral, I would go the self-hosting route.

Regarding the technical/hardware side, I might buy another mini PC to set up a K8S cluster. Alternatively, Iโ€™m considering the new Intel Arc Battlemage GPUs that just got released. The GMKTec AMD Ryzen 7 8845HS Mini PCโ€”NucBox K8 Plus I have even has an Oculink port, hรฉhรฉ! Or maybe Iโ€™ll go for both optionsโ€”imagine a K8S cluster with GPU enabled on each node ๐Ÿคค. Weโ€™ll see!

I try to write monthly on the LovinData Blog and on Medium, and like to give back the knowledge I've learned. So don't hesitate to reach out; I'm always available to chat about nerdy stuff ๐Ÿค—! Here are my socials: LinkedIn, Twitter and Reddit. Otherwise, let's learn together in the next story ๐Ÿซก! Bye โค๏ธ.