init clone of @adz code from offline.place
This commit is contained in:
50
Dockerfile
Normal file
50
Dockerfile
Normal file
@ -0,0 +1,50 @@
|
||||
FROM alpine:3.19.0
|
||||
|
||||
# Paths
|
||||
ARG BIN_TARGET=/usr/local/bin
|
||||
|
||||
# Versions
|
||||
ARG WEBHOOKD_VERSION=1.17.3
|
||||
ARG HUGO_VERSION=0.122.0
|
||||
|
||||
# User
|
||||
ARG USER=webhookd
|
||||
ARG UID=1000
|
||||
|
||||
# Hugo configuration
|
||||
ENV HUGO_GIT_URL=
|
||||
ENV HUGO_WORKING_DIR=/home/$USER/website
|
||||
ENV HUGO_PUBLIC_DIR=/home/$USER/public
|
||||
|
||||
# Create non-root user
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--uid "$UID" \
|
||||
"$USER"
|
||||
|
||||
# Install dependencies
|
||||
RUN apk add --no-cache git bash curl libc6-compat go openssh-client
|
||||
|
||||
# Install webhookd for scripts we can trigger via external HTTP requests
|
||||
RUN curl -o webhookd.tgz --fail -L "https://github.com/ncarlier/webhookd/releases/download/v${WEBHOOKD_VERSION}/webhookd-linux-amd64.tgz" && \
|
||||
tar xvzf webhookd.tgz -C $BIN_TARGET
|
||||
|
||||
# Install hugo, the static page generator
|
||||
RUN curl -o hugo.tgz --fail -L "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" && \
|
||||
tar xvzf hugo.tgz -C $BIN_TARGET
|
||||
|
||||
# Clean up
|
||||
RUN rm webhookd.tgz && \
|
||||
rm hugo.tgz && \
|
||||
rm $BIN_TARGET/README.md && \
|
||||
rm $BIN_TARGET/CHANGELOG.md && \
|
||||
rm $BIN_TARGET/LICENSE
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
USER $USER
|
||||
|
||||
RUN mkdir $HUGO_PUBLIC_DIR
|
||||
|
||||
CMD [ "webhookd" ]
|
91
README.md
Normal file
91
README.md
Normal file
@ -0,0 +1,91 @@
|
||||
Parasol Static Site
|
||||
====================
|
||||
|
||||
The following starter is two container setup works well for two docker
|
||||
containers for website building and webhook listener for changes.
|
||||
|
||||
Perhaps it can be repurposed as a recipe?!
|
||||
|
||||
|
||||
|
||||
### Deploy tools with Docker
|
||||
|
||||
Docker setup to host a `hugo` static website with a `nginx` HTTP server. The website can be updated and built via an external HTTP request using `webhookd` which pulls the latest version from a .git repository.
|
||||
|
||||
## Requirements
|
||||
|
||||
* `docker`
|
||||
* `docker-compose`
|
||||
|
||||
## Deployment
|
||||
|
||||
By default the hook server listens at port `8080` while the static website is hosted on port `9090`, the `HUGO_GIT_URL` variable is set to this very repository.
|
||||
|
||||
It is recommended to use an reverse proxy to move both endpoints behind authentication, DNS, TLS etc.
|
||||
|
||||
```bash
|
||||
# Start nginx server and webhook / build server in background (-d)
|
||||
docker-compose up -d
|
||||
|
||||
# Rebuild docker files after something changed
|
||||
docker-compose up --build -d
|
||||
```
|
||||
|
||||
Do not forget to run the hook for the first time to trigger building the website. This does not happen automatically.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Trigger deploy hook via HTTP request
|
||||
curl -v -XPOST http://localhost:8080/deploy
|
||||
```
|
||||
|
||||
It is recommended to configure your webhook endpoint to be protected by HTTP Basic authentication. To call that hook generate the header like that:
|
||||
|
||||
```bash
|
||||
# Generate authentication token
|
||||
echo -n user:password | base64
|
||||
|
||||
# Trigger deploy hook via authenticated HTTP request
|
||||
curl -v XPOST -H "Authorization: Basic <insert token here>" https://hook.com/deploy
|
||||
```
|
||||
|
||||
## Private repository
|
||||
|
||||
In case you're pulling from a private repository, you need to point at the folder where the ssh keys live. For this, create an `.env` file or use the `-e` command line argument when launching docker:
|
||||
|
||||
```bash
|
||||
SSH_DIR_PATH=/home/myuser/.ssh
|
||||
```
|
||||
|
||||
You might want to adjust your configs as docker will not have write access to adjust `known_hosts` etc:
|
||||
|
||||
```
|
||||
Host codeberg.org
|
||||
StrictHostKeyChecking no
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Build docker image based on Dockerfile
|
||||
sudo docker build . -t offline
|
||||
|
||||
# Run container from this image
|
||||
sudo docker run \
|
||||
-p 8080:8080 \
|
||||
-v ./scripts:/scripts \
|
||||
-e WHD_SCRIPTS=/scripts \
|
||||
-e HUGO_GIT_URL=https://codeberg.org/offline/future \
|
||||
offline:latest
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The following starter was made by [@adz](https://adz.garden) for [offline.place](https://offline.place) with the following license:
|
||||
|
||||
```
|
||||
UNIVERSAL PUBLIC DOMAIN LICENSE
|
||||
|
||||
This software and everything else in the universe is in the public domain. Ideas are not property.
|
||||
```
|
31
docker-compose.yml
Normal file
31
docker-compose.yml
Normal file
@ -0,0 +1,31 @@
|
||||
version: '3'
|
||||
|
||||
volumes:
|
||||
html:
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:1.25.3-alpine
|
||||
container_name: offline-nginx
|
||||
restart: always
|
||||
volumes:
|
||||
- html:/usr/share/nginx/website
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
ports:
|
||||
- 9090:80
|
||||
|
||||
builder:
|
||||
build: .
|
||||
container_name: offline-builder
|
||||
depends_on:
|
||||
- nginx
|
||||
restart: always
|
||||
volumes:
|
||||
- html:/home/webhookd/public
|
||||
- ./scripts:/home/webhookd/scripts
|
||||
- ${SSH_DIR_PATH}:/home/webhookd/.ssh:ro
|
||||
environment:
|
||||
- HUGO_GIT_URL=git@codeberg.org:offline/future.git
|
||||
- WHD_SCRIPTS=/home/webhookd/scripts
|
||||
ports:
|
||||
- 8080:8080
|
15
nginx.conf
Normal file
15
nginx.conf
Normal file
@ -0,0 +1,15 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# This is set to the build volume of our builder container in the
|
||||
# `docker-compose.yml` configuration
|
||||
root /usr/share/nginx/website;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
# First attempt to serve request as file, then as directory, then try
|
||||
# to find an index.html inside, then fall back to displaying a 404
|
||||
try_files $uri $uri/index.html =404;
|
||||
}
|
||||
}
|
38
scripts/deploy.sh
Executable file
38
scripts/deploy.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "◆ Check .git repository"
|
||||
|
||||
if [ -z "$HUGO_GIT_URL" ]; then
|
||||
echo "△ HUGO_GIT_URL environment variable is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$HUGO_WORKING_DIR" ]; then
|
||||
echo "Clone .git repository for the first time"
|
||||
git clone $HUGO_GIT_URL $HUGO_WORKING_DIR
|
||||
else
|
||||
echo "All good!"
|
||||
fi
|
||||
|
||||
cd $HUGO_WORKING_DIR
|
||||
|
||||
echo "◆ Pull latest version from .git repository"
|
||||
|
||||
# Force pull everything, just in case
|
||||
git fetch --all
|
||||
git reset --hard origin/main
|
||||
|
||||
echo "◆ Build static HTML page with hugo"
|
||||
|
||||
# Start building website with hugo
|
||||
hugo
|
||||
|
||||
# Clean the public folder without affecting what's currently served by HTTP
|
||||
# server
|
||||
rm -rf $HUGO_PUBLIC_DIR/*
|
||||
cp -r $HUGO_WORKING_DIR/public/* $HUGO_PUBLIC_DIR
|
||||
rm -rf $HUGO_WORKING_DIR/public/*
|
||||
|
||||
echo "▷ Sucessfully built new website!"
|
Reference in New Issue
Block a user