Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
billz committed Jan 17, 2024
1 parent afb9aa8 commit 77c0440
Showing 1 changed file with 237 additions and 0 deletions.
237 changes: 237 additions & 0 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Docker support

![](https://github.com/RaspAP/raspap-docker/assets/229399/e2adcee8-2f7d-490c-8d37-7a705bb5a320){: style="width:480px"}

## Overview
As an alternative to the [Quick installer](quick.md) or [manual installation](manual.md) steps, you may also deploy RaspAP in an isolated and portable **Docker** container.

A **container** is an isolated environment for your code. This means that a container has no knowledge of your operating system, dependencies, or your files. It runs on the environment provided to you by either Docker Desktop or the Docker Engine. Containers have everything that your code needs in order to run, down to a base operating system.

Here, we'll focus on using [Docker Engine](https://docs.docker.com/engine/) to deploy and manage a containerized RaspAP application stack.

## Why a container?
Docker containers have several advantages over other methods of developing and deploying code. As a sandboxed process, containers are isolated from all other processes running on a host machine. That isolation leverages things like [kernel namespaces and cgroups](https://medium.com/@saschagrunert/demystifying-containers-part-i-kernel-space-2c53d6979504), features that have been in Linux for a long time.

A RaspAP Docker container is a runnable instance of an image. This container can be started, stopped, moved or deleted using the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/). It can be run on a local device, virtual machines or deployed to the cloud. Isolation from other containers also means that it runs its own software, binaries and so on.

## Installing Docker Engine
Since RaspAP is built for Debian-based systems, the instructions here will focus on this OS family. To get started with Docker Engine on Debian, make sure you meet the [prerequisites](#prerequisites), and then follow the [installation steps](#install-using-the-apt-repository).

### Prerequisites
To install Docker Engine, you need the 64-bit version of one of these Debian versions:

- Debian Bookworm 12 (stable)
- Debian Bullseye 11 (oldstable)

Docker Engine for Debian is compatible with x86_64 (or amd64), armhf, arm64, and ppc64le (ppc64el) architectures.

### Uninstall old versions
Before you can install Docker Engine, you need to first uninstall any conflicting packages.

Distro maintainers provide unofficial distributions of Docker packages in their repositories. You must uninstall these packages before you can install the official version of Docker Engine.

The unofficial packages to uninstall are:

- `docker.io`
- `docker-compose`
- `docker-doc`
- `podman-docker`

Run the following command to uninstall all conflicting packages:

```
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
```

!!! note "Note"
`apt-get` might report that you have none of these packages installed.

### Install using the apt repository

Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker `apt` repository. Afterward, you can install and update Docker from the repository.

1. Set up Docker's `apt` repository.

```
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
```
2. Install the Docker packages.

To install the latest version, run:
```
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
3. Verify that the installation is successful by running the `hello-world` image:
```
sudo docker run hello-world
```
This command downloads a test image and runs it in a container. When the container runs, it prints a confirmation message and exits.

!!! tip "Tip"
If the test container fails to run or you encounter any errors, refer to the [Docker Engine](https://docs.docker.com/engine/install/troubleshoot/) documentation for troubleshooting tips.

### Post-installation steps
The Docker daemon binds to a Unix socket, not a TCP port. By default it's the `root` user that owns the Unix socket, and other users can only access it using `sudo`. The Docker daemon always runs as the `root` user.

If you don't want to preface the `docker` command with `sudo`, create a Unix group called `docker` and add users to it. When the Docker daemon starts, it creates a Unix socket accessible by members of the `docker` group.

To create the `docker` group and add your user:

1. Create the docker group.
```
sudo groupadd docker
```
2. Add your user to the `docker` group.
```
sudo usermod -aG docker $USER
```
3. Log out and log back in so that your group membership is re-evaluated.

With these steps completed, you have successfully installed and started Docker Engine. We're now ready to deploy RaspAP.

## Deploying RaspAP
With Docker Engine installed, you have two ways of deploying RaspAP in a Docker container. Each of these methods are described in the sections below.

### Using Docker compose
This method lets us deploy the entire RaspAP application stack with a single command (`docker-compose up`) as well as configure things like environment variables, network settings and so on in a centralized manner. Advanced users may also use this option to define a multi-container environment of which RaspAP is one component. This may be done with the `docker-compose.yml` file.

Begin by cloning the `raspap-docker` [GitHub repository](https://github.com/RaspAP/raspap-docker) into your home directory, then change into it:

```
cd ~/
git clone https://github.com/RaspAP/raspap-docker.git
cd raspap-docker
```

For ARM devices, such as the Raspberry Pi, we must uncomment the `cgroup: host` line in the `docker-compose.yaml` file:

``` py hl_lines="9"
version: "3.8"
services:
raspap:
container_name: raspap
image: ghcr.io/raspap/raspap-docker:latest
#build: .
privileged: true
network_mode: host
cgroup: host # uncomment when using an ARM device
cap_add:
- SYS_ADMIN
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
restart: unless-stopped
```

Edit this file with `nano docker-compose.yaml`, change the line to appear as above, then use ++ctrl+o++ and press ++enter++ to save and exit the file.

!!! warning "Important"
Do not use `docker-compose` but rather `docker compose`. If the latter isn't present on your system, refer to Docker's [installation steps](https://docs.docker.com/compose/install/).

With this configuration done, execute Docker compose like so:

```
docker compose up -d
```

You should see output similar to below to indicate the progress of RaspAP's Docker image being built:

![docker-compose](https://github.com/RaspAP/raspap-docker/assets/229399/770b5c11-a995-43ca-bc92-957dd273abe0){: style="width:640px"}

During this process, a Docker image containing RaspAP's application stack will be created on your system. This build always pulls the [latest RaspAP release](https://github.com/RaspAP/raspap-webgui/releases/latest) from the main [GitHub repository](https://github.com/RaspAP/raspap-webgui/).

Behind the scenes, Docker has used the image it created to start a containerized RaspAP application stack. You may confirm this by executing the following:

```
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d7b32b8373a raspap:latest "/bin/bash -c '/home…" 2 hours ago Up 2 hours raspap
```

At this stage, the RaspAP application is running and you may access the web interface as you would normally. This will depend on the method you use to access your device, but is usually one of the following:

- `http://raspberrypi.local`
- `http://10.3.141.1`
- `http://localhost`

Take note that RaspAP and all its dependencies are wholly contained within the running Docker container. That is, the host system does not have any of the `apt` packages or application files used by RaspAP, unless you've explicitly installed them.

### Using the container registry
As an alternative to `docker compose`, described above, you may also deploy RaspAP using its hosted Docker container image. This is available as a `raspap-docker` package hosted on the [GitHub Container registry](https://ghcr.io/). With this method, a single container is defined from its base image, the environment is setup and the application is configured within the container.

Given that everything needed to deploy RaspAP is stored within this package, it isn't necessary to clone the `raspap-docker` respository. Instead, you may simply execute one of the following `docker run` commands:

1. For ARM devices, the `cgroups` must be made writable.
```
docker run --name raspap -it -d --privileged --network=host --cgroupns=host -v /sys/fs/cgroup:/sys/fs/cgroup:rw --cap-add SYS_ADMIN ghcr.io/raspap/raspap-docker:latest
```
2. For non-ARM devices, execute the following.
```
docker run --name raspap -it -d --privileged --network=host -v /sys/fs/cgroup:/sys/fs/cgroup:ro --cap-add SYS_ADMIN ghcr.io/raspap/raspap-docker:latest
```

With either of the above commands, you should see output as below followed by progress indicating the state of the various package components as they are downloaded to your system:

```
Unable to find image 'ghcr.io/raspap/raspap-docker:latest' locally
latest: Pulling from raspap/raspap-docker
```

When the container image download is completed, you may verify its operational state like so:
```
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4257b8aa3c7e ghcr.io/raspap/raspap-docker:latest "/bin/bash -c '/home…" 32 minutes ago Up 32 minutes raspap
```

At this stage, the RaspAP application stack is running and you may access the web interface as you would normally. This will depend on the method you use to access your device, but is usually one of the following:

- `http://raspberrypi.local`
- `http://10.3.141.1`
- `http://localhost`

Take note that RaspAP and all its dependencies are wholly contained within the running Docker container. That is, the host system does not have any of the `apt` packages or application files used by RaspAP, unless you've explicitly installed them.

## Tips and tricks
The following section has some general advice that users of RaspAP's Docker container have found useful. If you have a tip or trick to contribute, feel free to join our [discussions](#discussions).

### Allocating a terminal
While RaspAP's Docker container is running, you may obtain an interactive pseudo-TTY, or Linux terminal, connected to standard input. Do so by executing the following:

```
docker exec -it raspap bash
```

The above command combines the `-i` (interactive) and `-t` (tty) options together with the `raspap` named container. The `bash` command starts an interactive Bash shell within the running container. From here you can perform most of the same shell operations and commands within Docker's pseudo-TTY as you would in a regular Linux environment.

### iptables rules and NAT
With either of the above methods, `iptables` [Network Address Translation (NAT) rules](https://github.com/RaspAP/raspap-docker/blob/master/firewall-rules.sh) will automatically be applied on the Docker host. It's necessary to add these rules on the host device due to Docker's network isolation and security defaults.

If your host's network interfaces are anything other than `wlan0` and `eth0`, you may customize [these rules](https://github.com/RaspAP/raspap-docker/blob/master/firewall-rules.sh) to suit your own specific needs. After editing this file on your device, set execute permissions and run it like so:

```
sudo chmod +x firewall-rules.sh
./firewall-rules.sh
```

## Troubleshooting
The `docker logs` command shows information logged by a running container and is generally the best starting point for troubleshooting. To obtain logs for the `raspap` container, execute `docker logs raspap`.

The Docker daemon logs may also help you diagnose problems. Use the command `journalctl -xu docker.service` (or read `/var/log/syslog` or `/var/log/messages`, depending on your Linux Distribution).

For issues related to Docker Engine, refer to [Docker's troubleshooting](https://docs.docker.com/engine/install/troubleshoot/) section.

## Discussions
Questions or comments about using RaspAP's Docker container? Join the [discussions here](https://github.com/RaspAP/raspap-docker/discussions/).

0 comments on commit 77c0440

Please sign in to comment.