steve 523a9e22c2 Merge pull request #28 from tmdinosaurcenter/dependabot/pip/email-validator-gte-2.3.0
chore(deps): update email-validator requirement from >=2.0 to >=2.3.0
2026-04-27 08:45:09 -06:00
2025-04-02 19:47:44 -06:00

Museum Visitor Guestbook

A simple Flask-based guestbook application designed for an internal museum kiosk. This application collects visitor details (first name(s), last name, email, location, and an optional comment) while dynamically revealing the comment field only after the required fields are filled out with at least 3 characters each. The app includes basic input validation, profanity filtering using a custom banned words list, and logging for easier troubleshooting. It uses SQLite for data storage and is containerized with Docker and Docker Compose for easy deployment on an intranet.

Museum Visitor Guestbook Screenshot

Features

  • Dynamic Form Behavior: The comment field is hidden by default and only revealed when the first name, last name, and location fields each contain at least 3 characters.
  • Input Validation: Ensures required fields (first name, last name, and location) are filled and validates email format (if provided). Uses a profanity filter loaded from en.txt to prevent inappropriate language in comments.
  • Logging: Logs key events and validation errors for debugging and monitoring.
  • SQLite Database: Stores guest entries locally, with persistence ensured by mounting a Docker volume.
  • Containerized Deployment: Uses Docker and Docker Compose for a production-ready environment with Gunicorn as the WSGI server.
  • Configurable Template: The applications title and logo can be dynamically configured via environment variables without rebuilding the image.

Getting Started

Prerequisites

  • Docker
  • Docker Compose
  • Optionally, Portainer for GUI-based container management

Running the Application

Before proceeding, youll need to have the example configuration files. These files—example.docker-compose.yml and example.env—are included in the repository. You can download them by cloning the entire repository:

git clone https://github.com/tmdinosaurcenter/kiosk-guestbook.git
cd kiosk-guestbook

If you dont wish to clone the entire repo, you can also download the two files individually from GitHub. Once you have them, follow the steps below.

Method 1: Using Docker on the CLI

  1. Copy Example Files: From the project root, copy the example files:
cp example.docker-compose.yml docker-compose.yml
cp example.env .env
  1. Edit the .env File (Optional)

Modify .env to customize settings such as SITE_TITLE, LOGO_URL, PORT, etc.

  1. Start the Application

Run the following command to pull (or use) the pre-built image and start the container:

docker-compose up -d

This command starts the container in detached mode, mounts the persistent volume for the SQLite database, and uses your environment variable settings.

  1. Access the Application

Open your browser and navigate to http://<your-server-ip>:8000 (or the port specified in your .env file).

Method 2: Running in Portainer

  1. Copy Example Files
cp example.docker-compose.yml docker-compose.yml
cp example.env stack.env

Note: Portainer expects the environment file to be named stack.env rather than .env

  1. Edit docker-compose.yml In the docker-compose.yml file, update the environment file reference from .env to stack.env

  2. Deploy via Portainer

    • Log in to Portainer and navigate to the "Stacks" section.
    • Create a new stack and upload or paste your modified docker-compose.yml along with the stack.env file.
    • Deploy the stack. Portainer will use stack.env for the environment variables.
  3. Access the Application: Once deployed, open your browser and navigate to http://:8000 (or your specified port) to view the application.

Logging and Monitoring

  • The application uses Python's built-in logging module.
  • Key events, such as database initialization, form submissions, and validation errors, are logged.
  • View logs with:

docker-compose logs -f

Admin Interface

A password-protected admin panel is available at /admin. It displays all guest entries in a paginated table and allows individual entries to be deleted. Authentication uses session cookies with an HTML login form — logging out fully invalidates the session so credentials are never cached by the browser.

Access requires ADMIN_USER, ADMIN_PASSWORD, and SECRET_KEY to be set in your .env. If either of the admin credentials are missing the interface returns 503. If SECRET_KEY is not set a default development key is used, which is insecure in production — always set your own.

Generating a SECRET_KEY

Use Python to generate a cryptographically random key:

python3 -c "import secrets; print(secrets.token_hex(32))"

Paste the output as the value for SECRET_KEY in your .env.

User Roles

The bootstrap superadmin (set via ADMIN_USER / ADMIN_PASSWORD) can manage additional users at /admin/users:

Role View entries Delete entries Manage users
superadmin
admin
viewer

API Access

Access the API endpoint to export guest entries by navigating to:

http://your-server-ip:8000/api/guests

Set the API_KEY variable in your .env and pass it in requests as the X-API-Key header. This endpoint can be integrated with on-prem automation tools like n8n.

Upgrading

When upgrading from a previous version, compare your .env against example.env to check for newly required variables.

As of v2.1.0, the following variables are required for the admin interface:

ADMIN_USER=admin
ADMIN_PASSWORD=changeme

As of v2.3.0, a SECRET_KEY is also required for session-based authentication:

SECRET_KEY=your-random-secret-key-here

Generate one with:

python3 -c "import secrets; print(secrets.token_hex(32))"

Replace all placeholder values with your own before deploying.

Additional Notes

  • Intranet-Only Deployment This application is designed for internal use only and is not exposed to the public internet.

  • Database Persistence The SQLite database is stored in a Docker volume (guestbook_data), ensuring that data persists even if containers are rebuilt.

  • Production Considerations The app runs with Gunicorn as a production-ready WSGI server. Adjust worker counts and resource limits as needed based on your servers specifications.

License

This project is licensed under the MIT License.

S
Description
No description provided
Readme MIT 557 KiB
Languages
Python 46.3%
HTML 33.9%
JavaScript 16.5%
Dockerfile 2.2%
Shell 1.1%