Skip to content
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

Update deploy-static-site-offen tutorial #967

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 59 additions & 78 deletions tutorials/deploy-static-site-offen-analytics/01.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ SPDX-License-Identifier: MIT
path: "/tutorials/deploy-static-site-offen-analytics"
slug: "deploy-static-site-offen-analytics"
date: "2020-10-08"
title: "How to deploy a static website with analytics using Offen and Caddy on Ubuntu 20"
title: "How to deploy a static website with analytics using Offen and Caddy on Ubuntu 24"
short_description: "This tutorial walks you through the steps needed to deploy a static website with self-hosted analytics on a VPS, using Offen Analytics and the Caddy webserver."
tags: ["Docker", "Analytics", "Website"]
author: "Frederik Ring"
Expand All @@ -26,7 +26,9 @@ If you care about your user's privacy, you should consider using self-hosted sof

---

This guide will walk you through the steps needed for deploying a static website alongside an [**Offen**][offen] analytics instance to a VPS (Virtual Private Server).
This guide will walk you through the steps needed for deploying a static website alongside an [**Offen**][offen] analytics instance to a VPS (Virtual Private Server). The tutorial assumes you are using Ubuntu 24, other distributions will work too though with some differences.

The commands in this tutorial assume you are logged in as a non-root `sudo` user. If you are logged in as root instead, you do not have to use `sudo` in front of certain commands at all.

When following this guide you will use [**Docker**][docker] and [**docker-compose**][compose] for deploying your site and Offen. [**Caddy**][caddy] is used as a lightweight server in front of your setup handling **free and automated SSL**, serving static content and routing to subdomains.

Expand All @@ -52,57 +54,42 @@ To be able to follow this tutorial correctly, you are expected to complete the f
- Setup `www.<example.com>` (your site) and `offen.<example.com>` (your Offen instance) subdomains that point to your new VPS. This can be either a `A Record` or a `CNAME Record`.
- Offen needs to be able to send transactional email in case you want to invite another user, or you have forgotten your password. To do this you will need to provide a set of SMTP credentials (host, username and password). If you don't want to figure this out right now, you can always add these at a later point. Be aware that there is **no possibility to reset your password without it** though.

## Step 1 - Install Docker and docker-compose
## Step 1 - Install Docker and the compose plugin

The easiest and recommended way of installing Docker on a new system is by using the official `apt` repository. To do so, run the following commands:
The easiest and recommended way of installing Docker and the `compose` plugin on a new system is by using the official `apt` repository. To do so, run the following commands:

```sh
# first, import and verify the repository key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
$ apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <[email protected]>
sub rsa4096 2017-02-22 [S]
# next, you can add the repository
$ add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

...output omitted...

Reading package lists... Done
# now install Docker
$ apt-get update && apt-get install docker-ce docker-ce-cli containerd.io

...output omitted...
```console
# Add Docker's official GPG key:
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl
$ sudo install -m 0755 -d /etc/apt/keyrings
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
$ sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update

$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
svenja11 marked this conversation as resolved.
Show resolved Hide resolved

# The next step is not needed if you are logged in as root
# sudo usermod -aG docker $USER

# you can now use docker version to check whether your install was successful
# depending on when you install, this might print a newer version
$ docker version --format "{{ .Client.Version }}"
19.03.12
$
```

Now, docker-compose can be installed:

```sh
$ curl -sSL "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
# use docker-compose version to check success
$ docker-compose version
docker-compose version 1.26.2, build eefe0d31
docker-py version: 4.2.2
CPython version: 3.7.7
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
27.3.1
$ docker compose version
Docker Compose version v2.29.7
$
```

---

In case you have trouble using the above instructions, refer to the official documentation on [installing Docker][install-docker] and [installing docker-compose][install-compose].
In case you have trouble using the above instructions or are using a different host OS, refer to the official documentation on [installing Docker][install-docker] and [installing compose][install-compose].

[install-docker]: https://docs.docker.com/engine/install/ubuntu/
[install-compose]: https://docs.docker.com/compose/install/
Expand All @@ -111,7 +98,7 @@ In case you have trouble using the above instructions, refer to the official doc

For the purpose of this tutorial, you can create a simple HTML file as our static site in a directory called `~/site`:

```sh
```console
$ cd && mkdir -p site
$ cat > ./site/index.html <<EOF
<!DOCTYPE html>
Expand All @@ -138,10 +125,9 @@ If you already have your static site at hand, copy it into the `site` directory.
Next, create a file called `docker-compose.yml` in your home directory and populate it with the following content:

```yml
version: '3'
services:
caddy:
image: caddy:2.1.1-alpine
image: caddy:2.8.4-alpine
ports:
- 80:80
- 443:443
Expand Down Expand Up @@ -169,7 +155,7 @@ www.example.com {
You are now ready to start serving your static site by running:

```sh
docker-compose up -d
docker compose up -d
```

Caddy will now automatically acquire a free SSL certificate from [Let's Encrypt][le] for you, so you should be able to access your site at `https://www.example.com` already.
Expand All @@ -184,15 +170,15 @@ Now that your site is up and running, you are ready to add the Offen container t

### Step 3.1 - Add an Offen container to your Docker setup

Offen is available as a lightweight Docker image (~10MB) on [Docker Hub][docker-hub]. At the time of writing, the latest version is `v0.1.5`, but it is a good idea to check the [official releases page][releases] for the latest version before you start.
Offen is available as a lightweight Docker image (~25MB) on [Docker Hub][docker-hub]. At the time of writing, the latest version is `v1.4.2`, but it is a good idea to check the [official releases page][releases] for the latest version before you start.

[docker-hub]: https://hub.docker.com/r/offen/offen
[releases]: https://github.com/offen/offen/releases

Configuration for Offen is stored in a file called `offen.env` that you can create in your home directory. Start configuring your instance by adding a random secret:

```sh
$ echo "OFFEN_SECRET=\"$(docker run --rm offen/offen:v0.1.5 secret -quiet)\"" >> offen.env
$ echo "OFFEN_SECRET=\"$(docker run --rm offen/offen:v1.4.2 secret -quiet)\"" >> offen.env
$
```

Expand All @@ -210,10 +196,9 @@ OFFEN_SMTP_SENDER="[email protected]"
Now, add an `offen` service to your `docker-compose.yml` so that it looks like this:

```yml
version: '3'
services:
caddy:
image: caddy:2.1.1-alpine
image: caddy:2.8.4-alpine
ports:
- 80:80
- 443:443
Expand All @@ -223,7 +208,7 @@ services:
- caddy_data:/data

offen:
image: offen/offen:v0.1.5
image: offen/offen:v1.4.2
volumes:
- offen_data:/var/opt/offen
- ./offen.env:/etc/offen/offen.env
Expand All @@ -242,21 +227,19 @@ offen.example.com {
}
```

You can now restart your docker-compose setup so that it also runs your Offen instance:
You can now restart your compose setup so that it also runs your Offen instance:

```sh
docker-compose down && docker-compose up -d
docker compose down && docker compose up -d
```

To check the status of your setup, use `docker-compose ps`:
To check the status of your setup, use `docker compose ps`:

```sh
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------
root_caddy_1 caddy run --config /etc/ca ... Up 2019/tcp, 0.0.0.0:443->443/tcp,
0.0.0.0:80->80/tcp
root_offen_1 offen Up 443/tcp, 80/tcp
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
user-caddy-1 caddy:2.8.4-alpine "caddy run --config …" caddy 3 minutes ago Up 3 minutes 443/tcp, 0.0.0.0:80->80/tcp, :::80->80/tcp, 2019/tcp, 443/udp
user-offen-1 offen/offen:v1.4.2 "/sbin/tini -- offen" offen About a minute ago Up About a minute (healthy) 80/tcp, 443/tcp
$
```

Expand Down Expand Up @@ -302,22 +285,22 @@ While the above setup works, there are some tweaks you likely want to apply to i
Assuming your VPS is not behind some sort of firewall yet - you can close all ports but HTTP, HTTPS and SSH in this setup - you can use [ufw][] to setup such rules for your server:

```sh
$ ufw default deny incoming
$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
$ ufw default allow outgoing
$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
$ ufw allow ssh
$ sudo ufw allow ssh
Rules updated
Rules updated (v6)
$ ufw allow http
$ sudo ufw allow http
Rules updated
Rules updated (v6)
$ ufw allow https
$ sudo ufw allow https
Rules updated
Rules updated (v6)
$ ufw --force enable
$ sudo ufw --force enable
Firewall is active and enabled on system startup
$
```
Expand All @@ -338,7 +321,7 @@ It makes sense to redirect the log output of your static site to a log file at `
Restart the `rsyslog` service:

```sh
$ systemctl restart rsyslog.service
$ sudo systemctl restart rsyslog.service
$
```

Expand All @@ -365,10 +348,9 @@ Now, you can define rotation rules for your new log files by appending the follo
As a last step, specify the `syslog` logging driver to be used in your `docker-compose.yml`:

```yml
version: '3'
services:
caddy:
image: caddy:2.1.1-alpine
image: caddy:2.8.4-alpine
ports:
- 80:80
- 443:443
Expand All @@ -382,7 +364,7 @@ services:
tag: caddy

offen:
image: offen/offen:v0.1.5
image: offen/offen:v1.4.2
volumes:
- offen_data:/var/opt/offen
- ./offen.env:/etc/offen/offen.env
Expand All @@ -399,13 +381,13 @@ volumes:
Restart your setup for the changes to have effect:

```sh
docker-compose down && docker-compose up -d
docker compose down && docker compose up -d
```

To check if your logs arrive in the desired places you can `tail` one of the log files:

```sh
$ tail -f /var/log/offen.log
$ sudo tail -f /var/log/offen.log
... continuous log output ...
```

Expand All @@ -415,15 +397,14 @@ Production systems should always have recurring backups of their data so you can

As the setup you just created stores its database file in a Docker volume, you can leverage the [docker-volume-backup][] tool to create automated backups.

[docker-volume-backup]: https://github.com/futurice/docker-volume-backup
[docker-volume-backup]: https://offen.github.io/docker-volume-backup/

Using it is as simple as adding another service to your `docker-compose.yml`:
It can be installed by adding another service to your `docker-compose.yml`:

```yml
version: '3'
services:
caddy:
image: caddy:2.1.1-alpine
image: caddy:2.8.4-alpine
ports:
- 80:80
- 443:443
Expand All @@ -433,7 +414,7 @@ services:
- caddy_data:/data

offen:
image: offen/offen:v0.1.5
image: offen/offen:v1.4.2
volumes:
- offen_data:/var/opt/offen
- ./offen.env:/etc/offen/offen.env
Expand All @@ -443,7 +424,7 @@ services:
- docker-volume-backup.stop-during-backup=true

backup:
image: futurice/docker-volume-backup:2.1.0
image: offen/docker-volume-backup:v2
volumes:
- offen_data:/backup/offen_data:ro
- ./backups:/archive
Expand Down