Browse Source

Merge pull request #394 from mr-karan/install

feat: Add easy install script
Kailash Nadh 4 years ago
parent
commit
a22d7facbd
4 changed files with 174 additions and 10 deletions
  1. 27 2
      README.md
  2. 11 0
      docker-compose.yml
  3. 4 8
      install-demo.sh
  4. 132 0
      install-prod.sh

+ 27 - 2
README.md

@@ -17,14 +17,39 @@ The latest image is available on DockerHub at `listmonk/listmonk:latest`. Use th
 
 ```bash
 mkdir listmonk-demo
-sh -c "$(curl -sSL https://raw.githubusercontent.com/knadh/listmonk/master/install-demo.sh)"
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/knadh/listmonk/master/install-demo.sh)"
 ```
 
 The demo does not persist Postgres after the containers are removed. DO NOT use this demo setup in production.
 
 #### Production
+
+##### Easy Docker install
+
+This setup is recommended if you want to _quickly_ setup `listmonk` in production.
+
+```bash
+mkdir listmonk
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/knadh/listmonk/master/install-prod.sh)"
+```
+
+The above shell script performs the following actions:
+
+- Downloads `docker-compose.yml` and generates a `config.toml`.
+- Runs a Postgres container and installs the database schema.
+- Runs the `listmonk` container.
+
+**NOTE**: It's recommended to examine the contents of the shell script, before running in your environment.
+
+##### Manual Docker install
+
+The following workflow is recommended to setup `listmonk` manually using `docker-compose`. You are encouraged to customise the contents of `docker-compose.yml` to your needs. The overall setup looks like:
+
 - `docker-compose up db` to run the Postgres DB.
-- `docker-compose run --rm app ./listmonk --install` to setup the DB (or `--upgrade` to upgrade an existing DB)
+- `docker-compose run --rm app ./listmonk --install` to setup the DB (or `--upgrade` to upgrade an existing DB).
+- Copy `config.toml.sample` to your directory and make the following changes:
+    - `app.address` => `0.0.0.0:9000` (Port forwarding on Docker will work only if the app is advertising on all interfaces.)
+    - `db.host` => `listmonk_db` (Container Name of the DB container)
 - Run `docker-compose up app` and visit `http://localhost:9000`.
 
 More information on [docs](https://listmonk.app/docs).

+ 11 - 0
docker-compose.yml

@@ -23,10 +23,16 @@ x-db-defaults: &db-defaults
     - POSTGRES_USER=listmonk
     - POSTGRES_DB=listmonk
   restart: unless-stopped
+  healthcheck:
+    test: ["CMD-SHELL", "pg_isready -U listmonk"]
+    interval: 10s
+    timeout: 5s
+    retries: 6
 
 services:
   db:
     <<: *db-defaults
+    container_name: listmonk_db
     volumes:
       - type: volume
         source: listmonk-data
@@ -34,14 +40,19 @@ services:
 
   app:
     <<: *app-defaults
+    container_name: listmonk_app
     depends_on:
       - db
+    volumes:
+      - ./config.toml:/listmonk/config.toml
 
   demo-db:
+    container_name: listmonk_demo_db
     <<: *db-defaults
 
   demo-app:
     <<: *app-defaults
+    container_name: listmonk_demo_app
     command: [sh, -c, "yes | ./listmonk --install --config config-demo.toml && ./listmonk --config config-demo.toml"]
     depends_on:
       - demo-db

+ 4 - 8
install-demo.sh

@@ -1,14 +1,10 @@
-#!/bin/sh
-
-set -e
+#!/usr/bin/env sh
+set -eu
 
 # Listmonk demo setup using `docker-compose`.
-#
 # See https://listmonk.app/docs/installation/ for detailed installation steps.
-#
-
 
-check_dependency() {
+check_dependencies() {
 	if ! command -v curl > /dev/null; then
 		echo "curl is not installed."
 		exit 1
@@ -35,6 +31,6 @@ show_output(){
 }
 
 
-check_dependency
+check_dependencies
 setup_containers
 show_output

+ 132 - 0
install-prod.sh

@@ -0,0 +1,132 @@
+#!/usr/bin/env sh
+set -eu
+
+# Listmonk production setup using `docker-compose`.
+# See https://listmonk.app/docs/installation/ for detailed installation steps.
+
+printf '\n'
+
+RED="$(tput setaf 1 2>/dev/null || printf '')"
+BLUE="$(tput setaf 4 2>/dev/null || printf '')"
+GREEN="$(tput setaf 2 2>/dev/null || printf '')"
+NO_COLOR="$(tput sgr0 2>/dev/null || printf '')"
+
+info() {
+  printf '%s\n' "${BLUE}>${NO_COLOR} $*"
+}
+
+error() {
+  printf '%s\n' "${RED}x $*${NO_COLOR}" >&2
+}
+
+completed() {
+  printf '%s\n' "${GREEN}✓${GREEN} $*"
+}
+
+exists() {
+  command -v "$1" 1>/dev/null 2>&1
+}
+
+check_dependencies() {
+	if ! exists curl; then
+		error "curl is not installed."
+		exit 1
+    fi
+
+	if ! exists docker; then
+		error "docker is not installed."
+		exit 1
+    fi
+
+	if ! exists docker-compose; then
+		error "docker-compose is not installed."
+		exit 1
+	fi
+}
+
+download() {
+    curl --fail --silent --location --output "$2" "$1"
+}
+
+is_healthy() {
+    info "waiting for db container to be up. retrying in 3s"
+    health_status="$(docker inspect -f "{{.State.Health.Status}}" "$1")"
+    if [ "$health_status" = "healthy" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+is_running() {
+    info "checking if "$1" is running"
+    status="$(docker inspect -f "{{.State.Status}}" "$1")"
+    if [ "$status" = "running" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+generate_password(){
+    echo $(tr -dc A-Za-z0-9 </dev/urandom | head -c 13 ; echo '')
+}
+
+get_config() {
+    info "fetching config.toml from listmonk repo"
+    download https://raw.githubusercontent.com/knadh/listmonk/master/config.toml.sample config.toml
+}
+
+get_containers() {
+    info "fetching docker-compose.yml from listmonk repo"
+    download https://raw.githubusercontent.com/knadh/listmonk/master/docker-compose.yml docker-compose.yml
+}
+
+modify_config(){
+    info "generating a random password"
+    db_password=$(generate_password)
+
+    info "modifying config.toml"
+    # Replace `db.host=localhost` with `db.host=db` in config file.
+    sed -i "s/host = \"localhost\"/host = \"listmonk_db\"/g" config.toml
+    # Replace `db.password=listmonk` with `db.password={{db_password}}` in config file.
+    # Note that `password` is wrapped with `\b`. This ensures that `admin_password` doesn't match this pattern instead.
+    sed -i "s/\bpassword\b = \"listmonk\"/password = \"$db_password\"/g" config.toml
+    # Replace `app.address=localhost:9000` with `app.address=0.0.0.0:9000` in config file.
+    sed -i "s/address = \"localhost:9000\"/address = \"0.0.0.0:9000\"/g" config.toml
+
+    info "modifying docker-compose.yml"
+    sed -i "s/POSTGRES_PASSWORD=listmonk/POSTGRES_PASSWORD=$db_password/g" docker-compose.yml
+}
+
+run_migrations(){
+    info "running migrations"
+    docker-compose up -d db
+    while ! is_healthy listmonk_db; do sleep 3; done
+    docker-compose run --rm app ./listmonk --install
+}
+
+start_services(){
+    info "starting app"
+    docker-compose up -d app db
+}
+
+show_output(){
+    info "finishing setup"
+    sleep 3
+
+    if is_running listmonk_db && is_running listmonk_app
+    then completed "Listmonk is now up and running. Visit http://localhost:9000 in your browser."
+    else
+        error "error running containers. something went wrong."
+    fi
+}
+
+
+check_dependencies
+get_config
+get_containers
+modify_config
+run_migrations
+start_services
+show_output