-
Notifications
You must be signed in to change notification settings - Fork 127
feat: add digital ocean snapshot builder #2345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| # Deploy Alby Hub on DigitalOcean | ||
|
|
||
| This folder builds a DigitalOcean snapshot for Alby Hub using Packer. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Install: | ||
|
|
||
| - `packer` | ||
| - the DigitalOcean Packer plugin | ||
|
|
||
| Example install on macOS with Homebrew: | ||
|
|
||
| ```bash | ||
| brew tap hashicorp/tap | ||
| brew install hashicorp/tap/packer | ||
| packer plugins install github.com/digitalocean/digitalocean | ||
| ``` | ||
|
|
||
| You also need: | ||
|
|
||
| - a DigitalOcean API token with write access | ||
|
|
||
| ## Required Environment Variables | ||
|
|
||
| Before running the build, set: | ||
|
|
||
| - `DIGITALOCEAN_API_TOKEN` | ||
| - `ALBYHUB_VERSION` | ||
|
|
||
| Example: | ||
|
|
||
| ```bash | ||
| export DIGITALOCEAN_API_TOKEN=dop_v1_... | ||
| export ALBYHUB_VERSION=v1.22.2 | ||
| ``` | ||
|
|
||
| ## Build The Snapshot | ||
|
|
||
| From this directory, run: | ||
|
|
||
| ```bash | ||
| ./build.sh | ||
| ``` | ||
|
|
||
| ### Note | ||
|
|
||
| The build does not produce a local file you upload manually. Instead, it creates a DigitalOcean snapshot in your account. | ||
|
|
||
| At the end of a successful build, Packer should print something like: | ||
|
|
||
| ```text | ||
| A snapshot was created: 'albyhub-v1-22-2-snapshot-1778744165' | ||
| ``` | ||
|
|
||
| That snapshot is the artifact you use. | ||
|
|
||
| ## How To Deploy | ||
|
|
||
| 1. Open the DigitalOcean dashboard. | ||
| 2. Go to `Create` -> `Droplet`. | ||
| 3. Find the new snapshot under "Choose an image". | ||
| 4. Create a droplet from it. | ||
| 5. Wait for the droplet to boot. | ||
| 6. You should now see Alby Hub running at: | ||
|
|
||
| ```text | ||
| http://<droplet-ip> | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -eu | ||
|
|
||
| if [ -z "${DIGITALOCEAN_API_TOKEN:-}" ]; then | ||
| echo "DIGITALOCEAN_API_TOKEN is required" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "${ALBYHUB_VERSION:-}" ]; then | ||
| echo "ALBYHUB_VERSION is required (example: v1.22.2)" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| export DIGITALOCEAN_API_TOKEN | ||
| export ALBYHUB_VERSION | ||
| export ALBYHUB_DASH_VERSION=$(printf '%s' "$ALBYHUB_VERSION" | sed 's/\./-/g') | ||
|
|
||
| packer build template.json |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| #!/bin/sh | ||
|
|
||
| myip=$(hostname -I | awk '{print$1}') | ||
| cat <<EOF | ||
| ******************************************************************************** | ||
|
|
||
| Welcome to DigitalOcean's 1-Click Alby Hub Droplet. | ||
| To keep this Droplet secure, the UFW firewall is enabled. | ||
| All ports are BLOCKED except 22 (SSH), 80 (HTTP), and 443 (HTTPS). | ||
|
|
||
| Access Alby Hub | ||
| URL: http://${myip} | ||
|
|
||
| In a web browser, you can view: | ||
| * The Alby Hub instance on this Droplet: http://${myip} | ||
| * The Alby Hub GitHub repository for issues/feature requests: https://github.com/getAlby/hub | ||
|
|
||
| On the server: | ||
| * Alby Hub is served from Docker Compose in /opt/albyhub | ||
| * Alby Hub data is stored in /opt/albyhub/data | ||
| * The app is started automatically on first boot | ||
| * To inspect the service, run: | ||
| cd /opt/albyhub && docker compose ps | ||
| cd /opt/albyhub && docker compose logs -f | ||
|
|
||
| If the app is still starting, refresh http://${myip} after a moment. | ||
|
|
||
| For help and more information, visit https://getalby.com | ||
|
|
||
| ******************************************************************************** | ||
| To delete this message of the day: rm -rf $(readlink -f ${0}) | ||
| EOF | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| services: | ||
| albyhub: | ||
| container_name: albyhub | ||
| image: ghcr.io/getalby/hub:__ALBYHUB_VERSION__ | ||
| volumes: | ||
| - ./data:/data | ||
| ports: | ||
| - "80:8080" | ||
| environment: | ||
| WORK_DIR: /data/albyhub | ||
| restart: unless-stopped | ||
| stop_grace_period: 300s |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| #!/bin/sh | ||
|
|
||
| set -eu | ||
|
|
||
| mkdir -p /opt/albyhub/data | ||
|
|
||
| cd /opt/albyhub | ||
| docker compose up -d --quiet-pull |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #!/bin/sh | ||
|
|
||
| mkdir -p /etc/apt/keyrings | ||
|
|
||
| curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc | ||
| chmod a+r /etc/apt/keyrings/docker.asc | ||
|
|
||
| cat > /etc/apt/sources.list.d/docker.sources <<EOM | ||
| Types: deb | ||
| URIs: https://download.docker.com/linux/ubuntu | ||
| Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") | ||
| Components: stable | ||
| Architectures: $(dpkg --print-architecture) | ||
| Signed-By: /etc/apt/keyrings/docker.asc | ||
| EOM | ||
|
|
||
| apt-get -y update | ||
| apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | ||
|
|
||
| systemctl enable docker | ||
| systemctl start docker |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| #!/bin/sh | ||
|
|
||
| sed -e 's|GRUB_CMDLINE_LINUX="|GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1|g' \ | ||
| -i /etc/default/grub | ||
|
|
||
| update-grub |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #!/bin/sh | ||
|
|
||
| sed -e 's|DEFAULT_FORWARD_POLICY=.*|DEFAULT_FORWARD_POLICY="ACCEPT"|g' \ | ||
| -i /etc/default/ufw | ||
|
Comment on lines
+3
to
+4
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forward policy is overly permissive for a hardened base image. Line 3 sets routed/forwarded traffic to global 🤖 Prompt for AI Agents |
||
|
|
||
| ufw limit ssh | ||
| ufw allow http | ||
| ufw allow https | ||
| ufw --force enable | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #!/bin/sh | ||
|
|
||
| set -eu | ||
|
|
||
| mkdir -p /opt/albyhub/data | ||
|
|
||
| sed -i.bak "s|__ALBYHUB_VERSION__|${application_version}|g" /opt/albyhub/docker-compose.yml | ||
| rm -f /opt/albyhub/docker-compose.yml.bak | ||
|
|
||
| docker pull ghcr.io/getalby/hub:${application_version} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #!/bin/sh | ||
|
|
||
| ################################ | ||
| ## PART: Write the application tag | ||
| ## | ||
| ## vi: syntax=sh expandtab ts=4 | ||
|
|
||
| build_date=$(date +%Y-%m-%d) | ||
| distro="$(lsb_release -s -i)" | ||
| distro_release="$(lsb_release -s -r)" | ||
| distro_codename="$(lsb_release -s -c)" | ||
| distro_arch="$(uname -m)" | ||
|
|
||
| cat >> /var/lib/digitalocean/application.info <<EOM | ||
| application_name="${application_name}" | ||
| build_date="${build_date}" | ||
| distro="${distro}" | ||
| distro_release="${distro_release}" | ||
| distro_codename="${distro_codename}" | ||
| distro_arch="${distro_arch}" | ||
| application_version="${application_version}" | ||
| EOM |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Ensure /tmp exists and has the proper permissions before | ||
| # checking for security updates | ||
| # https://github.com/digitalocean/marketplace-partners/issues/94 | ||
| if [[ ! -d /tmp ]]; then | ||
| mkdir /tmp | ||
| fi | ||
| chmod 1777 /tmp | ||
|
|
||
| apt-get -y update | ||
| apt-get -y upgrade | ||
| rm -rf /tmp/* /var/tmp/* | ||
| history -c | ||
| cat /dev/null > /root/.bash_history | ||
| unset HISTFILE | ||
| apt-get -y autoremove | ||
| apt-get -y autoclean | ||
| find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; | ||
| rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? | ||
| rm -rf /var/lib/cloud/instances/* | ||
| rm -f /root/.ssh/authorized_keys /etc/ssh/*key* | ||
| touch /etc/ssh/revoked_keys | ||
| chmod 600 /etc/ssh/revoked_keys | ||
|
|
||
| # Securely erase the unused portion of the filesystem | ||
| GREEN='\033[0;32m' | ||
| NC='\033[0m' | ||
| printf "\n${GREEN}Writing zeros to the remaining disk space to securely | ||
| erase the unused portion of the file system. | ||
| Depending on your disk size this may take several minutes. | ||
| The secure erase will complete successfully when you see:${NC} | ||
| dd: writing to '/zerofile': No space left on device\n | ||
| Beginning secure erase now\n" | ||
|
|
||
| dd if=/dev/zero of=/zerofile & | ||
| PID=$! | ||
| while [ -d /proc/$PID ] | ||
| do | ||
| printf "." | ||
| sleep 5 | ||
| done | ||
| sync; rm /zerofile; sync | ||
| cat /dev/null > /var/log/lastlog; cat /dev/null > /var/log/wtmp | ||
| sudo apt-get --yes purge droplet-agent* | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| { | ||
| "variables": { | ||
| "do_api_token": "{{env `DIGITALOCEAN_API_TOKEN`}}", | ||
| "image_name": "albyhub-{{env `ALBYHUB_DASH_VERSION`}}-snapshot-{{timestamp}}", | ||
| "apt_packages": "apt-transport-https ca-certificates curl jq linux-image-extra-virtual software-properties-common ufw", | ||
| "application_name": "Alby Hub", | ||
| "application_version": "{{env `ALBYHUB_VERSION`}}" | ||
| }, | ||
| "sensitive-variables": ["do_api_token"], | ||
| "builders": [ | ||
| { | ||
| "type": "digitalocean", | ||
| "api_token": "{{user `do_api_token`}}", | ||
| "image": "ubuntu-24-04-x64", | ||
| "region": "fra1", | ||
|
im-adithya marked this conversation as resolved.
|
||
| "size": "s-1vcpu-1gb", | ||
| "ssh_username": "root", | ||
| "snapshot_name": "{{user `image_name`}}" | ||
| } | ||
| ], | ||
| "provisioners": [ | ||
| { | ||
| "type": "shell", | ||
| "inline": ["cloud-init status --wait"] | ||
| }, | ||
| { | ||
| "type": "file", | ||
| "source": "files/var/", | ||
| "destination": "/var/" | ||
| }, | ||
| { | ||
| "type": "file", | ||
| "source": "files/etc/", | ||
| "destination": "/etc/" | ||
| }, | ||
| { | ||
| "type": "file", | ||
| "source": "files/opt/albyhub", | ||
| "destination": "/opt/" | ||
| }, | ||
| { | ||
| "type": "shell", | ||
| "environment_vars": [ | ||
| "DEBIAN_FRONTEND=noninteractive", | ||
| "LC_ALL=C", | ||
| "LANG=en_US.UTF-8", | ||
| "LC_CTYPE=en_US.UTF-8" | ||
| ], | ||
| "inline": [ | ||
| "apt -qqy update", | ||
| "apt -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' full-upgrade", | ||
| "apt -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' install {{user `apt_packages`}}", | ||
| "apt-get -qqy clean" | ||
| ] | ||
| }, | ||
| { | ||
| "type": "shell", | ||
| "environment_vars": [ | ||
| "application_name={{user `application_name`}}", | ||
| "application_version={{user `application_version`}}", | ||
| "DEBIAN_FRONTEND=noninteractive", | ||
| "LC_ALL=C", | ||
| "LANG=en_US.UTF-8", | ||
| "LC_CTYPE=en_US.UTF-8" | ||
| ], | ||
| "scripts": [ | ||
| "scripts/010-docker.sh", | ||
| "scripts/012-grub-opts.sh", | ||
| "scripts/014-ufw-albyhub.sh", | ||
| "scripts/015-albyhub.sh", | ||
| "scripts/020-application-tag.sh", | ||
| "scripts/900-cleanup.sh" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.