diff --git a/contrib/images/digitalocean/files/etc/update-motd.d/99-one-click b/contrib/images/digitalocean/files/etc/update-motd.d/99-one-click new file mode 100755 index 000000000..c9fc474ee --- /dev/null +++ b/contrib/images/digitalocean/files/etc/update-motd.d/99-one-click @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Configured as part of the DigitalOcean 1-Click Image build process + +myip=$(hostname -I | awk '{print$1}') +cat < >(tee /var/log/one_click_setup.log) 2>&1 + +ufw --force enable +printf "dokku dokku/hostname string %s" hostname | debconf-set-selections + +export DEBIAN_FRONTEND=noninteractive +export LANG=C +export LC_ALL=C + +# Install Dokku.... +for count in {1..30}; do + dpkg -i /var/lib/digitalocean/debs/*deb || /bin/true + apt-get -f install || /bin/true + + version=$(dpkg-query --showformat='${Version}' -W dokku) + if [[ -n "$version" ]]; then + ran=0 + exit 0 + else + count=$(($count + 1)) + fi + sleep 5 +done diff --git a/contrib/images/digitalocean/files/var/lib/cloud/scripts/per-once/002_enable_ssh b/contrib/images/digitalocean/files/var/lib/cloud/scripts/per-once/002_enable_ssh new file mode 100755 index 000000000..48bd764a5 --- /dev/null +++ b/contrib/images/digitalocean/files/var/lib/cloud/scripts/per-once/002_enable_ssh @@ -0,0 +1,9 @@ +#!/bin/bash +exec > >(tee /var/log/one_click_setup.log) 2>&1 + +# Remove the force command +sed -e '/Match user root/d' \ + -e '/.*ForceCommand.*droplet.*/d' \ + -i /etc/ssh/sshd_config + +systemctl restart ssh diff --git a/contrib/images/digitalocean/in_parts/011-docker b/contrib/images/digitalocean/in_parts/011-docker new file mode 100755 index 000000000..65d2955e3 --- /dev/null +++ b/contrib/images/digitalocean/in_parts/011-docker @@ -0,0 +1,43 @@ +#!/bin/bash +set -eo pipefail + +export DEBIAN_FRONTEND=noninteractive + +pkgs=(apt-transport-https + ca-certificates + curl + jq + linux-image-extra-virtual + software-properties-common +) + +echo '--> Updating apt repositories' +apt-get -qqy update + +echo "--> Installing basic dependencies: ${pkgs[*]}" +apt-get -qqy install "${pkgs[@]}" + +echo '--> Setting up docker apt repository' +curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + +cat >/etc/apt/sources.list.d/docker.list < Installing docker-ce' +apt-get -y update +apt-get -y install docker-ce docker-compose-plugin + +echo '--> Enabling docker-ce' +systemctl enable docker +systemctl start docker + +echo '--> Enabling docker live-restore' +if [[ ! -f /etc/docker/daemon.json ]]; then + echo "{}" >/etc/docker/daemon.json +fi + +config="$(jq '. + {"live-restore": true}' /etc/docker/daemon.json)" +echo "$config" >/etc/docker/daemon.json +systemctl reload docker +docker info | grep -i live diff --git a/contrib/images/digitalocean/in_parts/011-ssh-message b/contrib/images/digitalocean/in_parts/011-ssh-message new file mode 100755 index 000000000..da7a0b5df --- /dev/null +++ b/contrib/images/digitalocean/in_parts/011-ssh-message @@ -0,0 +1,9 @@ +#!/bin/bash +set -eo pipefail + +echo '--> Prevent login until after setup is complete' +# Be a bit of a dork about login in +cat >>/etc/ssh/sshd_config < Install core dependencies for dokku' +apt-get -y install "${pkgs[@]}" + +echo '--> Setting up dokku apt repository' +curl -fsSL https://packagecloud.io/dokku/dokku/gpgkey -o /etc/apt/keyrings/dokku.asc + +cat >/etc/apt/sources.list.d/dokku.list < Install dependencies for dokku from new repository' +apt-get -y clean +apt-get -y update +apt-get -y install "${dokku_pkgs[@]}" + +echo '--> Pre-cache dokku bits that are must run on boot' +apt-get -y clean +apt-get -y install --download-only "dokku=${DOKKU_VERSION}" dokku-event-listener herokuish + +mkdir -p /var/lib/digitalocean/debs +cp -au /var/cache/apt/archives/*deb /var/lib/digitalocean/debs diff --git a/contrib/images/digitalocean/in_parts/012-grub-opts b/contrib/images/digitalocean/in_parts/012-grub-opts new file mode 100755 index 000000000..72b471c77 --- /dev/null +++ b/contrib/images/digitalocean/in_parts/012-grub-opts @@ -0,0 +1,8 @@ +#!/bin/bash +set -eo pipefail + +echo '--> Update grub boot loader' +sed -e 's|GRUB_CMDLINE_LINUX="|GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1|g' \ + -i /etc/default/grub + +update-grub diff --git a/contrib/images/digitalocean/in_parts/014-docker-dns b/contrib/images/digitalocean/in_parts/014-docker-dns new file mode 100755 index 000000000..acd43f6ba --- /dev/null +++ b/contrib/images/digitalocean/in_parts/014-docker-dns @@ -0,0 +1,6 @@ +#!/bin/bash +set -eo pipefail + +echo '--> Enable Google DNS for Docker' +sed -e 's|#DOCKER_OPTS|DOCKER_OPTS|g' \ + -i /etc/default/docker diff --git a/contrib/images/digitalocean/in_parts/014-ufw-rules b/contrib/images/digitalocean/in_parts/014-ufw-rules new file mode 100755 index 000000000..5665ea827 --- /dev/null +++ b/contrib/images/digitalocean/in_parts/014-ufw-rules @@ -0,0 +1,12 @@ +#!/bin/bash +set -eo pipefail + +echo '--> Enable and configure UFW' +sed -e 's|DEFAULT_FORWARD_POLICY=.*|DEFAULT_FORWARD_POLICY="ACCEPT"|g' \ + -i /etc/default/ufw + +ufw allow ssh +ufw allow http +ufw allow https +ufw allow 2375/tcp +ufw allow 2376/tcp diff --git a/contrib/images/digitalocean/in_parts/099-application_tag b/contrib/images/digitalocean/in_parts/099-application_tag new file mode 100755 index 000000000..9bd9bff61 --- /dev/null +++ b/contrib/images/digitalocean/in_parts/099-application_tag @@ -0,0 +1,20 @@ +#!/bin/bash +set -eo pipefail + +echo '--> Write the application info' +application_version="$DOKKU_VERSION" +build_date="$(date -I)" +distro_arch="$(uname -m)" +distro_codename="$(lsb_release -sc)" +distro_release="$(lsb_release -sr)" +distro="$(lsb_release -si)" + +cat >/var/lib/digitalocean/application.info < Cleaning up' +rm -rf /tmp/* /var/tmp/* +history -c +cat /dev/null > /root/.bash_history +unset HISTFILE +apt-get -y autoremove +apt-get -y autoclean +rm -rf /var/lib/cloud/instances/* + +echo '--> Removing keys' +rm -f /root/.ssh/authorized_keys /etc/ssh/*key* + +echo '--> Clearing log files' +find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; +rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? +cat /dev/null > /var/log/lastlog; cat /dev/null > /var/log/wtmp diff --git a/contrib/images/digitalocean/packer.pkr.hcl b/contrib/images/digitalocean/packer.pkr.hcl new file mode 100644 index 000000000..21bb0f957 --- /dev/null +++ b/contrib/images/digitalocean/packer.pkr.hcl @@ -0,0 +1,96 @@ +packer { + required_plugins { + digitalocean = { + version = ">= 1.0.4" + source = "github.com/digitalocean/digitalocean" + } + } +} + +variable "source_image" { + type = string + default = "ubuntu-22-04-x64" +} + +variable "dokku_version" { + type = string +} + +source "digitalocean" "ubuntu" { + image = var.source_image + region = "nyc3" + size = "s-2vcpu-2gb" + ssh_username = "root" + snapshot_name = format("dokku-%s-%s", var.dokku_version, formatdate("YYYYMMDDhhmm", timestamp())) +} + +build { + name = "dokku" + sources = [ + "source.digitalocean.ubuntu" + ] + + provisioner "shell" { + inline = [ + "echo '--> Waiting until cloud-init is complete'", + "/usr/bin/cloud-init status --wait", + ] + } + + provisioner "file" { + source = "${path.root}/files/etc/update-motd.d/99-one-click" + destination = "/etc/update-motd.d/99-one-click" + } + + provisioner "file" { + source = "${path.root}/files/var/lib/cloud/scripts/per-once/001_setup" + destination = "/var/lib/cloud/scripts/per-once/001_setup" + } + + provisioner "file" { + source = "${path.root}/files/var/lib/cloud/scripts/per-once/002_enable_ssh" + destination = "/var/lib/cloud/scripts/per-once/002_enable_ssh" + } + + provisioner "shell" { + script = "${path.root}/in_parts/011-docker" + } + + provisioner "shell" { + script = "${path.root}/in_parts/011-ssh-message" + } + + provisioner "shell" { + environment_vars = [ + "DOKKU_VERSION=${var.dokku_version}" + ] + script = "${path.root}/in_parts/012-dokku-packages" + } + + provisioner "shell" { + script = "${path.root}/in_parts/012-grub-opts" + } + + provisioner "shell" { + script = "${path.root}/in_parts/014-docker-dns" + } + + provisioner "shell" { + script = "${path.root}/in_parts/014-ufw-rules" + } + + provisioner "shell" { + environment_vars = [ + "DOKKU_VERSION=${var.dokku_version}" + ] + script = "${path.root}/in_parts/099-application_tag" + } + + provisioner "shell" { + script = "${path.root}/in_parts/099-cleanup" + } +} + +post-processor "manifest" { + output = "digitalocean-manifest.json" +} diff --git a/contrib/packer.json b/contrib/packer.json deleted file mode 100644 index 96a60e5b2..000000000 --- a/contrib/packer.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "builders": [ - { - "type": "digitalocean", - "region": "nyc3", - "image": "ubuntu-14-04-x64" - } - ], - "provisioners": [ - { - "type": "file", - "source": "deb.mk", - "destination": "/tmp/Makefile" - }, - { - "type": "shell", - "inline": [ - "echo '--> Waiting 30 seconds for core services to be available'", - "sleep 30", - - "echo '--> Updating apt repositories'", - "sudo apt-get update -qq >/dev/null", - - "echo '--> Installing make requirement'", - "sudo apt-get -qq -y --no-install-recommends install build-essential", - - "cd /tmp && make install-from-deb", - "rm /root/.ssh/authorized_keys" - ] - } - ] -}