Posts

Running a Bottle app in Docker

Sep 14, 2025 | 4 minutes to read

I’ve been self-hosting a number of apps in Docker for my own personal use for some time. Things like Immich and Jellyfin and AudioBookshelf are easy to set up and require very little maintenance. This is part of my de-googling process and I’ve been super happy with those apps. This week I realized I don’t have a tool like Postman for API testing, so I assigned myself some homework: Create a new minimal app I can use to test APIs, and make it available on my litle NUC 10 home server. Here are the steps I followed to do all of that. I think I’ve spent something like 2.5 hours total, so this was really worth the effort, IMO.

  • Fire up the DuckDuckGO AI chatbot and ask it for advice on how to create this app.

  • Chat back and forth for a while until I settle on this architecture:

    • Python 3 on the server, using Bottle to make a nice lightweight web service.
    • Add the Python Requests module to make routing easier (though as you’ll see, there’s really not a lot of that even)
  • Follow the AI bot’s instructions to create these two files in “src” folder:

    • a server.py file (the server side app)
    • and an index.html file (the web interface) which includes the CSS, HTML and JS all in one file, because that’s all only like 350 lines.
  • That’s it, that’s the whole app!

  • Test that locally on 127.0.0.1 and it works.

  • More back and forth until I get the app doing basic HTTP/S calls and displaying their responses on the same page, via some very simple JavaScript.

  • Add in bootstrap and adjust the CSS to make it look nice, and the app is done (for now).

  • Commit the whole project to my local ForgeJo git server (another self-hosted app, because I don’t cotton to any Microsoft BS either) and that’s Phase 1.

Now I can run the app on my server with something like, “python3 server.py” and boom, I can access that from my PC and my Phone and it looks great!

the app with a sample response

Sweet!!!

Next, I wanted to move that app from running directly on my PC, to running in a Docker container, like all of the other apps on my server. That turns out to be pretty simple as well.

  • Create a DockerFile which is what Docker needs to be able to “build” the app into a Container:
# syntax=docker/dockerfile:1

FROM python:3.13.7-trixie
WORKDIR /app
COPY . .
RUN apt-get update
RUN pip install bottle
RUN pip install requests
ENTRYPOINT /bin/bash -c "python3 src/server.py"
EXPOSE 8111
  • That tells Docker to:

    • Start from an image containing a recent Debian version (“Trixie” aka Debian v13), and Python 3.13.
    • Run that OS
    • Do an apt update to make sure its app repo DB is up to date.
    • install Bottle (my chosen web server) via the pip command.
    • do the same for Requests
    • execute the script via the python3 engine.
    • make sure Docker knows I want the app running on my server’s Port 8111 (which is baked into the server.py as well)
  • Docker needs to build that into a Container so this is the command to make that happen:

docker build -t mundane-api .
  • Then we run the app with this command:
docker run -d -p 0.0.0.0:8111:8111 mundane-api
  • “-d” tells Docker to run the app “detached” or in the background. The alternative would take over my terminal window, which is good for debugging but a pain once you get the app running well.
  • “-p” tells Docker to “publish” the app, or IOW to make it available on the server.
  • I used “0.0.0.0:8111” to tell Docker I want the app to run on all local networks and to listen on port 8111.
  • Voila! Now I can access my little Mundane API Test app via my server on its Port 8111.

My last step was just converting that Docker “run” command into a Docker Compose file, so I can now maintain and monitor the Docker app from my local Dockge app. (Dockge is great once you are running more than a couple of apps in Docker. I should do a separate post about all of its great features soon…)

  • In Dockge, I pasted the “run” command and it converts that into a docker-compose.yml file:
services:
  mundane-api:
    ports:
      - 0.0.0.0:8111:8111
    image: mundane-api
networks: {}

I save all of these files into a new folder in the same place I keep all of my Docker “stacks” and boom - Docgke is montoring the app for me now.

dockge watching my app

And I’m done! I will work on updates for the app next but this was really fun to learn and get running and really, not tooooo difficult. It helped that my little API testing app didn’t have any storage to worry about and just has that one main page for the UI.

Till next time… :)


You can leave a comment on this post here.