r-i2p-wiki

The community wiki for /r/i2p

View the Project on GitHub J-tt/r-i2p-wiki

Creating a simple static eepSite using Docker, Alpine, and i2pd

One of the most common things I hear people say about i2p is that they have trouble finding interesting content on the existing eepSites. It’s true, to an extent, as well. Most of the interesting eepSite content is, in fact, about i2p and i2p-related projects. That’s not a bad thing, but it’s a little unfortunate because it’s actually very easy to host your own content on the i2p network. In this, the first of many guides to hosting web-like services within the i2p network using i2pd and Docker.

Prerequisites

The tutorial here assumes that you’ve already got a GNU/Linux machine with Docker installed and have at least a passing familiarity with using Docker from the terminal. If you need to install Docker, go here for Debian-based Distros, here for Ubuntu-based distros, and go here for Redhat based distros. On Alpine Linux, run “apk add docker” as root.

Create a Docker network off the host

In order to provide static IP addresses for the containers you generate, you’ll need to create a separate Docker network with an explicitly defined, limited subnet.

docker network create --subnet 172.81.81.0/29 eepsite

Configuring an i2p router with a single HTTP service tunnel

There are a number of Docker containers that can be used to run i2pd, but for the purposes of building services that run on i2pd, I like to make my own. I prefer this approach because I like to use the defaults that are used by the Debian package, and the easiest way to do that is to just use the Debian package. The trade-off, of course, is a somewhat larger container.

The Dockerfile

FROM debian:sid
RUN apt-get update && apt-get dist-upgrade -y
RUN apt-get install -y gpg ca-certificates
RUN echo "deb http://repo.lngserv.ru/debian stretch main" | tee /etc/apt/sources.list.d/i2pd.list
RUN echo "deb-src http://repo.lngserv.ru/debian stretch main" | tee -a /etc/apt/sources.list.d/i2pd.list
RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv 66F6C87B98EBCFE2
RUN apt-get update && apt-get install -y i2pd
COPY i2pd.conf tunnels.conf /etc/i2pd/
CMD chown -R i2pd:i2pd /var/lib/i2pd; \
    ln -sf /usr/share/i2pd/certificates /var/lib/i2pd/certificates; \
    ln -sf /etc/i2pd/subscriptions.txt /var/lib/i2pd/subscriptions.txt; \
    su - -c "i2pd i2pd --service --loglevel=info \
      --conf=/etc/i2pd/i2pd.conf \
      --tunconf=/etc/i2pd/tunnels.conf \
      --log=/var/log/i2pd/log"; \
    sleep 5; \
    tail -f /var/log/i2pd/log

Before we build, we’ll need to create a configuration files to use for our Dockerized i2pd container. In the i2pd.conf file, you should disable the HTTP and SOCKS proxies and set the bandwidth to unlimited(“X” in the configuration file). An example i2pd.conf can be found here, it can be used for all of the forthcoming eepSite tutorials I will be writing. The other, slightly more interesting file is the tunnels.conf file.

The tunnels.conf file

[DARKHTTPD]
type = http
host = eepsite-darkhttpd
port = 8080
inbound.length = 3
outbound.length = 3
keys = darkhttpd.dat

Note that the inbound.length and outbound.length are both set to three. This is optimized to make web sites anonymous, but it will cost some speed. Selecting a different length may be an acceptable trade-off to achieve higher speed and lower latency.

Build and Run the container:

Once you’ve got your configuration files and your Dockerfile created, run the following command to build the container (Where Dockerfile.i2pd is the newly created Dockerfile):

docker build --rm -f Dockerfile.i2pd -t dockerhub_username/eepsite .

And this command to run the container:

docker run --restart=always -i -t \
    --name eepsite-i2pd \
    --network eepsite \
    --network-alias eepsite-i2pd \
    --hostname eepsite-i2pd \
    --link eepsite-darkhttpd \
    --ip 172.81.81.2 \
    -p :4567 \
    -p 127.0.0.1:7070:7070 \
    -v eepsite:/var/lib/i2pd \
    dockerhub_username/eepsite-i2pd

Configuring DarkHTTPD with your content

Now that your i2pd container is up and bootstrapping it’s connection to the i2p network, you can start configuring your static eepSite container. To do this, you’ll need a static web site to host. Either plain files or those generated by a static site generator like Jekyll will do.

The Dockerfile

FROM alpine:3.7
ARG WEBSITE=website
ENV WEBSITE=$WEBSITE
RUN apk update
RUN apk add darkhttpd
COPY $WEBSITE /var/www/localhost/htdocs/$WEBSITE
USER darkhttpd
CMD darkhttpd /var/www/localhost/htdocs/$WEBSITE --port 8080 --log stdout --no-server-id

I keep my eepSite files in the same folder as the Dockefiles, under their own directory named “website” to make things easier when passing the website’s files into the Docker build context. As you can see, the path used can be changed by passing an argument to the “docker build” command or the argument can be omitted for a default value of “website.” The Dockerfile copies the contents of “website” into a folder owned by darkhttpd, changes to the darkhttpd user, and starts the server in the directory where we copied the files for our static site.

Build and Run the container:

The full command to build the image for your static eepsite is:

docker build --rm \
    --build-arg WEBSITE=website \
    -f Dockerfile.darkhttpd -t dockerhub_username/eepsite-darkhttpd .

with the argument included. Make sure to change the argument if your website is in a different directory than “website.”

Lastly, to run the container and serve the darkhttpd static website over i2p, run the command:

docker run --restart=always -i -t -d \
    --name eepsite-darkhttpd \
    --network eepsite \
    --network-alias eepsite-darkhttpd \
    --hostname eepsite-darkhttpd \
    --ip 172.81.81.3 \
    dockerhub_username/eepsite-darkhttpd