Skip to content
Table of contents

another-install-script: A menu for homelab installation

another-install-script is a shell entry point for choosing system setup and container installations. Its structure separates the menu from the service definitions so that adding a service does not require putting every command in setup.sh.

Configuration and automation Docker
  • Updated
  • 3
  • Shell · 93.8%
  • GPL-3.0
Documented components
2Explore modules
Source documents
2Read the instructions
Repository languagesShell 93.8%3

Shares calculated from GitHub Linguist bytes.

Shell93.8%
93.8%129,426 bytes
Dockerfile3.12%
3.12%4,311 bytes
Python3.07%
3.07%4,242 bytes
Language%Bytes
Shell93.8%129,426
Dockerfile3.12%4,311
Python3.07%4,242

1. Overview

1.1. Why it exists

Interactive TUI shell installer automating deployment of Docker containers and server configurations.

1.2. Best fit

One-command server provisioning for homelabs and development VPS.

2. Use cases

Whiptail menu in Bash that installs base tools and Docker Compose services on a personal Ubuntu server.

Use-case diagram for another-install-script: Install base server tools; Deploy selected containers; Open ports for containers; Remove installed containers; Uninstall the setupanother-install-scriptInstall base server toolsDeploy selected containersOpen ports for containersRemove installed containersUninstall the setupServer admin«system»Docker Engine«system»UFW firewall
People on the left, external systems on the right; each oval is a use case backed by the files cited below.
Install base server tools
Server admin

The Installation entry of main_setup_menu (src/menu.sh) shows a checklist: basic packages, Docker, Cockpit, LXDE, Ansible, Dokku, Vagrant and more; src/install.sh runs the selected items.

Deploy selected containers
Server adminDocker Engine

Add Container lists the folders under containers/; each <name>.sh runs docker-compose up -d on the docker-compose.yml next to it (for example containers/gogs/).

Open ports for containers
Server adminUFW firewall

After containers are added, manage_firewall_ports_allow_list in src/firewall.sh reads their ports from config.yml and allows them; with system.firewall set to yes, ufw denies other incoming traffic but keeps SSH, 2222, HTTP and HTTPS.

Remove installed containers
Server adminDocker Engine

remove_container_menu shows the installed containers; each remove_docker_<name> function runs docker-compose down on that service.

Uninstall the setup
Server adminDocker EngineUFW firewall

The Uninstall entry runs uninstall.sh, which loads the src/ modules to undo the setup. The Backup entry currently calls the same script; the backup helpers in src/backup.sh are not wired to the menu.

2.1. Scenario: Provision a new VPS with a few self-hosted services

  1. Clone the repository and run sudo bash setup.sh; it opens main_setup_menu because bashmenu is yes in config.yml.
  2. Choose Installation and keep basic and docker checked; selecting docker opens the container list next.
  3. Tick services such as gogs and bookstack; each script runs docker-compose up -d.
  4. Let the firewall step allow the ports listed in config.yml and enable ufw.
  5. Later, use Remove Container to stop a service with docker-compose down.

Files readREADME.mdsetup.shconfig.ymlsrc/menu.shsrc/install.shsrc/containers.shsrc/firewall.shsrc/backup.shuninstall.shcontainers/gogs/gogs.sh

3. Getting started

These commands come from the repository documentation. They were not run during this review.

README.md · How to install
git clone https://github.com/antoinebou13/another-install-script.git
cd another-install-script
sudo bash setup.sh
README.md · How to run coverage and tests
cd tests
bash test.sh
README.md · How to run coverage and tests
cd tests
bash coverage.sh
README.md · How to generate the documentation
git submodule update --init --recursive
git pull --recurse-submodules
git submodule update --remote
cd docs/generator
chmod +x generate_docs.sh
bash generate_docs.sh ../docs.md
README.md · Project Structure
+-- docs
|   +-- vendor
|       +-- ...
|   +-- docs.md
|   +-- generate_docs.md
|   +-- ...
+-- containers
|   +-- $container_name
|   |   |   +-- docker-compose.yml
|   |   |   +-- $container_name.sh
|   |   |   +-- ...
+-- src

4. Repository references

Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.

Prerequisites and first run

4.1. How to install

README.md

Currently, the script has been tested only on Ubuntu 18.04. You can install it by:
Read the full instructions ↗

4.2. List of other installed program that you can chose to install

README.md

This script also offers optional installation of several other programs including git, python3, docker, docker-compose, snapd, curl, vim, and more.

  • build-essential
  • git
  • python3
  • python3-pip
  • wireless-tools
  • wpasupplicant
  • default-jre
  • jq
  • net-tools
  • firefox
  • lxde
  • vim
  • snapd
  • nmap
  • wget
  • curl
  • mlocate
  • cmake
  • docker
  • docker-compose
  • dry
  • ctop
  • emojify
  • dokku
  • lynk
Read the full instructions ↗
Development and contributions

4.3. How to run coverage and tests

README.md

Manuel Testing For running the bats tests For running and generate with kcov
Read the full instructions ↗

4.4. Contributing

README.md

All pull request and suggestion is highly appreciated and encourage Go to Contributing
Read the full instructions ↗

4.5. Contributing (CONTRIBUTING.md)

.github/CONTRIBUTING.md

When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. Please note we have a code of conduct, please follow it in all your interactions with the project.
Read the full instructions ↗
Source documentation

2 documents read from 2 candidates.

5. Features and components 2

Entry point and menus
setup.sh sources src/menu.sh and calls main_setup_menu. The root script handles arguments, while the sourced module controls navigation. config.yml sits beside the launcher as the project’s configuration surface.
Service definitions
The containers directory holds installation material for individual services. Keeping that material outside the menu makes the repository easier to extend, but each installation still changes the host or its Docker environment.

6. Architecture

Expand a component to follow its connections, or explore the full diagram.

System components Context
Mermaid Interactive diagram

System overview of the components and connections verified in the repository.

Static architecture view for another-install-script
Static preview. The interactive diagram replaces it after Mermaid loads.
flowchart LR

subgraph group_cli["CLI management"]
  node_menu["CLI menu<br/>[menu.sh]"]
  node_router["Command router<br/>[router.sh]"]
  node_utilities["Shell utilities<br/>[utils.sh]"]
end

subgraph group_services["Service deployment"]
  node_service_catalog["Service catalog"]
  node_service_scripts["Service installers"]
  node_compose_definitions["Compose definitions"]
  node_container_manager["Container manager<br/>[containers.sh]"]
  node_docker_manager["Docker operations<br/>[docker.sh]"]
end

subgraph group_system["Server management"]
  node_program_installer["Program installer<br/>[install.sh]"]
  node_other_tools["Other programs<br/>[other.sh]"]
  node_firewall["Firewall management<br/>[firewall.sh]"]
  node_backup["Backup management<br/>[backup.sh]"]
end

subgraph group_config["Configuration utilities"]
  node_config_loader["Config management<br/>[config.sh]"]
  node_list_generator["Service list generator<br/>[containers_list.py]"]
  node_proxy_generator["Proxy config generator"]
  node_settings["System settings<br/>[config.yml]"]
end

node_user(("Server administrator"))
node_docker["Docker"]

node_user -->|"chooses services"| node_menu
node_menu -.->|"routes commands"| node_router
node_router -.->|"manages containers"| node_container_manager
node_container_manager -.->|"uses Docker operations"| node_docker_manager
node_docker_manager -.->|"operates"| node_docker
node_service_scripts -.->|"uses definitions"| node_compose_definitions
node_container_manager -.->|"installs services"| node_service_catalog
node_user -->|"requests programs"| node_program_installer
node_program_installer -.->|"offers programs"| node_other_tools
node_list_generator -->|"reads settings"| node_settings
node_proxy_generator -->|"reads settings"| node_settings


class node_menu,node_router,node_utilities toneBlue
class node_service_catalog,node_service_scripts,node_compose_definitions,node_container_manager,node_docker_manager toneAmber
class node_program_installer,node_other_tools,node_firewall,node_backup,node_user toneMint
class node_config_loader,node_list_generator,node_proxy_generator,node_settings toneRose
class node_docker toneIndigo

A command-line manager for installing and configuring self-hosted services. The documented flow starts in the menu, selects a service or program, and delegates container, proxy and configuration work to shell and Python utilities.

Components
18
Connections
11
Evidence-backed links
4/11
Text version of the diagram
  • setup.sh → src/menu.sh
  • src/menu.sh → Configuration and selection
  • Configuration and selection → Container installation
Follow one path through the code

Start with the main_setup_menu call, then inspect the selected service under containers before executing it. The menu is a dispatcher; the selected service determines the actual side effects.

7. Technical dossier

Built from the source at commit 6e1e193 (209 files). Each item comes from a pattern match in the code, so open the linked file before relying on it.

7.1. Layers and modules

Folders are sorted into layers by name, from the user interface down to data access. Because the sorting uses names only, the diagram says nothing about calls between layers.

Mermaid Layered view
flowchart TB
  subgraph L_interface["Entry points and API"]
    direction TB
    interface_0["containers/code-server<br/>1 file"]
  end
  subgraph L_application["Application services"]
    direction TB
    application_0["docs/scripts<br/>1 file"]
  end
  subgraph L_domain["Domain and business rules"]
    direction TB
    domain_0["containers/cloudtorrent<br/>1 file"]
  end
  subgraph L_infrastructure["Data and infrastructure"]
    direction TB
    infrastructure_0["containers/htpcdownloadbox<br/>1 file"]
  end
  subgraph L_core["Core source"]
    direction TB
    core_0["src<br/>12 files"]
    core_1["(root)<br/>3 files"]
    core_2["containers/n8n<br/>2 files"]
    core_3["containers/airsonic<br/>1 file"]
    core_more["+87"]
  end
  subgraph L_tests["Tests"]
    direction TB
    tests_0["tests<br/>3 files"]
  end
  subgraph L_hosting["Build, CI and hosting"]
    direction TB
    hosting_0["containers<br/>95 files"]
    hosting_1[".github<br/>7 files"]
  end
  L_interface ~~~ L_application
  L_application ~~~ L_domain
  L_domain ~~~ L_infrastructure
  L_infrastructure ~~~ L_core
  L_core ~~~ L_tests
  L_core ~~~ L_hosting
Modules and their main layer
ModuleLayerFilesTypesExtensions
srcCore source122.sh .py
(root)Core source30.sh
containers/n8nCore source20.sh
containers/airsonicCore source10.sh
containers/ansiblesemaphoreCore source10.sh
containers/bitwardenCore source10.sh
containers/bookstackCore source10.sh
containers/calibreCore source10.sh
containers/cheveretoCore source10.sh
containers/cloudtorrentDomain and business rules10.sh
containers/code-serverEntry points and API10.sh
containers/couchpotatoCore source10.sh
containers/cyberchefCore source10.sh
containers/dailynotesCore source10.sh

81 smaller modules are not shown.

7.2. C4 model

From system context to code declarations. Each level reflects the available source evidence.

UML 1 · System context
1 · System context

The widest C4 view: who uses the project and which outside systems and data stores it relies on. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
System(SYS, "another-install-script", "another-install-script is a shell entry point for choosing system set…")
@enduml
UML 2 · Containers
2 · Containers

One level closer: the parts that run separately inside the project, their main language and how calls flow between them. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Container>
LAYOUT_LEFT_RIGHT()
System_Boundary(SYS, "another-install-script") {
  Container(C0, "airsonic", "Docker")
  Container(C1, "ansible-semaphore_db", "Docker")
  Container(C2, "bookstack", "Docker")
  Container(C3, "bookstack_db", "Docker")
  Container(C4, "calibre", "Docker")
  Container(C5, "chevereto_db", "Docker")
  Container(C6, "chevereto", "Docker")
  Container(C7, "code-server", "Docker")
}
@enduml
UML 3 · Components and layers
3 · Components and layers

Modules grouped by source-layer classification. Boundaries show organization, not runtime isolation or call relationships. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "another-install-script") {
Boundary(L0, "Entry points and API", "layer") {
Component(M0_0, "containers/code-server", ".sh", "1 files")
}
Boundary(L1, "Application services", "layer") {
Component(M1_0, "docs/scripts", ".sh, .bash", "3 files")
}
Boundary(L2, "Domain and business rules", "layer") {
Component(M2_0, "containers/cloudtorrent", ".sh", "1 files")
}
Boundary(L3, "Data and infrastructure", "layer") {
Component(M3_0, "containers/htpcdownloadbox", ".sh", "1 files")
}
Boundary(L4, "Core source", "layer") {
Component(M4_0, "src", ".sh, Python", "12 files")
Component(M4_1, "(root)", ".sh", "3 files")
Component(M4_2, "containers/n8n", ".sh", "2 files")
Component(M4_3, "containers/airsonic", ".sh", "1 files")
Component(M4_4, "containers/ansiblesemaphore", ".sh", "1 files")
Component(M4_5, "containers/bitwarden", ".sh", "1 files")
Component(M4_6, "containers/bookstack", ".sh", "1 files")
Component(M4_7, "containers/calibre", ".sh", "1 files")
Component(M4_more, "+83 modules", "", "")
}
Boundary(L5, "Tests", "layer") {
Component(M5_0, "docs", ".sh", "19 files")
Component(M5_1, "tests", ".sh", "3 files")
}
Boundary(L6, "Build, CI and hosting", "layer") {
Component(M6_0, "containers", ".yml, Dockerfile", "95 files")
Component(M6_1, ".github", ".md, CODEOWNERS", "7 files")
Component(M6_2, "docs", ".yaml, Makefile", "2 files")
}
}
@enduml
UML 4 · Code
4 · Code

Selected declarations, fields and methods grouped by source file. No inheritance or call edges are inferred. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "another-install-script" {
package "src/containers_list.py" as F0 {
class "GeneratorAIS" as T0_0 {
  read_yml()
  generate_containers_list()
  write_containers_list_text()
}
}
package "src/nginx_reverse_proxy.py" as F1 {
class "ReverseProxy" as T1_0 {
  read_yml()
  generate_nginx_conf()
  generate_server_block()
}
}
}
@enduml

7.3. Data flow

The calls from the GitDiagram graph, in the order you meet them from the entry points. GitDiagram generates the graph with AI; the file paths it cites were checked against the repository tree.

Mermaid Sequence diagram
sequenceDiagram
  autonumber
  participant P0 as Service installers
  participant P1 as Compose definitions
  participant P2 as Service list generator
  participant P3 as System settings
  participant P4 as Proxy config generator
  participant P5 as Server administrator
  participant P6 as CLI menu
  participant P7 as Program installer
  participant P8 as Command router
  participant P9 as Other programs
  participant P10 as Container manager
  participant P11 as Docker operations
  participant P12 as Service catalog
  participant P13 as Docker
  P0--)P1: uses definitions
  P2->>P3: reads settings
  P4->>P3: reads settings
  P5->>P6: chooses services
  P5->>P7: requests programs
  P6--)P8: routes commands
  P7--)P9: offers programs
  P8--)P10: manages containers
  P10--)P11: uses Docker operations
  P10--)P12: installs services
  P11--)P13: operates
Steps as text
  1. Service installers to Compose definitions uses definitions
  2. Service list generator to System settings reads settings
  3. Proxy config generator to System settings reads settings
  4. Server administrator to CLI menu chooses services
  5. Server administrator to Program installer requests programs
  6. CLI menu to Command router routes commands
  7. Program installer to Other programs offers programs
  8. Command router to Container manager manages containers
  9. Container manager to Docker operations uses Docker operations
  10. Container manager to Service catalog installs services
  11. Docker operations to Docker operates

7.4. Business logic

Once UI code and the services and entities above are set aside, these classes have the most methods.

GeneratorAIS Core source, 3 methods
read_yml, generate_containers_list, write_containers_list_text
ReverseProxy Core source, 3 methods
read_yml, generate_nginx_conf, generate_server_block

7.5. Database and persistence

Data containers

mariadb linuxserver/mariadb mariadb postgres:16 mysql:8.1 mysql:8.1 mongo:7.0 postgres:latest

7.6. CI/CD pipeline

No CI/CD pipeline in the repository apart from Travis CI. The code is built and run by hand, as described above.

7.7. Deployment

Mermaid Deployment diagram
flowchart LR
  repo[("GitHub repository")]
  ci_Travis_CI[["Travis CI"]]
  image["Docker image<br/>FROM alpine:edge"]
  subgraph compose["Docker Compose"]
    svc_airsonic["airsonic"]
    svc_ansible_semaphore_db["ansible-semaphore_db"]
    svc_bookstack["bookstack"]
    svc_bookstack_db["bookstack_db"]
    svc_calibre["calibre"]
    svc_chevereto_db["chevereto_db"]
    svc_chevereto["chevereto"]
    svc_code_server["code-server"]
    svc_more["+8"]
  end
  repo --> ci_Travis_CI
  repo -->|"docker build"| image
  image -->|"docker compose up"| compose
UML Deployment
Deployment

The outer node is where the code runs. Each base image points to what it builds, solid arrows lead to databases and dashed ones to outside services. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
node "Docker Compose" as H {
  node "airsonic" as N0 <<container>>
  node "ansible-semaphore_db" as N1 <<container>>
  node "bookstack" as N2 <<container>>
  node "bookstack_db" as N3 <<container>>
  node "calibre" as N4 <<container>>
  node "chevereto_db" as N5 <<container>>
  node "chevereto" as N6 <<container>>
  node "code-server" as N7 <<container>>
  node "couchpotato" as N8 <<container>>
  node "cyberchef" as N9 <<container>>
}
artifact "FROM alpine:edge" as IMG0
IMG0 ..> N0 : builds
artifact "FROM golang:1.21-alpine" as IMG1
IMG1 ..> N0 : builds
artifact "FROM alpine:latest" as IMG2
IMG2 ..> N0 : builds
@enduml

Where it runs

Compose services

airsonic ansible-semaphore_db bookstack bookstack_db calibre chevereto_db chevereto code-server couchpotato cyberchef dailynotes dashmachine draw.io duplicati emby firefly_iii_app

Docker base images

alpine:edge golang:1.21-alpine alpine:latest node:20.7-alpine ubuntu:22.04 alpine:latest

7.8. Monitoring

What the code logs, measures and exposes to tell whether it is working.

Container health checks

7.9. Security

Supply chain

7.10. Testing

Test files
3
Source files
109
Unit tests
3

Code coverage

No measured coverage report in the analyzed sources.

Where the tests are

tests 3

Nothing found for: Public interface, Private interface, Services, Entities, External integrations, Stack and dependencies.

8. Deployment and operations

The ports, storage, and startup relationships below come from the repository configuration. depends_on records startup order, not service readiness.

9. Types and file structure

2 declared types, with 2 in the base-relationship overview.

Type diagram
classDiagram
direction TB
class t9c1d5cd3c00c["GeneratorAIS"] {
  __init__()
  read_yml()
  generate_containers_list()
  write_containers_list_text()
}
class t51dcacef3aad["ReverseProxy"] {
  read_yml()
  generate_nginx_conf()
  generate_server_block()
}
class bb0976d8612e0["object"] {
  <<unresolved_base>>
}
bb0976d8612e0 <|-- t9c1d5cd3c00c

Unresolved bases remain labelled; full signatures are not reconstructed.

10. Reference

203 / 203 eligible files read (291 in the tree); 0 oversized, 0 failed reads and 1 syntax diagnostics.

What the scan covers

Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.

Linguist statistics cover the whole repository and may include other languages.

12. Files to read 3

13. Glossary

Repository

The versioned source files, configuration, and history of a project.

README

The repository’s entry document, usually covering its purpose and initial setup.

Dependency

A library, tool, or service that another component needs to build or run.

Container

An isolated process environment created from an image. Persistent data needs storage outside the container’s disposable filesystem.

Published port

A host port mapped to a service’s container port. Publishing a port can expose that service beyond its container network.

CLI

A text interface in which commands and arguments select operations. Exit codes let scripts detect success or failure.

14. References

  1. antoinebou12. (2026, November 5). another-install-script. [Software repository] github.com.
  2. antoinebou12. (2026, November 5). another-install-script: README. [Repository documentation] github.com.
  3. antoinebou12. (2026, November 5). setup.sh. [Source file] github.com.
  4. antoinebou12. (2026, November 5). src/menu.sh. [Source file] github.com.
  5. antoinebou12. (2026, November 5). config.yml. [Source file] github.com.
  6. Boucher, A. (2024, January 1). MediaBoxDockerCompose. [Project article] antoineboucher.info.
  7. Boucher, A. (2026, October 23). another-install-script: A menu for homelab installation. [Project article] antoineboucher.info.

Sources without a publication date show the date they were last checked, November 5, 2026. File links retain the inspected revision where available.