-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbeachbox.sh
More file actions
203 lines (179 loc) · 5.93 KB
/
Copy pathbeachbox.sh
File metadata and controls
203 lines (179 loc) · 5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/bash
# Beachbox - really simple configurator for quickest and easiest self-hosting of a web app or API on a server.
# Generates Docker Compose file and Caddyfile for ready-to-run multi-container environment.
# https://github.com/VoidMonk/beachbox
set -o nounset
set -o errexit
echo -e "Beachbox - app container definition generator (Docker Compose file and Caddyfile)\n"
# Check if Docker is installed
if ! command -v docker >/dev/null 2>&1; then
echo "Error: Docker is not installed or not in PATH."
echo "Please install Docker before running this script."
exit 1
fi
# Check if Docker Compose is available (standalone or as 'docker compose')
if docker compose version >/dev/null 2>&1; then
:
elif command -v docker-compose >/dev/null 2>&1; then
:
else
echo "Error: Docker Compose is not installed or not in PATH."
echo "Please install Docker Compose before running this script."
exit 1
fi
# Login to container registry
read -n 1 -r -p "* Login to container registry? (y/n): " CR_LOGIN_ANS
echo
if [[ "$CR_LOGIN_ANS" =~ ^[Yy]$ ]]; then
echo -e "First, create or copy existing personal token (read:packages permission) for GitHub Container Registry at https://github.com/settings/tokens \n"
read -n 1 -s -r -p "Press any key when ready to login.."
echo
docker login ghcr.io
fi
# Ask for repo, app, domain details
read -r -p "* Enter repo owner and project (as lowercase owner/project) of app container image: " OWNER_PROJECT_ANS
if [ -z "$OWNER_PROJECT_ANS" ]; then
echo 'Error: Owner/project cannot be blank'
exit 1
fi
read -r -p "* Enter a name for app container: " APP_NAME_ANS
if [ -z "$APP_NAME_ANS" ]; then
echo 'Error: Name cannot be blank'
exit 1
fi
read -r -p "* Enter SQLite database path in app container [/app/database.sqlite]: " SQLITE_DATABASE_PATH_ANS
SQLITE_DATABASE_PATH_ANS=${SQLITE_DATABASE_PATH_ANS:-/app/database.sqlite}
if [[ "$SQLITE_DATABASE_PATH_ANS" != /* ]]; then
echo 'Error: SQLite database path must be absolute'
exit 1
fi
read -r -p "* Enter one or more domain names (space separated) for app container: " ALL_DOMAINS_ANS
if [ -z "$ALL_DOMAINS_ANS" ]; then
echo 'Error: Domains cannot be blank'
exit 1
fi
if [[ $ALL_DOMAINS_ANS = *" "* ]]; then
read -r -p "* Enter the domain name (one of above) to use for Watchtower container update webhook: " WEBHOOK_DOMAIN_ANS
if [ -z "$WEBHOOK_DOMAIN_ANS" ]; then
echo 'Error: Domain cannot be blank'
exit 1
fi
else
WEBHOOK_DOMAIN_ANS=$ALL_DOMAINS_ANS
fi
# Ask for Watchtower webhook token
read -s -r -p "* Enter the auth token (strong random string) for Watchtower webhook (HTTP API): " WEBHOOK_TOKEN_ANS
if [ -z "$WEBHOOK_TOKEN_ANS" ]; then
echo 'Error: Token cannot be blank'
exit 1
fi
# Check if .env or compose.yml or Caddyfile already exist to avoid accidental overwrite
for f in .env compose.yml Caddyfile; do
if [ -e "$f" ]; then
read -n 1 -r -p "Warning: $f already exists and will be overwritten. Continue? (y/n): " OVERWRITE_ANS
echo
if [[ ! "$OVERWRITE_ANS" =~ ^[Yy]$ ]]; then
echo "Aborted by user."
exit 1
fi
fi
done
# Start generating files
echo -e "\n\nCreating .env file.."
cat << EOF > .env
OWNER_PROJECT="$OWNER_PROJECT_ANS"
APP_NAME="$APP_NAME_ANS"
ALL_DOMAINS="$ALL_DOMAINS_ANS"
WEBHOOK_DOMAIN="$WEBHOOK_DOMAIN_ANS"
WEBHOOK_TOKEN="$WEBHOOK_TOKEN_ANS"
SQLITE_DATABASE_PATH="$SQLITE_DATABASE_PATH_ANS"
EOF
echo -e "env file created!\n"
# Create the bind-mounted database file only for a new installation
if [ -e database.sqlite ]; then
if [ ! -f database.sqlite ]; then
echo 'Error: database.sqlite exists but is not a regular file'
exit 1
fi
echo -e "Existing database.sqlite preserved.\n"
else
touch database.sqlite
echo -e "database.sqlite created!\n"
fi
echo "Creating Caddyfile.."
cat << 'EOF' > Caddyfile
# Caddyfile is auto-generated (via beachbox), mounted (via Docker Compose) and auto-loaded when its container starts
# Changes for a running container can be manually applied with 'docker exec -w /etc/caddy caddy_container_id caddy reload' (get container id with 'docker ps')
{$ALL_DOMAINS} {
header -Via
@adminonly {
host {$WEBHOOK_DOMAIN}
path /package/update
}
handle @adminonly {
rewrite * /v1/update
reverse_proxy watchtower:9000
}
reverse_proxy {$APP_NAME}:8080 {
lb_try_duration 10s
lb_try_interval 1s
}
}
EOF
echo -e "Caddyfile created!\n"
echo "Creating Docker compose file.."
cat << 'EOF' > compose.yml
# Docker Compose file is auto-generated (via beachbox)
# Start all services with 'docker compose up -d'
services:
# App container
app:
image: ghcr.io/${OWNER_PROJECT}:latest
container_name: ${APP_NAME}
restart: always
volumes:
- ./database.sqlite:${SQLITE_DATABASE_PATH}
# Caddy (reverse proxy + HTTPS via HTTP challenge)
caddy:
image: caddy:latest
container_name: caddy
restart: always
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
env_file:
- ./.env
depends_on:
- app
# Watchtower (polling + HTTP API)
watchtower:
image: nickfedor/watchtower:latest
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/.docker/config.json:/config.json
environment:
- WATCHTOWER_HTTP_API_TOKEN=${WEBHOOK_TOKEN}
command: >
--cleanup
--interval 86400
--http-api-update
--http-api-port "9000"
--http-api-periodic-polls
--stop-timeout 1s
--include-stopped
--revive-stopped
--rolling-restart
volumes:
caddy_data:
caddy_config:
EOF
echo -e "Docker compose file created!\n"
echo -e "All files created. Check files, and then start all services with 'docker compose up -d' \n"
echo -e "Access your self-hosted app at its domain name!\n"