pull/10/head
Hunter Long 2018-06-24 18:58:27 -07:00
parent 535ee06414
commit 3df5ecf5f5
18 changed files with 116 additions and 141 deletions

View File

@ -38,20 +38,17 @@ LETSENCRYPT_HOST=mydomain.com \
Once your instance has started, it will take a moment to get your SSL certificate. Make sure you have a A or CNAME record on your domain that points to the IP/DNS of your server running Statup. Once your instance has started, it will take a moment to get your SSL certificate. Make sure you have a A or CNAME record on your domain that points to the IP/DNS of your server running Statup.
## Run on EC2 Server ## Run on EC2 Server
Running Statup on the smallest EC2 server is very quick using the AWS AMI Image: `ami-84da93fc`. Running Statup on the smallest EC2 server is very quick using the AWS AMI Image: `ami-7be8a103`.
```bash ```bash
ec2-run-instances --key KEYPAIR ami-7ad39a02 ec2-run-instances --key KEYPAIR ami-7be8a103
``` ```
# EC2 with Automatic SSL Certificate # EC2 with Automatic SSL Certificate
```bash ```bash
wget https://raw.githubusercontent.com/hunterlong/statup/master/servers/ec2-ssl.sh wget https://raw.githubusercontent.com/hunterlong/statup/master/servers/ec2-ssl.sh
# # Edit ec2-ssl.sh and change LETSENCRYPT_HOST and LETSENCRYPT_EMAIL
# Edit ec2-ssl.sh and add LETSENCRYPT_HOST and LETSENCRYPT_EMAIL
#
# nano ec2-ssl.sh # nano ec2-ssl.sh
# ec2-run-instances --key KEYPAIR --user-data-file ec2-ssl.sh ami-7be8a103
ec2-run-instances --key KEYPAIR --user-data-file ec2-ssl.sh ami-7ad39a02
``` ```
## Email Nofitications ## Email Nofitications

View File

@ -3,6 +3,8 @@
APP="statup" APP="statup"
REPO="hunterlong/statup" REPO="hunterlong/statup"
printf "UPDATE core SET version='$VERSION';\n" >> sql/upgrade.sql
rice embed-go rice embed-go
mkdir build mkdir build

View File

@ -10,12 +10,10 @@ import (
func CheckServices() { func CheckServices() {
services, _ = SelectAllServices() services, _ = SelectAllServices()
time.Sleep(3 * time.Second)
for _, v := range services { for _, v := range services {
obj := v obj := v
go obj.StartCheckins() go obj.StartCheckins()
go obj.CheckQueue() go obj.CheckQueue()
time.Sleep(1 * time.Second)
} }
} }
@ -89,8 +87,6 @@ func (s *Service) Failure(issue string) {
Issue: issue, Issue: issue,
} }
s.CreateFailure(data) s.CreateFailure(data)
SendFailureEmail(s) SendFailureEmail(s)
OnFailure(s) OnFailure(s)
} }

45
cli.go Normal file
View File

@ -0,0 +1,45 @@
package main
import (
"fmt"
"os"
"time"
)
func CatchCLI(args []string) {
switch args[1] {
case "version":
fmt.Printf("Statup v%v\n", VERSION)
case "export":
fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
RenderBoxes()
configs, _ = LoadConfig()
setupMode = true
mainProcess()
time.Sleep(10 * time.Second)
indexSource := ExportIndexHTML()
SaveFile("./index.html", []byte(indexSource))
fmt.Println("Exported Statup index page: 'index.html'")
case "help":
HelpEcho()
case "update":
fmt.Println("Sorry updating isn't available yet!")
default:
fmt.Println("Statup does not have the command you entered.")
os.Exit(1)
}
}
func HelpEcho() {
fmt.Printf("Statup v%v - Statup.io\n", VERSION)
fmt.Printf("A simple Application Status Monitor that is opensource and lightweight.\n")
fmt.Printf("Commands:\n")
fmt.Println(" statup - Main command to run Statup server")
fmt.Println(" statup version - Returns the current version of Statup")
fmt.Println(" statup export - Exports the index page as a static HTML for pushing")
fmt.Println(" to Github Pages or your own FTP server. Export will")
fmt.Println(" create 'index.html' in the current directory.")
fmt.Println(" statup update - Attempts to update to the latest version")
fmt.Println(" statup help - Shows the user basic information about Statup")
fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
}

View File

@ -1,4 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
VERSION=v0.22
OS=osx OS=osx
ARCH=x64 ARCH=x64
if [ `getconf LONG_BIT` = "64" ] if [ `getconf LONG_BIT` = "64" ]
@ -15,9 +16,8 @@ case "${unameOut}" in
MINGW*) OS=windows;; MINGW*) OS=windows;;
*) OS="UNKNOWN:${unameOut}" *) OS="UNKNOWN:${unameOut}"
esac esac
echo " Installing for $OS $ARCH..." FILE="https://github.com/hunterlong/statup/releases/download/$VERSION/statup-$OS-$ARCH"
FILE="https://repo.com/tag/statup-$OS-$ARCH"
curl -sS $FILE -o statup curl -sS $FILE -o statup
chmod +x statup chmod +x statup
mv statup /usr/local/bin/ mv statup /usr/local/bin/
echo " statup has been successfully installed!" statup version

View File

@ -1,3 +1,6 @@
var currentLocation = window.location;
$("#domain_input").val(currentLocation.origin);
$('select#database_type').on('change', function(){ $('select#database_type').on('change', function(){
var selected = $('#database_type option:selected').val(); var selected = $('#database_type option:selected').val();
if (selected=="sqlite") { if (selected=="sqlite") {
@ -14,3 +17,4 @@ $('select#database_type').on('change', function(){
$("#db_database").show(); $("#db_database").show();
} }
}); });

View File

@ -50,6 +50,11 @@
<input type="text" name="description" class="form-control" value="{{ .Description }}" id="formGroupExampleInput" placeholder="Great Uptime"> <input type="text" name="description" class="form-control" value="{{ .Description }}" id="formGroupExampleInput" placeholder="Great Uptime">
</div> </div>
<div class="form-group">
<label for="formGroupExampleInput">Domain</label>
<input type="text" name="domain" class="form-control" value="{{ .Domain }}" id="formGroupExampleInput">
</div>
<div class="form-group"> <div class="form-group">
<label for="formGroupExampleInput">Custom Footer</label> <label for="formGroupExampleInput">Custom Footer</label>
<textarea rows="4" name="footer" class="form-control" id="formGroupExampleInput">{{ .Footer }}</textarea> <textarea rows="4" name="footer" class="form-control" id="formGroupExampleInput">{{ .Footer }}</textarea>

View File

@ -15,6 +15,8 @@
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
<div class="col-12">
{{ if .Error }} {{ if .Error }}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
{{ .Error }} {{ .Error }}
@ -36,23 +38,23 @@
</div> </div>
<div class="form-group" id="db_host"> <div class="form-group" id="db_host">
<label for="formGroupExampleInput">Host</label> <label for="formGroupExampleInput">Host</label>
<input type="text" name="db_host" class="form-control" value="{{.DbHost}}" placeholder="localhost"> <input type="text" name="db_host" class="form-control" value="{{.DbHost}}" placeholder="localhost" required>
</div> </div>
<div class="form-group" id="db_port"> <div class="form-group" id="db_port">
<label for="formGroupExampleInput">Database Port</label> <label for="formGroupExampleInput">Database Port</label>
<input type="text" name="db_port" class="form-control" value="{{.DbPort}}" placeholder="localhost"> <input type="text" name="db_port" class="form-control" value="{{.DbPort}}" placeholder="localhost" required>
</div> </div>
<div class="form-group" id="db_user"> <div class="form-group" id="db_user">
<label for="formGroupExampleInput2">Username</label> <label for="formGroupExampleInput2">Username</label>
<input type="text" name="db_user" class="form-control" value="{{.DbUser}}" placeholder="root"> <input type="text" name="db_user" class="form-control" value="{{.DbUser}}" placeholder="root" required>
</div> </div>
<div class="form-group" id="db_password"> <div class="form-group" id="db_password">
<label for="formGroupExampleInput2">Password</label> <label for="formGroupExampleInput2">Password</label>
<input type="password" name="db_password" class="form-control" value="{{.DbPass}}" id="formGroupExampleInput2" value="" placeholder="password123"> <input type="password" name="db_password" class="form-control" value="{{.DbPass}}" id="formGroupExampleInput2" value="" placeholder="password123" required>
</div> </div>
<div class="form-group" id="db_database"> <div class="form-group" id="db_database">
<label for="formGroupExampleInput2">Database</label> <label for="formGroupExampleInput2">Database</label>
<input type="text" name="db_database" class="form-control" value="{{.DbData}}" id="formGroupExampleInput2" value="statup" placeholder="Database name"> <input type="text" name="db_database" class="form-control" value="{{.DbData}}" id="formGroupExampleInput2" value="statup" placeholder="Database name" required>
</div> </div>
</div> </div>
@ -61,7 +63,7 @@
<div class="form-group"> <div class="form-group">
<label for="formGroupExampleInput">Project Name</label> <label for="formGroupExampleInput">Project Name</label>
<input type="text" name="project" class="form-control" value="{{.Project}}" id="formGroupExampleInput" placeholder="Great Uptime"> <input type="text" name="project" class="form-control" value="{{.Project}}" id="formGroupExampleInput" placeholder="Great Uptime" required>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -69,24 +71,24 @@
<input type="text" name="description" class="form-control" value="{{.Description}}" id="formGroupExampleInput" placeholder="Great Uptime"> <input type="text" name="description" class="form-control" value="{{.Description}}" id="formGroupExampleInput" placeholder="Great Uptime">
</div> </div>
<div class="form-group">
<label for="domain_input">Domain URL</label>
<input type="text" name="domain" class="form-control" value="{{.Domain}}" id="domain_input" required>
</div>
<div class="form-group"> <div class="form-group">
<label for="formGroupExampleInput">Admin Username</label> <label for="formGroupExampleInput">Admin Username</label>
<input type="text" name="username" class="form-control" value="{{.Username}}" id="formGroupExampleInput" value="admin" placeholder="admin"> <input type="text" name="username" class="form-control" value="{{.Username}}" id="formGroupExampleInput" value="admin" placeholder="admin" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="formGroupExampleInput">Admin Email Address</label> <label for="formGroupExampleInput">Admin Email Address</label>
<input type="email" name="email" class="form-control" value="{{.Email}}" id="formGroupExampleInput" placeholder="info@admin.com"> <input type="email" name="email" class="form-control" value="{{.Email}}" id="formGroupExampleInput" placeholder="info@admin.com" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="formGroupExampleInput">Admin Password</label> <label for="formGroupExampleInput">Admin Password</label>
<input type="password" name="password" class="form-control" value="{{.Password}}" id="formGroupExampleInput" value="admin" placeholder="admin"> <input type="password" name="password" class="form-control" value="{{.Password}}" id="formGroupExampleInput" placeholder="password" required>
</div>
<div class="form-group">
<label for="formGroupExampleInput">Confirm Password</label>
<input type="password" name="confirm_password" class="form-control" value="{{.Password}}" id="formGroupExampleInput" value="admin" placeholder="admin">
</div> </div>
<div class="form-group"> <div class="form-group">
@ -107,10 +109,13 @@
</div> </div>
</div>
{{template "footer"}} {{template "footer"}}
<script src="/js/jquery-3.3.1.slim.min.js"></script> <script src="/js/jquery-3.3.1.slim.min.js"></script>
<script src="/js/bootstrap.min.js"></script> <script src="/js/bootstrap.min.js"></script>
<script src="/js/setup.js"></script> <script src="/js/setup.js"></script>
</body> </body>
</html> </html>

20
main.go
View File

@ -15,7 +15,6 @@ import (
plg "plugin" plg "plugin"
"strconv" "strconv"
"strings" "strings"
"time"
) )
var ( var (
@ -94,24 +93,7 @@ func DownloadFile(filepath string, url string) error {
func main() { func main() {
if len(os.Args) >= 2 { if len(os.Args) >= 2 {
if os.Args[1] == "version" { CatchCLI(os.Args)
fmt.Printf("Statup v%v\n", VERSION)
}
if os.Args[1] == "export" {
fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
RenderBoxes()
configs, _ = LoadConfig()
setupMode = true
mainProcess()
time.Sleep(10 * time.Second)
indexSource := ExportIndexHTML()
SaveFile("./index.html", []byte(indexSource))
fmt.Println("Exported Statup index page: 'index.html'")
}
os.Exit(0) os.Exit(0)
} }

View File

@ -0,0 +1,15 @@
version: '2.3'
services:
statup:
container_name: statup
image: hunterlong/statup:latest
restart: always
ports:
- 0.0.0.0:80:8080
volumes:
- ./statup/app:/app
environment:
NAME: Single Docker Image
DESCRIPTION: You'll need to input your own Database information in Setup process

View File

@ -1,10 +1,16 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#
# Steps for Automatic SSL with Statup
#
# 1. Create EC2 Instance while including this file has "--data-file"
# 2. Once EC2 is created, view System Logs in EC2 instance.
# 3. In System logs, scroll all the way down and you'll see useful DNS records to use
# 4. Edit your domains DNS to point to the EC2 server.
#
## Domain for new SSL certificate and email for Lets Encrypt SSL recovery
## Domain for new SSL certificate LETSENCRYPT_HOST="status.MYDOMAIN.com"
LETSENCRYPT_HOST="status.balancebadge.io" LETSENCRYPT_EMAIL="noreply@MYEMAIL.com"
## An email address that can recover SSL certificate from Lets Encrypt
LETSENCRYPT_EMAIL="info@socialeck.com"
################################################### ###################################################
############# Leave this part alone ############### ############# Leave this part alone ###############

View File

@ -6,7 +6,7 @@ After=network-online.target
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart=/home/ubuntu/startup.sh ExecStart=/home/ubuntu/init.sh
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
cd /home/ubuntu
sudo rm -f docker-compose.yml
sudo curl -o docker-compose.yml -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/hunterlong/statup/master/servers/docker-compose.yml
sudo service docker start
sudo docker system prune -af
sudo LETSENCRYPT_HOST=$LETSENCRYPT_HOST LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL docker-compose pull
sudo LETSENCRYPT_HOST=$LETSENCRYPT_HOST LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL docker-compose up -d

View File

@ -1,24 +0,0 @@
#!/usr/bin/env bash
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce -y
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo docker-compose --version
sudo systemctl enable docker
mkdir statup
cd statup
wget https://raw.githubusercontent.com/hunterlong/statup/master/servers/docker-compose.yml
sudo service docker start
sudo docker-compose up -d

View File

@ -1,30 +0,0 @@
#!/usr/bin/env bash
LETSENCRYPT_HOST="status.balancebadge.io"
LETSENCRYPT_EMAIL="info@socialeck.com"
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce -y
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo docker-compose --version
sudo systemctl enable docker
mkdir statup
cd statup
rm -f docker-compose.yml
curl -o docker-compose.yml -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/hunterlong/statup/master/servers/docker-compose-ssl.yml
sudo service docker start
sudo docker system prune -af
sudo LETSENCRYPT_HOST=$LETSENCRYPT_HOST LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL docker-compose pull
sudo LETSENCRYPT_HOST=$LETSENCRYPT_HOST LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL docker-compose up -d

View File

@ -1,24 +0,0 @@
#!/usr/bin/env bash
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce -y
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo docker-compose --version
sudo systemctl enable docker
mkdir statup
cd statup
wget https://raw.githubusercontent.com/hunterlong/statup/master/servers/docker-compose.yml
sudo service docker start
sudo docker-compose up -d

View File

@ -183,7 +183,7 @@ func (c *DbConfig) Save() error {
NewSHA1Hash(10), NewSHA1Hash(10),
"", "",
"", "",
"", c.Domain,
VERSION, VERSION,
[]plugin.Info{}, []plugin.Info{},
[]PluginJSON{}, []PluginJSON{},

4
web.go
View File

@ -351,6 +351,10 @@ func SaveSettingsHandler(w http.ResponseWriter, r *http.Request) {
if footer != core.Footer { if footer != core.Footer {
core.Footer = footer core.Footer = footer
} }
domain := r.PostForm.Get("domain")
if domain != core.Domain {
core.Domain = domain
}
core.Update() core.Update()
OnSettingsSaved(core) OnSettingsSaved(core)
http.Redirect(w, r, "/settings", http.StatusSeeOther) http.Redirect(w, r, "/settings", http.StatusSeeOther)