chore(do/1-click): sunset DigitalOcean 1-click app (#2074)

This commit is contained in:
Iain Sproat 2024-06-21 17:26:04 +01:00 коммит произвёл GitHub
Родитель 2e59d231b5
Коммит 08d1bffdf6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 14 добавлений и 383 удалений

Просмотреть файл

@ -39,8 +39,9 @@ What is Speckle? Check our [![YouTube Video Views](https://img.shields.io/youtub
Give Speckle a try in no time by:
- [![speckle](https://img.shields.io/badge/https://-app.speckle.systems-0069ff?style=flat-square&logo=hackthebox&logoColor=white)](https://app.speckle.systems) ⇒ creating an account
- [![create a droplet](https://img.shields.io/badge/Create%20a%20Droplet-0069ff?style=flat-square&logo=digitalocean&logoColor=white)](https://marketplace.digitalocean.com/apps/speckle-server?refcode=947a2b5d7dc1) ⇒ deploying an instance in 1 click
- [![app.speckle.systems](https://img.shields.io/badge/https://-app.speckle.systems-0069ff?style=flat-square&logo=hackthebox&logoColor=white)](https://app.speckle.systems) ⇒ Create an account at app.speckle.systems
- [![Deploy on your own infrastructure with docker compose](https://img.shields.io/badge/https://-speckle.guide-0069ff?style=flat-square&logo=hackthebox&logoColor=white)](<[https://](https://speckle.guide/dev/server-manualsetup.html)>) ⇒ Deploy on your own infrastructure with Docker Compose
- [![Deploy on your own infrastructure with docker compose](https://img.shields.io/badge/https://-speckle.guide-0069ff?style=flat-square&logo=hackthebox&logoColor=white)](<[https://](https://speckle.guide/dev/server-setup-k8s.html)>) ⇒ Deploy on your own infrastructure with Kubernetes
## Resources

Просмотреть файл

@ -1,17 +0,0 @@
#!/bin/bash
set -euo pipefail
echo "* Getting latest version of SpeckleServer Setup files..."
mkdir -p /opt/speckle-server
cd /opt/speckle-server || exit 1
wget https://raw.githubusercontent.com/specklesystems/speckle-server/main/utils/1click_image_scripts/setup.py -O setup.py
wget https://raw.githubusercontent.com/specklesystems/speckle-server/main/utils/1click_image_scripts/template-nginx-site.conf -O template-nginx-site.conf
wget https://raw.githubusercontent.com/specklesystems/speckle-server/main/utils/1click_image_scripts/template-docker-compose.yml -O template-docker-compose.yml
docker image rm {speckle/speckle-preview-service:2,speckle/speckle-webhook-service:2,speckle/speckle-server:2,speckle/speckle-frontend:2} || true
chmod +x setup.py
echo "* Getting the docker images for the latest SpeckleServer release..."
docker compose -f template-docker-compose.yml pull

Просмотреть файл

@ -1,14 +1,5 @@
#!/usr/bin/env python3
import os
import socket
import subprocess
import secrets
import ruamel.yaml # this module preserves yaml comments and whitespaces
from ruamel.yaml.scalarstring import DoubleQuotedScalarString
FILE_PATH = os.path.dirname(os.path.abspath(__file__))
LOGO_STR = """
_____ _ _ _____
/ ___| | | | | / ___|
@ -21,202 +12,22 @@ LOGO_STR = """
"""
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
if not ip:
print("Error: Can't get local IP address")
exit(1)
return ip
def read_domain(ip):
print("\nYou can set up a domain name for this Speckle server.")
print(
"Important: To use a domain name, you must first configure it to point to this VM address (so we can issue the SSL certificate)"
)
print(f"VM address: {ip}")
while True:
domain = input("Domain name (leave blank to use the IP address): ").strip()
if not domain:
return None
try:
domain_ip = socket.gethostbyname(domain.strip())
except Exception as ex:
print(f"Error: Domain '{domain}' cannot be resolved: {str(ex)}")
continue
if domain_ip != ip:
print(f"Error: Domain '{domain}' points to {domain_ip} instead of {ip}")
continue
return domain
def read_email_settings(domain):
print(
"\nYou should configure an email provider to allow the Speckle Server to send emails."
)
print(
"Supported vendors: Any email provider that can provide SMTP connection details (mailjet, mailgun, etc)."
)
print(
"Important: If you don't configure email details, some features that require sending emails will not work, nevertheless the server should be functional."
)
while True:
enable_email = False
while True:
enable_email = input("Enable emails? [Y/n]: ").strip().lower()
if enable_email in ["n", "no"]:
enable_email = False
break
elif enable_email in ["", "y", "yes"]:
enable_email = True
break
else:
print("Unrecognized option")
continue
if not enable_email:
return None
print("Enter your SMTP connection details offered by your email provider")
smtp_host = input("SMTP server / host: ").strip()
smtp_port = input("SMTP port: ").strip()
try:
int(smtp_port)
except Exception:
print("Error: SMTP port must be a number. Retrying...")
continue
smtp_user = input("SMTP Username: ").strip()
smtp_pass = input("SMTP Password: ").strip()
if domain:
default_from_email = "no-reply@" + domain
else:
default_from_email = ""
email_from = input(f"Email address to send email as [{default_from_email}]: ")
if not email_from.strip():
email_from = default_from_email
if (
not smtp_host
or not smtp_port
or not smtp_user
or not smtp_pass
or not email_from
):
print("Error: One or more fields were empty. Retrying...")
continue
return {
"host": smtp_host,
"port": smtp_port,
"user": smtp_user,
"pass": smtp_pass,
"from": email_from,
}
def main():
print(LOGO_STR)
ip = get_local_ip()
###
### Read user input
#########
domain = read_domain(ip)
if domain:
canonical_url = f"https://{domain}"
else:
canonical_url = f"http://{ip}"
email = read_email_settings(domain)
###
### Create docker-compose.yml from the template
#########
print("\nConfiguring docker containers...")
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
with open(os.path.join(FILE_PATH, "template-docker-compose.yml"), "r") as f:
yml_doc = yaml.load(f)
env = yml_doc["services"]["speckle-server"]["environment"]
env["CANONICAL_URL"] = DoubleQuotedScalarString(canonical_url)
env["FRONTEND_ORIGIN"] = DoubleQuotedScalarString(canonical_url)
env["SESSION_SECRET"] = DoubleQuotedScalarString(secrets.token_hex(32))
if email:
env["EMAIL"] = DoubleQuotedScalarString("true")
env["EMAIL_HOST"] = DoubleQuotedScalarString(email["host"])
env["EMAIL_PORT"] = DoubleQuotedScalarString(email["port"])
env["EMAIL_USERNAME"] = DoubleQuotedScalarString(email["user"])
env["EMAIL_PASSWORD"] = DoubleQuotedScalarString(email["pass"])
env["EMAIL_FROM"] = DoubleQuotedScalarString(email["from"])
else:
env["EMAIL"] = DoubleQuotedScalarString("false")
fe2env = yml_doc["services"]["speckle-frontend-2"]["environment"]
fe2env["NUXT_PUBLIC_SERVER_NAME"] = DoubleQuotedScalarString(canonical_url)
fe2env["NUXT_PUBLIC_API_ORIGIN"] = DoubleQuotedScalarString(canonical_url)
fe2env["NUXT_PUBLIC_BASE_URL"] = DoubleQuotedScalarString(canonical_url)
with open(os.path.join(FILE_PATH, "docker-compose.yml"), "w") as f:
f.write("# This file was generated by SpeckleServer setup.\n")
f.write("# If the setup is re-run, this file will be overwritten.\n\n")
yaml.dump(yml_doc, f)
###
### Run the new docker compose file (will update containers if already running)
#########
subprocess.run(
["bash", "-c", f'cd "{FILE_PATH}"; docker compose up -d'], check=True
)
###
### Update nginx config and restart nginx
#########
print("\nConfiguring local nginx...")
nginx_conf_str = "# This file is managed by SpeckleServer setup script.\n"
nginx_conf_str += (
"# Any modifications will be removed when the setup script is re-executed\n\n"
)
with open(os.path.join(FILE_PATH, "template-nginx-site.conf"), "r") as f:
nginx_conf_str += f.read()
if domain:
nginx_conf_str = nginx_conf_str.replace("TODO_REPLACE_WITH_SERVER_NAME", domain)
else:
nginx_conf_str = nginx_conf_str.replace("TODO_REPLACE_WITH_SERVER_NAME", "_")
with open("/etc/nginx/sites-available/speckle-server", "w") as f:
f.write(nginx_conf_str)
subprocess.run(["nginx", "-s", "reload"], check=True)
###
### Run letsencrypt on new config
#########
if domain:
print("\n***")
print(
"*** Will now run LetsEncrypt utility to generate https certificate. Please answer any questions that are presented"
)
print(
"*** We highly recommend setting a good email address so that you are notified if there is any action needed to renew certificates"
)
print("***")
subprocess.run(["certbot", "--nginx", "-d", domain])
print("\nConfiguration complete!")
print("You can access your speckle server at: " + canonical_url)
print(LOGO_STR)
print("\nOne more thing and you are ready to roll:")
print(
f" - Go to {canonical_url} in your browser and create an account. The first user to register will be granted administrator rights."
"\nAs of March 2024, Speckle server DigitalOcean 1-click setup script is no longer supported."
)
print(
" - Fill in information about your server under your profile page (in the lower left corner)."
"\nPlease use the official Speckle Server installation guide to install Speckle Server on your own infrastructure."
)
print(
"\nThis could be on a DigitalOcean Droplet that you have created yourself using an Ubuntu image."
)
print(
"\nOur documentation can be found at https://speckle.guide/dev/server-manualsetup.html"
)
print(
"\nIf you require to view previous versions of the 1-click setup script, please review the history of the speckle-server repository on GitHub."
)
print("\nHappy Speckling!")

Просмотреть файл

@ -1,129 +0,0 @@
version: '2.3'
services:
####
# Speckle Server dependencies
#######
postgres:
image: 'postgres:14.5-alpine'
restart: always
environment:
POSTGRES_DB: speckle
POSTGRES_USER: speckle
POSTGRES_PASSWORD: speckle
volumes:
- ./postgres-data:/var/lib/postgresql/data/
ports:
- '127.0.0.1:5432:5432'
redis:
image: 'redis:7.0-alpine'
restart: always
volumes:
- ./redis-data:/data
ports:
- '127.0.0.1:6379:6379'
minio:
image: 'minio/minio'
command: server /data --console-address ":9001"
restart: always
volumes:
- ./minio-data:/data
ports:
- '127.0.0.1:9000:9000'
- '127.0.0.1:9001:9001'
####
# Speckle Server
#######
speckle-frontend-2:
image: speckle/speckle-frontend-2:2
restart: always
ports:
- '127.0.0.1:8080:8080'
environment:
NUXT_PUBLIC_SERVER_NAME: 'TODO: change' # e.g. 'my-speckle-server'
NUXT_PUBLIC_API_ORIGIN: 'TODO: change' # e.g. 'http://127.0.0.1'
NUXT_PUBLIC_BASE_URL: 'TODO: change' # e.g. 'http://127.0.0.1'
NUXT_PUBLIC_BACKEND_API_ORIGIN: 'http://speckle-server:3000'
NUXT_PUBLIC_LOG_LEVEL: 'warn'
NUXT_REDIS_URL: 'redis://redis'
speckle-server:
image: speckle/speckle-server:2
restart: always
healthcheck:
test:
- CMD
- node
- -e
- "try { require('node:http').request({headers: {'Content-Type': 'application/json'}, port:3000, hostname:'127.0.0.1', path:'/liveness', method: 'GET', timeout: 2000 }, (res) => { body = ''; res.on('data', (chunk) => {body += chunk;}); res.on('end', () => {process.exit(res.statusCode != 200 || body.toLowerCase().includes('error'));}); }).end(); } catch { process.exit(1); }"
interval: 10s
timeout: 10s
retries: 3
start_period: 90s
ports:
- '127.0.0.1:3000:3000'
environment:
CANONICAL_URL: 'TODO: change'
SESSION_SECRET: 'TODO: change'
STRATEGY_LOCAL: 'true'
LOG_LEVEL: 'info'
POSTGRES_URL: 'postgres'
POSTGRES_USER: 'speckle'
POSTGRES_PASSWORD: 'speckle'
POSTGRES_DB: 'speckle'
REDIS_URL: 'redis://redis'
WAIT_HOSTS: 'postgres:5432, redis:6379, minio:9000'
EMAIL: 'false'
EMAIL_HOST: 'TODO'
EMAIL_PORT: 'TODO'
EMAIL_USERNAME: 'TODO'
EMAIL_PASSWORD: 'TODO'
EMAIL_FROM: 'TODO'
EMAIL_SECURE: 'false'
S3_ENDPOINT: 'http://minio:9000'
S3_ACCESS_KEY: 'minioadmin'
S3_SECRET_KEY: 'minioadmin'
S3_BUCKET: 'speckle-server'
S3_CREATE_BUCKET: 'true'
S3_REGION: '' # optional, defaults to 'us-east-1'
FILE_SIZE_LIMIT_MB: 100
USE_FRONTEND_2: 'true'
FRONTEND_ORIGIN: 'TODO: change'
speckle-preview-service:
image: speckle/speckle-preview-service:2
restart: always
mem_limit: '1000m'
memswap_limit: '1000m'
environment:
LOG_LEVEL: 'info'
PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle'
WAIT_HOSTS: 'postgres:5432'
speckle-webhook-service:
image: speckle/speckle-webhook-service:2
restart: always
environment:
LOG_LEVEL: 'info'
PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle'
WAIT_HOSTS: 'postgres:5432'
fileimport-service:
image: speckle/speckle-fileimport-service:2
restart: always
environment:
LOG_LEVEL: 'info'
PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle'
WAIT_HOSTS: 'postgres:5432'
SPECKLE_SERVER_URL: 'http://speckle-server:3000'

Просмотреть файл

@ -1,35 +0,0 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name TODO_REPLACE_WITH_SERVER_NAME;
client_max_body_size 100m;
location / {
client_max_body_size 100m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8080;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ~* ^/(graphql|explorer|(auth/.*)|(objects/.*)|(preview/.*)|(api/.*)|(static/.*)) {
client_max_body_size 100m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:3000;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}