{"id":13850817,"url":"https://github.com/l3nz/whaleware","last_synced_at":"2025-04-03T03:38:39.373Z","repository":{"id":20077313,"uuid":"23346271","full_name":"l3nz/whaleware","owner":"l3nz","description":"A standard startup template for Docker images","archived":false,"fork":false,"pushed_at":"2023-04-05T09:38:39.000Z","size":63,"stargazers_count":16,"open_issues_count":7,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-22T05:30:19.365Z","etag":null,"topics":["docker"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/l3nz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-08-26T09:29:16.000Z","updated_at":"2022-02-17T17:05:26.000Z","dependencies_parsed_at":"2024-11-22T07:03:24.783Z","dependency_job_id":null,"html_url":"https://github.com/l3nz/whaleware","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l3nz%2Fwhaleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l3nz%2Fwhaleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l3nz%2Fwhaleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l3nz%2Fwhaleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/l3nz","download_url":"https://codeload.github.com/l3nz/whaleware/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246933359,"owners_count":20857051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker"],"created_at":"2024-08-04T21:00:19.337Z","updated_at":"2025-04-03T03:38:39.316Z","avatar_url":"https://github.com/l3nz.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"whaleware\n=========\n\n\t\n\nA standard startup template for Docker server images. Available as a base CentOS 7 image \nunder the name 'lenz/whaleware' - https://registry.hub.docker.com/r/lenz/whaleware\n\nPrinciples\n----------\n\n- Server instances should have a fine-grained life cycle. Starting up a web instance does not\n  mean that the instance is immediately ready to serve requests. It might have to warm itself\n  up, update a local database, load resources, etc. You do not want to add an instance to a \n  load balancing pool before it's ready to run.\n- Server instances should be able to report their own health periodically.\n- Server instances should contain a watchdog process that will restart them as needed.\n- As the number of configuration variables tends to be quite large, instead of passing \n  a large set of parameters, we prefer using a JSON structure. This JSON structure is then \n  filled in with embedded default parameters, so that only non-default ones are to\n  be passed externally.\n- Though we have a preference for JSON over HTTP, notifications should be environment-agnostic.\n  You could store the current lifecycle information and app health on a database, or on\n  an external webapp, on `etcd` or in an Elasticsearch database. You should be able to choose.\n- Running a server within Docker means receiving Docker signals - so you can start an orderly\n  shutdown in case the instance needs to terminate.\n- Data should be stored in a separate directory, ready to mount a data-only container (if you want to)\n  or to run without persistent data at all.\n- You should be able to customize easily all of the features above, and decide what to use and \n  what to ignore. You want notifications? edit one file. You don't want notifications? just leave it blank.\n\n\nBenefits\n--------\n\n- Using a common filesystem layout. Just replace files as needed under `/ww/usr`\n- All-JSON configuration. The configuration is passed as a JSON file that is merged with an existing defaults file. \n  So you do not have to track a large number of separate environment variables. \n- Centrally reports the state of an instance. \n- Periodically reports health statistics.\n- Monitors the application and restarts it if needed\n- Makes no assumption on the kind of services used for reporting - we use HTTP, but you may hot-swap the reporting\n  scripts to implement your own checks and reporting format.\n- Tries to terminate all services gracefully on stops.\n\n\nHow it works\n------------\n\nWhen an instance is started (via `/ww/run`) it gets the external configuration from the CFG \nparameter, applies any defaults found in `/www/etc/default_cfg.json` and saves it under\n`/www/etc/cfg.json` . This configuration can be queried at any time though the `/ww/cfg` script.\n\nOn first start, it runs the **boot** script to edit the default image according to the \nconfiguration received externally. This happens each time an image is booted.\n\nThen it checks to see if the data-only container is initialized. Of course this only makes sense\nif you have a data-only container mounted under `/data`. If none is mounted, the webapp will\nalways perform a first boot.\n\nIf `/data` is not initialized, it launches the **firstboot** script so you can create databases, copy\nconfiguration scripts, etc. \n\nAfter this, the **upgrade** script is run. This is used to detect if `/data` contains material from\na previous version that needs upgrading.\n\nAfter this, the service(s) are started and **warmup** is called. This is needed to \nrun any warmup queries that might be needed to provide acceptable production performance.\n\nOnly at this point the app is considered UP and is ready to serve instances.\n\nEvery 30 seconds, the **monitor** script is run. It is supposed to query the app and return a JSON\nobject with health information (number of queries processed, free memory, etc.). This information is\nposted to a database through the **pushstats** script.\n\nIf the monitor scripts returns with an error code, then all services are stopped and restarted \n(through **svcdown** and **svcup**).\n\nWhile the app is running, if you issue a `docker stop` the run process will shutdown services and \nterminate cleanly.\n\nMost likely, you will NOT need all of these stages in your app. So you can simply create\nthe scripts you need and leave other scripts blank.\n\nPermanent storage\n-----------------\n\nwhaleware offers a common pattern to manage permanent storage. All storage should be stored under the \"/data\"\ndirectory. If you want this to be permanent, you can either use a data-only container that exports\nit or mount it as a local folder.\n\n### Using a data-only container\n\nThe simplest way to run a permanent data-only container is to create a named container and bind it\nto your whaleware image:\n\n    docker run --name=MYWBT loway/data true\n    docker run --volumes-from MYWBT -p 8080:8080 -d loway/wombatdialer\n\nBy using a named container, the likelihood of binding to the wrong container is reduced.\n\n### Using a local directory\n\nYou can also bind your whaleware image to a local folder, just like in:\n\n    mkdir -p /opt/data/WBT1DATA\n    docker run -v /opt/data/WBT1DATA:/data -p 8080:8080 -d loway/wombatdialer\n\nThis makes it easy to access and inspect the contents of your data container at the price of\na somehow \"messier\" configuration on the host.\n\n\nConfiguration\n-------------\n\nwhaleware stores all configuration as a JSON file. The default configuration is stored\nin `/ww/etc/defaults.json`. When the app is run, a current configuration is computed by merging \nit with the contents of the CFG environment variable, that is to contain a JSON structure.\nYou then access the results of the merge though the `/ww/cfg` script.\n\nThis way you can override the default configuration on the command line, as in:\n\n    docker run -e CFG='{\"memory\":400}' -p 8080:8080 -d loway/wombatdialer\n\nAnd you can still have fairly complex configuration.\n\n\nDirectories used\n----------------\n\n- `/ww` - where all files for whaleware live\n- `/ww/usr` - where scripts are to be put\n- `/ww/files` - where your own configuration files can be put\n- `/ww/etc` - where the default configuration and the current configuration are stored\n- `/data` - where all data for an app is to be positioned\n- `/backup` - a mount point for backup scripts to send data to the host\n\n\nScripts used\n------------\n\nDefault scripts:\n\n- `/ww/run` - the script that orchestrates all other scripts\n- `/ww/cfg` - reads a configuration value from the current configuration\n\nUnder `/ww/usr` are the following scripts. Replace the one(s) you need.\n\n- `boot` - the script that sets the sytem up on an image boot. Sets the system up but for the `/data` directory. \n   Runs as first script on each and every boot.\n- `firstboot` - on the first boot, the `/data` directory is initialized. It happens just once if you have permanent storage.\n- `upgrade` - upgrades the system (eg applies database schema changes). It is run on every boot.\n- `warmup` - starts services and warms them up. It is run on every boot.\n- `monitor` - return a JSON blob about the state of the service. If it returns with an error code different than zero,\n  the webapp needs to be restarted.\n\nHelper scripts:\n\n- `svcdown` - shut down the server\n- `svcup` - starts the server\n- `lifecycle [STATE]` - notifies a central server about the life-cycle of the current app. The default implementation\n  just logs it on stdout.\n- `pushstats [JSON]` - pushes the JSON blob returned by `monitor` to a monitoring service. The default implementation\n  does nothing. \n\n\nAn app's life cycle\n-------------------\n\nAn app progresses trough a life-cycle. The life-cycle can be pushed externally through the `lifecycle` script so\nthat an external system can be aware of the current state of the app.\n\n- DOCKERUP - An optional state notified by a startup script before the app is started\n- BOOT - System is running the `boot` script.\n- FIRSTBOOT - System is running the `firstboot` script.\n- UPGRADING - System is running the `upgrading` script.\n- WARMUP - System is running the `warmup` script.\n- UP - System is ready to serve requests.\n- RESTARTING - System is being restarted, because either the `monitor` script encountered a problem or\n  a SIGHUP was received by the Docker host. After the restart, the system is flagged as UP.\n- STOPPED - System is being stopped because it received a SIGTERM from Docker (likely a \"docker stop\" was performed)\n- ERROR - System is in an unrecoverable error state and is terminating (not currently used).\n- DOCKERDOWN - An optional state notified by a stop script after the Docker app is shutdown\n\nExamples\n--------\n\n* [wombatdialer](examples/wombatdialer/wombatdialer.md). - a next generation dialer application for the Asterisk PBX. \n  It is interesting because it is a Java web application with embedded MySQL\n  and has a complex life cycle - so you can see the basic components in action.\n* [asterisk-load-test](examples/asterisk-load-test/README.md). - a set of plain Asterisk images that you can hot-swap. \n  AMI and ARI ports are up and ready for developement and testing. Now available for Asterisk 1.8, Asterisk 11, Asterisk 12 and \n  Asterisk 13.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl3nz%2Fwhaleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fl3nz%2Fwhaleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl3nz%2Fwhaleware/lists"}