3 minutes
Hosting a lokinet SNApp from inside a docker container
What is lokinet?
Like the tor project, lokinet is a decentralized onion router that routes (all) traffic through multiple other servers. The nice thing about it is, that it runs on a lower network layer than tor. This makes lokinet able to route traffic using any network protocol, instead of sending everything over TCP. A good example of this is SSH. If a lokinet server is hosting an SSH or VPN service, it can be accessed without the need for port forwarding.
Goal
The goal of this project is to host a website (SNApp) on lokinet using a docker image. This project keeps it simple, using only a webserver. However, anything that can be hosted, can be hosted on lokinet.
Previous work
This blogpost is based on another post in which docker and docker-compose are explained.
Building a lokinet server container
Below is a Dockerfile
that creates a container with lokinet inside.
The goal of this container is to provide a lokinet service with a permanent .loki
address.
FROM ubuntu:latest
RUN apt update
RUN apt upgrade
RUN echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections
RUN apt install curl lsb-release resolvconf dnsutils --yes
RUN curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg
RUN echo "deb https://deb.oxen.io `lsb_release -sc` main" > /etc/apt/sources.list.d/oxen.list
RUN apt update
RUN apt install lokinet --yes
RUN chown _lokinet:_loki /etc/loki -R
RUN /usr/bin/lokinet -g
RUN lokinet-bootstrap
RUN chown _lokinet:_loki /etc/loki -R
RUN echo "#!/bin/bash" > /get_loki_address.sh
RUN echo "host -t cname localhost.loki 127.3.2.1" >> /get_loki_address.sh
RUN chmod +x /get_loki_address.sh
RUN cp /etc/loki/lokinet.ini /
RUN echo "#!/bin/bash" > /start.sh
RUN echo "cp -n /lokinet.ini /etc/loki/" >> /start.sh
RUN echo "cp -n /lokinet.ini /var/lib/lokinet/" >> /start.sh
RUN echo "/usr/bin/lokinet -g" >> /start.sh
RUN echo "sed -ie 's|#keyfile=|keyfile=/var/lib/lokinet/snappkey.private|g' /etc/loki/lokinet.ini" >> /start.sh
RUN echo "sed -ie 's|#keyfile=|keyfile=/var/lib/lokinet/snappkey.private|g' /var/lib/lokinet/lokinet.ini" >> /start.sh
RUN echo "rm -rf /var/lib/lokinet/nodedb/" >> start.sh
RUN echo "rm -rf /var/lib/lokinet/profiles.dat" >> start.sh
RUN echo "/usr/bin/lokinet" >> /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]
Configuring docker-compose
Below is a docker-compose.yml
file that configures 3 services:
lokinet
: Using the aboveDockerfile
, a lokinet service will allow access to the.loki
address.tiredofit/nginx-php-fpm
: to run a webserver, which can host a simple website.containrrr/watchtower
: to automatically keep all containers up to date.
version: "3.3"
services:
lokinet:
build: lokinet
restart: always
privileged: true
tty: true
network_mode: host
tmpfs:
- /run
- /tmp
volumes:
- "./lokinet/var_lib_lokinet:/var/lib/lokinet"
- "./lokinet/etc_loki:/etc/loki"
php-nginx:
container_name: php-nginx
image: tiredofit/nginx-php-fpm
restart: always
ports:
- "80:80"
volumes:
- "./webroot:/www/html"
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: lokinet php-nginx
In the docker-compose.yml
file, the network_mode
for the lokinet container is set to host
. This will cause lokinet to have direct access to the host OS’s network. Now lokinet can talk to all other containers, as if it was running directly on the host OS.
Running the containers
When running the command docker-compose up --build
, all the configured containers will start running.
Getting the loki address
The lokinet
container contains a script that can give the current .loki
address. First, access the container using the following command:
docker exec -it <container id> /bin/bash
Then, from inside the container, execute the script:
/get_loki_address.sh
Now the .loki
address will be shown. If a client connects to this .loki
address, the website will be shown.
Debugging
If the .loki
address cannot be reached after a few minutes, try removing the ./lokinet/var_lib_lokinet/nodedb
directory and the ./lokinet/var_lib_lokinet/profiles.dat
and restart the container(s).
Conclusion
It is possible to host a website on lokinet using docker. A Dockerfile
and docker-compose.yml
were the only configuration files needed. To host other kinds of services on lokinet, just add another container in the docker-compose.yml
file and it will be hosted on lokinet.