Docker @ Home, an awesome way for your in-the-closet server.
Old (and unfinished) post for historical reasons
This post is very old and contains next to none relevant info anymore. Today (2021), there are plenty of solutions today. Google it.
It's a common problem among us, how and where should I put my personal running services. Lets say you want to run a dns server, gitlab, splunk, a piratepad, sickbeard, sabnzb, (and the list goes on...), all on 1 server, in your home, accessible from the outside, and use https.. And then you want backup of this, and a personal documentation, so you can replicate it later.. It will take a real some real efford to get all this running.
Personally, I have tried a lot of different self-hosting solutions for my small services, including 1 per vm, all running at the same host (but seperated with SELinux), and spreading it out over several physical servers.
So, here is what we will create;
- All your stuff behind 1 domain.
- Authentication using your mail (OAuth/Gmail support).
- Different people can access different parts of your stuff
- A solution for public access to some part of your page.
- SSO for services like Gitlab, ...
- Accessible from the outside and inside of your network.
- http redirect to https with a valid ($5 USD) certificate.
- Multiple domain support (if you want more than 1 domain on your ip)
- Dynamic ip
- Something that is easy to expand, take backup of, and rebuild if failed.
We will make this work with the use of Docker and docker-compose, and a lot of custom-created containers. Feel free to use other containers as well, or build your own based on mine. :)
Ok, so before you start, you should have 1 server running Docker.
Structure (some if it)
File and folders
Everything should run inside one folder on your server, lets call it your.domain.com
, the structure inside that is as follows:
- your.domain.com
fig.yml
- The main configuration for how all the docker-containers is runned.gitlab/data
- Datafolder for Gitlabpostgresql/data
wwwhisper/data
- Authentication containernginx-simple/nginx.conf
_front/your.domain.com_127.0.0.1:8000
Container layout
FIXME
Authentication
The authentication will be done by wwwhisper, which uses Persona to do the authentication itself. wwwhisper uses some nginx magic to make it possible to give access to example your-mail@your.domain.com
to your.domain.com/secret
. Even tho the service running with the url /secret
doesn't know about authentication.
wwwhisper will also make a http-header available with the users mail-adress when logged in. We will use this for SSO.
It also have a pretty admin-interface :)
Inside and outside access
So, this is not really a big problem. But I had some issues when I depended on only my public ip/dns from inside my LAN. With the firewall configuration I wanted, I usually ended up at my gateway web-side, not my server.
I ended up creating a tiny dnsmasq container that made sure that my inside ip to your.domain.com
was pointing to the LAN ip, not my public ip.
Certificate
You could obviously have both a self-signed, or extended validation certificate. But untill letsencrypt (free, automated, open) is here. cheapsslsecurity sells Comodo and RabidSSL certs for around $5usd/year.
I also made a container for taking care of https.
It will be the first container that is hit when accessing your server on bort 80
or 443
. It supports multiple domains, and redirecting traffic both to the same server, or another server on the same LAN.
Dynamic ip problem
You can solve this many ways. There are plenty of dns update utilities out there. Someone can even be configured on the router. I am a big fan of [DNSSimple], so I made a container to keep my ip up-to-date. I am including the configuration if you also want to use it.
Robustness
As the folder/file structure hints to, you will end up with 1 configuration file for how all your services are stitched together (the fig.yml
file), and all your actual data in separate data
folders.
Fig will make it easy to setup, and the folders will make it easy to backup.
Details
fig.yml (example)
dnsupdater:
image: xeor/dnsimple-updater
environment:
DOMAIN: your.domain.com
DOMAIN_API_TOKEN: abc123
RECORD_ID: 300000
UPDATE_TIMER: 1200
intproxy:
image: xeor/webproxy
volumes:
- /var/run/docker.sock:/docker.sock
wwwhisper:
image: xeor/wwwhisper
environment:
SITE_URL: https://your.domain.com
ADMIN_MAIL: your-mail@your.domain.com
VIRTUAL_HOST: your.domain.com
volumes:
- wwwhisper/data:/wwwhisper/sites
- /var/run/docker.sock:/docker.sock
secretUrl:
image: xeor/nginx-simple
links:
- intproxy:your.domain.com
environment:
WWWHISPER_USES_RELATIVE_PATH: "true"
WWWHISPER_PROTECT: s
HTTP_PROXY_PATH: s
volumes:
- nginx-simple/nginx.conf:/nginx.conf
nginxProxyWatcher:
image: xeor/nginx-proxy-m-watcher-nossl
volumes:
- /var/run/docker.sock:/docker.sock
nginxProxyForwarder:
image: xeor/nginx-proxy-m-forwarder
ports:
- "80:80"
volumes_from:
- nginxProxyWatcher
postgresql:
image: postgres
volumes:
- postgresql/data:/var/lib/postgresql/data
gitlabRedis:
image: redis
gitlab:
image: xeor/gitlab-sso
ports:
- "2222:22"
links:
- gitlabRedis:redisio
- postgresql:postgresql
- intproxy:your.domain.com
environment:
WWWHISPER_PROTECT: git
HTTP_PROXY_PATH: git
GITLAB_HOST: your.domain.com
GITLAB_SSH_PORT: 2222
GITLAB_EMAIL: git@your.domain.com
GITLAB_BACKUPS: daily
GITLAB_RELATIVE_URL_ROOT: /git
DB_TYPE: postgres
DB_USER: gitlab
DB_NAME: gitlabhq
SMTP_USER: git@your.domain.com
SMTP_PASS: abc123
OAUTH_GOOGLE_API_KEY: abc123.apps.googleusercontent.com
OAUTH_GOOGLE_APP_SECRET: abc123
gitstats:
image: xeor/git-stats
environment:
GIT_REPO: http://gitstats:longpw@your.domain.com/git/org/project.git/
WWWHISPER_PROTECT: gitstats
WWWHISPER_PORT: 8080
WWWHISPER_USES_RELATIVE_PATH: "true"
links:
- intproxy:your.domain.com