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.
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:
fig.yml- The main configuration for how all the docker-containers is runned.
gitlab/data- Datafolder for Gitlab
wwwhisper/data- Authentication container
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.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.
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
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.
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
Fig will make it easy to setup, and the folders will make it easy to backup.
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: firstname.lastname@example.org 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: email@example.com GITLAB_BACKUPS: daily GITLAB_RELATIVE_URL_ROOT: /git DB_TYPE: postgres DB_USER: gitlab DB_NAME: gitlabhq SMTP_USER: firstname.lastname@example.org 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:email@example.com/git/org/project.git/ WWWHISPER_PROTECT: gitstats WWWHISPER_PORT: 8080 WWWHISPER_USES_RELATIVE_PATH: "true" links: - intproxy:your.domain.com