├── .github
└── workflows
│ └── build-docker-image.yml
├── Dockerfile
├── README.md
├── _includes
└── head.html
├── contributing
├── adding-a-page.md
├── file-structure.md
├── getting-started.md
├── index.yml
├── modifying-a-page.md
└── style-guide.md
├── guides
├── Hardware
│ └── index.yml
├── Misc
│ ├── fixing-harddrive-error-icon-in-dell-omsa.md
│ └── index.yml
├── Software
│ ├── devops-toolchains
│ │ ├── gitlab-kubernetes.md
│ │ └── index.yml
│ ├── index.yml
│ ├── reverse-proxy-servers
│ │ ├── index.yml
│ │ └── nginx.md
│ ├── virtual-private-networks
│ │ ├── index.yml
│ │ └── wireguard.md
│ └── web-hosting
│ │ ├── apache.md
│ │ ├── getting-a-free-domain-and-tls-certificates.md
│ │ ├── how-to-host-websites.md
│ │ ├── index.yml
│ │ └── nginx.md
└── index.yml
├── index.md
├── learn
├── common-terms-and-concepts.md
├── difficulty-tiers.md
├── index.yml
├── operating-systems.md
├── self-hosted-alternatives-to-popular-services-and-providers.md
├── what-are-reverse-proxies.md
└── what-is-self-hosting.md
├── retype.yml
└── static
└── favicon.png
/.github/workflows/build-docker-image.yml:
--------------------------------------------------------------------------------
1 | name: Build and Publish Docker Image
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | env:
9 | IMAGE_NAME: wiki
10 |
11 | jobs:
12 | build-and-push:
13 | runs-on: ubuntu-latest
14 | permissions:
15 | packages: write
16 | contents: read
17 |
18 | steps:
19 | - uses: actions/checkout@v3
20 | - name: Build Image
21 | run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"
22 | - name: Login to Registry
23 | run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
24 | - name: Push Image to Registry
25 | run: |
26 | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
27 | IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
28 | VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
29 | [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
30 | [ "$VERSION" == "main" ] && VERSION=latest
31 | echo IMAGE_ID=$IMAGE_ID
32 | echo VERSION=$VERSION
33 | docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
34 | docker push $IMAGE_ID:$VERSION
35 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/sdk:7.0 AS builder
2 |
3 | WORKDIR /build
4 | COPY . /build
5 |
6 | RUN dotnet tool install retypeapp --tool-path /bin
7 | RUN retype build --output .docker-build/
8 |
9 | FROM httpd:latest
10 | COPY --from=builder /build/.docker-build/ /usr/local/apache2/htdocs/
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # r/SelfHosted Wiki
2 |
3 | ## 🎉 Welcome!
4 |
5 | This is the official GitHub repository for the [r/SelfHosted](https://www.reddit.com/r/selfhosted/) wiki.
6 |
7 | ## 📖 Learning
8 |
9 | If you want to learn more about self hosting, start [here](https://wiki.r-selfhosted.com).
10 |
11 | ## 👷 Contributing
12 |
13 | If you would like to contribute please visit [this page](https://wiki.r-selfhosted.com/contributing/getting-started/).
14 |
--------------------------------------------------------------------------------
/_includes/head.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/contributing/adding-a-page.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Adding a Page
3 | icon: dot
4 | order: 80
5 | ---
6 |
7 | Adding pages with Retype is easy! Each page is its own `.md` file. You can create a new branch in your fork of the wiki if it helps you stay organized.
8 |
9 | When naming the pages filename please use dashes in place of spaces. We recommend looking at other pages in the wiki as examples.
10 |
11 | At the top of every page you should have something similar to the following. We will call this the pages meta section.
12 |
13 | ```markdown
14 | ---
15 | label: Page Title
16 | icon: dot
17 | order: 100
18 | ---
19 | ```
20 |
21 | The label will be used in the sidebar of the left of the page and at the top of your page. There are times when you may want a shorter label than the title of page. In this case you can use 'title':
22 |
23 | ```markdown
24 | ---
25 | label: Short Sidebar Text
26 | title: Longer More Descriptive Title
27 | icon: dot
28 | order: 100
29 | ---
30 | ```
31 |
32 | For pages located at the third level please set the `icon` to `dot`. An example of this our [page on WireGuard](/guides/Software/virtual-private-networks/wireguard).
33 |
34 | Below the meta section ensure you have a single newline and then begin your content. For example:
35 |
36 | ```markdown
37 | ---
38 | label: Page Title
39 | icon: dot
40 | order: 100
41 | ---
42 |
43 | Content goes here...
44 | ```
45 |
46 | See? It's easy!
47 |
48 | Retype uses Markdown syntax for text styles, formatting, hyperlinks, and all kinds of stuff. You can learn more about how to configure a page in the [Retype documentation](https://retype.com/configuration/page/). You can also learn more about the different types of components that Retype supports [here](https://retype.com/components/) - there's a lot!
49 |
50 | If you want more information on how to use Markdown syntax in content, we recommend [this page](https://retype.com/guides/formatting/) and [this one](https://daringfireball.net/projects/markdown/basics).
51 |
52 | Once you've finished your work push it to your fork and then [create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)!
53 |
--------------------------------------------------------------------------------
/contributing/file-structure.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: File Structure
3 | title: Folder and File Structure
4 | icon: dot
5 | order: 90
6 | ---
7 |
8 | Retype's file structure is very simple. For example, here is the part of the file structure of this very wiki.
9 |
10 | ```
11 | / _includes
12 | head.html
13 | / contributing
14 | adding-a-page.md
15 | file-structure.md
16 | getting-started.md
17 | modifying-a-page.md
18 | / guides
19 | / devops-toolchains
20 | gitlab-kubernetes.md
21 | index.yml
22 | / reverse-proxy-servers
23 | index.yml
24 | nginx.md
25 | / virtual-private-networks
26 | index.yml
27 | wireguard.md
28 | / webservers
29 | apache.md
30 | index.yml
31 | nginx.md
32 | getting-a-free-domain-and-tls-certificates.md
33 | how-to-host-websites.md
34 | index.yml
35 | / learn
36 | common-terms-and-concepts.md
37 | difficulty-tiers.md
38 | index.yml
39 | operating-systems.md
40 | self-hosted-alternatives-to-popular-services-and-providers.md
41 | what-are-reverse-proxies.md
42 | what-is-self-hosting.md
43 | / static
44 | index.md
45 | retype.yml
46 |
47 | ```
48 |
--------------------------------------------------------------------------------
/contributing/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Getting Started
3 | icon: dot
4 | order: 100
5 | ---
6 |
7 | This guide will show you how to setup a local environment for you to edit, create, or update content! Please note, if you wish to make a simple edit, you can always submit a quick pull request by utilizing the edit button on the file in question directly on the [GitHub repo online](https://github.com/r-selfhosted/wiki).
8 |
9 | ## Installing Retype
10 |
11 | Since we are using [Retype](https://retype.com), getting a local copy of the wiki up and running is fairly simple.
12 |
13 | ### OS Independent
14 |
15 | Since Retype is cross-platform, and OS choice is far from uniform in this community, I won't go into how to get Retype functioning on your OS of choice. Follow the [Getting Started](https://retype.com/guides/getting-started/) documentation. Once you can successfully get a version number from the command `retype version`, you're ready to continue.
16 |
17 | !!!warning
18 | At the time of writing it appears [Retype supports macOS ARM64](https://retype.com/guides/getting-started/#macos) however I've been unable to get it to work.
19 | !!!
20 |
21 | ### Fork the Repository
22 |
23 | First thing you'll want to do is create a fork of the [/r/SelfHosted wiki repository](https://github.com/r-selfhosted/wiki). Your work will be done within this fork.
24 |
25 | 4. Run the server locally with the following command:
26 | ```bash
27 | retype start --host 0.0.0.0
28 | ```
29 | You should see some output about the success/launch of the local server, similar to below:
30 | ```
31 | INPUT: /home/jimmy/Developer/github.com/r-selfhosted/wiki
32 | OUTPUT: [in-memory]
33 | Retype finished in 3.5 seconds!
34 | 13 pages built
35 | 0 errors
36 | 3 warnings
37 |
38 | View at http://127.0.0.1:5000/
39 | Press Ctrl+C to shut down
40 | ```
41 | Navigate your web browser to `http://localhost:5000` and you should see the wiki. The wiki will be rebuilt and the pages will refresh automatically in your browser when you save them in your editor. You're now ready to start adding or modifying content!
42 |
--------------------------------------------------------------------------------
/contributing/index.yml:
--------------------------------------------------------------------------------
1 | title: Contributing
2 | icon: pencil
3 |
--------------------------------------------------------------------------------
/contributing/modifying-a-page.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Modifying a Page
3 | icon: dot
4 | order: 70
5 | ---
6 |
7 | Modifying a page is even simpler than creating one! As with [creating a page](/contributing/adding-a-page/) you can create a new branch in your forked repository. Open the document you wish to change in your favorite editor, make your changes and [submit a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)!
8 |
9 | Retype uses Markdown to format and style text, amongst other things. If you want more information on how to use Markdown syntax in content, we recommend [this page](https://retype.com/guides/formatting/) and [this one](https://daringfireball.net/projects/markdown/basics).
10 |
--------------------------------------------------------------------------------
/contributing/style-guide.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Style Guide
3 | icon: dot
4 | order: 60
5 | ---
6 |
7 | Read about our best practices for writing and formatting content on the r/SelfHosted wiki!
8 |
9 | !!!
10 | Coming Soon!
11 | !!!
12 |
--------------------------------------------------------------------------------
/guides/Hardware/index.yml:
--------------------------------------------------------------------------------
1 | order: 3
2 | icon: cpu
3 |
--------------------------------------------------------------------------------
/guides/Misc/fixing-harddrive-error-icon-in-dell-omsa.md:
--------------------------------------------------------------------------------
1 | ---
2 | authors:
3 | - name: jimmybrancaccio
4 | link: https://github.com/jimmybrancaccio
5 | avatar: ":dragon_face:"
6 | label: Dell OMSA HDD Errors
7 | title: Fixing Hard Drive Error Icons in Dell OMSA
8 | icon: alert-fill
9 | order: alpha
10 | ---
11 |
12 | Difficulty: [!badge variant="success" text="Easy / Basic"]
13 |
14 | For those of us who are using non-Dell hard drives you may notice an error or warning icon in OMSA. They will also show up as uncertified which can be a bit annoying. Thankfully this is relatively easy to fix. If you've installed Dell OMSA to a Linux system you may follow these steps:
15 |
16 | 1. First stop all of the Dell services by running `srvadmin-services.sh stop`.
17 | 2. Go into the `/opt/dell/srvadmin/etc/srvadmin-storage/` directory.
18 | 3. Open the `stsvc.ini` file and locate the following text:
19 | ```ini
20 | ;nonDellCertified flag for blocking all non-dell certified alerts.
21 | NonDellCertifiedFlag=yes
22 | ```
23 |
24 | Change this text to:
25 | ```ini
26 | ;nonDellCertified flag for blocking all non-dell certified alerts.
27 | NonDellCertifiedFlag=no
28 | ```
29 | 4. Save and exit the file.
30 | 5. Start up the Dell services again using `srvadmin-services.sh start`.
31 |
--------------------------------------------------------------------------------
/guides/Misc/index.yml:
--------------------------------------------------------------------------------
1 | order: 1
2 | icon: light-bulb
3 |
--------------------------------------------------------------------------------
/guides/Software/devops-toolchains/gitlab-kubernetes.md:
--------------------------------------------------------------------------------
1 | ---
2 | authors:
3 | - name: kmorton1988
4 | link: https://github.com/kmorton1988
5 | avatar: ":dragon_face:"
6 | label: GitLab in Kubernetes
7 | icon: dot
8 | order: alpha
9 | ---
10 |
11 | Difficulty: [!badge variant="warning" text="Hard / Advanced"]
12 |
13 | ## Introduction
14 |
15 | In this article, I will describe all the steps required to setup GitLab CI/CD in Kubernetes using Kustomize.
16 | We will go through how to run GitLab on Kubernetes when you already have related resources `Postgres`, `Redis`, `MinIO`, `TLS Certificates`, etc...already available in your setup.
17 |
18 | This is a very common scenario in companies and also for self-hosting that you are already using these services in your environment and prefer to use the same for gitlab.
19 |
20 | !!!
21 | The all in one production installation may be easily performed with Helm. You can refer to the official documentation from GitLab if that is your requirement.
22 | !!!
23 |
24 |
25 | ## Requirements
26 |
27 | You will need the following in order to run GitLab.
28 |
29 | 1. Database: Postgres
30 | 2. Cache: Redis
31 | 3. Storage: MinIO is used as object storage for the container registry, GitLab backups, the Terraform storage backend, GitLab artifacts and more
32 | 4. Ingress Controller: Nginx ingress
33 | 5. Persistent Volume: Gitaly will store repository data data on disk. Your Kubernetes cluster must have a way of provisioning storage. You can install the [local path provisioner](https://github.com/rancher/local-path-provisioner) in your cluster for dynamically provisioning volumes.
34 |
35 | ### Necessary Repositories
36 | 1. [Gitlab Manifests](https://github.com/kha7iq/gitlab-k8s)
37 | 2. [SubVars App](https://github.com/kha7iq/subvars)
38 |
39 | !!! Info
40 | You can swap MinIO with any other object storage i.e S3 by changing the connection info secret.
41 | !!!
42 |
43 | ## Lets Get Started!
44 |
45 | When installing GitLab with Helm it generates the ConfigMaps after rendering the templates with parameters. We can manually change these values in ConfigMaps but its a hassle and not convenient. To make this process easy we will use a tool called [subvars](https://github.com/kha7iq/subvars) which will let us render these values from the command line. Install it by following the instructions on the [GitHub page](https://github.com/kha7iq/subvars), we will use it later.
46 |
47 | 1. Download the release with manifests from [GitHub](https://github.com/kha7iq/gitlab-k8s). Alternatively you can clone the repo. If you are cloning the repo remove the `.git` folder afterwards as it creates issues some times when rendering multiple version of the same file with `subvars`.
48 | ```bash
49 | export RELEASE_VER=1.0
50 | wget -q https://github.com/kha7iq/gitlab-k8s/archive/refs/tags/v${RELEASE_VER}.tar.gz
51 | tar -xf v${RELEASE_VER}.tar.gz
52 | cd gitlab-k8s-${RELEASE_VER}
53 | ```
54 | 2. Next set the URL for our GitLab instance in our [Kustomization file](https://github.com/kha7iq/gitlab-k8s/blob/master/ingress-nginx/kustomization.yaml). This is located within the `ingress-nginx` folder. You will find two blocks, one for `web-ui` and the second for the `registry` along with a `tls-secret-name` for HTTPS.
55 | ```yaml
56 | patch: |-
57 | - op: replace
58 | path: /spec/rules/0/host
59 | value: your-gitlab-url.example.com
60 | - op: replace
61 | path: /spec/tls/0/hosts/0
62 | value: your-gitlab-url.example.com
63 | - op: replace
64 | path: /spec/tls/0/secretName
65 | value: example-com-wildcard-secret
66 | ```
67 | 3. Next create `minio-conn-secret` containing the configuration for MinIO. It will be used for all of the enabled S3 buckets except for the GitLab backup, we will create that separately. Create a Kubernetes secret to store this information. The following is an example
68 | ```bash minio.config
69 | cat << EOF > minio.config
70 | provider: AWS
71 | region: us-east-1
72 | aws_access_key_id: 4wsd6c468c0974006d
73 | aws_secret_access_key: 5d5e6c468c0974006cdb41bc4ac2ba0d
74 | aws_signature_version: 4
75 | host: minio.example.com
76 | endpoint: "https://minio.example.com"
77 | path_style: true
78 | EOF
79 | ```
80 |
81 | ```bash
82 | kubectl create secret generic minio-conn-secret \
83 | --from-file=connection=minio.config --dry-run=client -o yaml >minio-connection-secret.yml
84 | ```
85 | 4. Now create a secret with the MinIO configuration which will be used for the GitLab backup storage. Replace the MinIO endpoint, bucket name, access key & secret key.
86 | ```bash
87 | cat << EOF > storage.config
88 | [default]
89 | access_key = be59435b326e8b0eaa
90 | secret_key = 6e0a10bd2253910e1657a21fd1690088
91 | bucket_location = us-east-1
92 | host_base = https://minio.example.com
93 | host_bucket = https://minio.example.com/gitlab-backups
94 | use_https = True
95 | default_mime_type = binary/octet-stream
96 | enable_multipart = True
97 | multipart_max_chunks = 10000
98 | multipart_chunk_size_mb = 128
99 | recursive = True
100 | recv_chunk = 65536
101 | send_chunk = 65536
102 | server_side_encryption = False
103 | signature_v2 = True
104 | socket_timeout = 300
105 | use_mime_magic = False
106 | verbosity = WARNING
107 | website_endpoint = https://minio.example.com
108 | EOF
109 | ```
110 |
111 | ```bash
112 | kubectl create secret generic storage-config --from-file=config=storage.config \
113 | --dry-run=client -o yaml > secrets/storage-config.yml
114 | ```
115 |
116 | !!!
117 | All other secrets can be used as is from the repository or you can change all of them. You may read more about this [here](https://docs.gitlab.com/charts/installation/secrets.html)
118 | !!!
119 | 5. One of the most important secrets is the `gitlab-rails-secret` secret. In case of a disaster where you have to restore GitLab from a backup you must apply the same secret to your cluster as these keys will be used to decrypt the database from backup. Make sure you keep this consistent after first install and **do not change it**.
120 | 6. It's alot of work to change database details and other parameters one by one in ConfigMaps. I have implemented some templating for this which can provide all the values of environment variables and render the manifests with `subvars`. It will output these to a destination folder and replace all the parameters defined as Go templates. The values should be self explanatory, for example, the `GITLAB_GITALY_STORAGE_SIZE` variable is used to specify how much storage is needed for Gitaly and `GITLAB_STORAGE_CLASS` is the name of storage class in your Kubernetes cluster. The following command is an example of how to use this:
121 | ```bash
122 | GITLAB_URL=gitlab.example.com \
123 | GITLAB_REGISTRY_URL=registry.example.com \
124 | GITLAB_PAGES_URL=pages.example.com \
125 | GITLAB_POSTGRES_HOST=192.168.1.90 \
126 | GITLAB_POSTGRES_PORT=5432 \
127 | GITLAB_POSTGRES_USER=gitlab \
128 | GITLAB_POSTGRES_DB_NAME=gitlabhq_production \
129 | GITLAB_REDIS_HOST=192.168.1.91:6379 \
130 | GITLAB_GITALY_STORAGE_SIZE=15Gi \
131 | GITLAB_STORAGE_CLASS=local-path \
132 | subvars dir --input gitlab-k8s-1.0 --out dirName
133 | ```
134 | Change into `dirName/gitlab-k8s-1.0` so you may review things to confirm everything is in order before applying the changes to the cluster.
135 | 7. The final step is to create the namespace `gitlab` and build with Kustomize or `kubectl`. I prefer Kustomize but you can also use `kubectl` with `-k` flag.
136 | ```bash Create the Namespace
137 | kubectl create namespace gitlab
138 | ```
139 | ```bash Apply the Final Manifest
140 | kustomize build gitlab-k8s-1.0/ | kubectl apply -f -
141 | # or following if you have already changed into directory
142 | kustomize build . | kubectl apply -f -
143 | # With kubectl
144 | kubectl apply -k gitlab-k8s-1.0/
145 | # or following if you have already changed into directory
146 | kubectl apply -k .
147 | ```
148 | 8. Head over to the endpoint you have configured for your GitLab instance, `https://gitlab.example.com` for example, and login.
149 |
150 |
151 | ## Notes
152 |
153 | * Default passwords
154 | GitLab 'root' user password configured as secret
155 | ```bash
156 | LAwGTzCebner4Kvd23UMGEOFoGAgEHYDszrsSPfAp6lCW15S4fbvrVrubWsua9PI
157 | ```
158 | Postgres password configured as secret
159 | ```bash
160 | ZDVhZDgxNWY2NmMzODAwMTliYjdkYjQxNWEwY2UwZGMK
161 | ```
162 |
--------------------------------------------------------------------------------
/guides/Software/devops-toolchains/index.yml:
--------------------------------------------------------------------------------
1 | label: DevOps Toolchains
2 | icon: tools
3 |
--------------------------------------------------------------------------------
/guides/Software/index.yml:
--------------------------------------------------------------------------------
1 | order: 2
2 | icon: browser
3 |
--------------------------------------------------------------------------------
/guides/Software/reverse-proxy-servers/index.yml:
--------------------------------------------------------------------------------
1 | label: Reverse Proxy Servers
2 | icon: server
3 |
--------------------------------------------------------------------------------
/guides/Software/reverse-proxy-servers/nginx.md:
--------------------------------------------------------------------------------
1 | ---
2 | authors:
3 | - name: kmorton1988
4 | link: https://github.com/kmorton1988
5 | avatar: ":dragon_face:"
6 | label: Nginx
7 | icon: dot
8 | order: alpha
9 | ---
10 |
11 | Difficulty: [!badge variant="success" text="Easy / Basic"]
12 |
13 | ## Prerequisites
14 |
15 | There are some prerequisites you'll need before setting up a reverse proxy server. The first thing you'll need is to have port 80 and 443 of your public IP address forwarded to the machine you want to use as a proxy. This can be configured through your router. You will also need a domain name with an A record that points to your public IP address. Finally, you'll need some services running on your local network for you to proxy.
16 |
17 | ## Nginx Installation
18 |
19 | ### Debian-based Systems
20 |
21 | 1. First, type `sudo apt update` to update the package information.
22 | 2. Then, type `sudo apt install nginx` to install Nginx.
23 | 3. Finally, allow the necessary ports using `sudo ufw allow 80/tcp` and `sudo ufw allow 443/tcp`.
24 |
25 | ### RHEL-based Systems
26 |
27 | 1. First, enable the EPEL repository using `sudo yum install epel-release`.
28 | 2. Then, type `sudo yum install nginx` to install Nginx.
29 | 3. Finally, allow the necessary ports using `sudo firewall-cmd --permanent --zone=public --add-service=http` and `sudo firewall-cmd --permanent --zone=public --add-service=https`. Type `sudo firewall-cmd --reload` to reload the firewall.
30 |
31 | Make sure Nginx starts up using `sudo systemctl start nginx`.
32 |
33 | To verify that Nginx is working properly, visit `http://yoursite.com` and you should see a Nginx welcome page similar to what's shown below. This specific page may vary depending on your distro.
34 |
35 | !!!warning FIX ME!
36 | Add screenshot of Nginx welcome page here.
37 | !!!
38 |
39 | ## Deciding on the Reverse Proxy Structure
40 |
41 | Before we actually create our reverse proxy configuration, we have to decide which local servers will handle each of the subdomains. For example, if I wanted `nextcloud.yoursite.com` to be handled by a server at `192.168.0.230`, I could add a Nginx configuration for that.
42 |
43 | Once you've decided which subdomains you'll use, add a CNAME record that maps the subdomain to your main domain name. Below is an example in Google Domains. It will vary depending on your DNS provider.
44 |
45 | !!!warning FIX ME!
46 | Add screenshot of CNAME configuration in Google Domains here.
47 | !!!
48 |
49 | ## Modifying the Nginx Configuration Files
50 |
51 | !!!
52 | Editable templates for each of the config files shown in this guide can be found at [this GitHub repo](https://github.com/Rav4s/NginX-Config-Files).
53 | !!!
54 |
55 | In order to set up the reverse proxy we have to remove the default website configuration and add our own to handle each subdomain. In this guide, we'll create two config files, one for a www/non-www domain and one for any other subdomain.
56 |
57 | ### Removing the Default Configuration
58 |
59 | To remove the default configuration, type in `cd /etc/nginx/sites-enabled/` to enter the directory and `sudo rm default` to remove the configuration file.
60 |
61 | ### Creating the First Configuration File
62 |
63 | To begin, type `cd /etc/nginx/sites-available/` to enter the `sites-available` directory. Then type `sudo vi reverse-proxy.conf` to begin editing the file.
64 |
65 | The first thing you'll want to add in this file is a server block. This server block will listen on `http://www.yoursite.com` and redirect visitors to `https://www.yoursite.com`.
66 |
67 | ```nginx
68 | server {
69 | listen 80;
70 | server_name www.yoursite.com;
71 | return 301 https://www.yoursite.com$request_uri;
72 | }
73 | ```
74 |
75 | The next thing to add is another server block, which will listen on `http://yoursite.com` and redirect visitors to `https://www.yoursite.com`
76 |
77 | ```nginx
78 | server {
79 | listen 80;
80 | server_name yoursite.com;
81 | return 301 https://www.yoursite.com$request_uri;
82 | }
83 | ```
84 |
85 | Our third server block will listen on `https://yoursite.com`, and redirect the https traffic to `https://www.yoursite.com`. This server block also contains information about the SSL certificates, which we will modify later when we obtain them.
86 |
87 | ```nginx
88 | server {
89 | listen 443;
90 | server_name yoursite.com;
91 | return 301 https://www.yoursite.com$request_uri;
92 |
93 | # SSL Configuration
94 |
95 | ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem; # managed by Certbot
96 | ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem; # managed by Certbot
97 | ssl on;
98 | ssl_session_cache builtin:1000 shared:SSL:10m;
99 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
100 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
101 | ssl_prefer_server_ciphers on;
102 |
103 | }
104 | ```
105 |
106 | This last server block will perform the actual proxying. It will listen on `https://www.yoursite.com` and proxy requests to a backend server. To do this, we can add a location block within this server block. Within the location block, we set proxy headers which nginx forwards to the backend, and we add the proxy pass and proxy redirect with the IP address and port of the backend server. The last few lines are optional, but I recommend using them because they heighten the security of your server. These lines enable HSTS, clickjacking protection, XSS protection, and disable content and MIME sniffing. Finally, we can add a line which adds the trailing slash to all URLs.
107 |
108 | ```nginx
109 | server {
110 | listen 443;
111 | server_name www.yoursite.com;
112 |
113 | # SSL Configuration
114 | ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem; # managed by Certbot
115 | ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem; # managed by Certbot
116 | ssl on;
117 | ssl_session_cache builtin:1000 shared:SSL:10m;
118 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
119 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
120 | ssl_prefer_server_ciphers on;
121 |
122 | # Set the access log location
123 | access_log /var/log/nginx/yoursite.access.log;
124 |
125 | location / {
126 |
127 | # Set the proxy headers
128 | proxy_set_header Host $host;
129 | proxy_set_header X-Real-IP $remote_addr;
130 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
131 | proxy_set_header X-Forwarded-Proto $scheme;
132 |
133 | # Configure which address the request is proxied to
134 | proxy_pass http://yourserverip:yourport/;
135 | proxy_read_timeout 90;
136 | proxy_redirect http://yourserverip:yourport https://www.yoursite.com;
137 |
138 | # Security headers
139 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
140 | add_header X-Frame-Options DENY;
141 | add_header X-Content-Type-Options nosniff;
142 | add_header X-XSS-Protection "1; mode=block";
143 | add_header Referrer-Policy "origin";
144 |
145 | # Add the trailing slash
146 | rewrite ^([^.]*[^/])$ $1/ permanent;
147 | }
148 |
149 | }
150 | ```
151 |
152 | After adding these lines, type `:wqa` to save the file and exit Vim.
153 |
154 | There's one more step before we can use this configuration. We need to symlink it to the `sites-enabled` directory. To do this, type `sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf`.
155 |
156 | ### Creating the Second Configuration File
157 |
158 | This next configuration file will serve as a template for any other subdomains you want to add to your reverse proxy. To begin making this config file, type `cd /etc/nginx/sites-available/` and then `sudo vi SUBDOMAIN.conf`, replacing `SUBDOMAIN` with the subdomain you want to configure.
159 |
160 | The first thing we'll add in this file is a server block. This server block will listen on `http://YOURSUBDOMAIN.YOURSITEDOMAIN.com` and redirect visitors to `https://YOURSUBDOMAIN.YOURSITEDOMAIN.com`.
161 |
162 | ```nginx
163 | server {
164 | listen 80;
165 | server_name YOURSUBDOMAIN.YOURSITEDOMAIN.com;
166 | return 301 https://$host$request_uri;
167 | }
168 | ```
169 |
170 | This next server block will perform the actual proxying. It will listen on `https://YOURSUBDOMAIN.YOURSITEDOMAIN.com` and proxy requests to your backend server. To do this, we'll add a location block inside the server block. Within the location block, we set proxy headers which nginx forwards to the backend, and we add the proxy pass and proxy redirect with the IP address and port of the backend server. Again, the security headers at the bottom are optional, but they will greatly improve the security of your server, so I recommend that you add them.
171 |
172 | ```nginx
173 | server {
174 | listen 443;
175 | server_name YOURSUBDOMAIN.YOURSITEDOMAIN.com;
176 |
177 | # SSL configuration
178 | ssl_certificate /etc/letsencrypt/live/YOURSUBDOMAIN.YOURSITEDOMAIN.com/fullchain.pem; # managed by Certbot
179 | ssl_certificate_key /etc/letsencrypt/live/YOURSUBDOMAIN.YOURSITEDOMAIN.com/privkey.pem; # managed by Certbot
180 | ssl on;
181 | ssl_session_cache builtin:1000 shared:SSL:10m;
182 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
183 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
184 | ssl_prefer_server_ciphers on;
185 |
186 | # Set the access log location
187 | access_log /var/log/nginx/YOURSUBDOMAIN.access.log;
188 |
189 | location / {
190 |
191 | # Set the proxy headers
192 | proxy_set_header Host $host;
193 | proxy_set_header X-Real-IP $remote_addr;
194 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
195 | proxy_set_header X-Forwarded-Proto $scheme;
196 |
197 | # Configure which address the request is proxied to
198 | proxy_pass http://YOURSERVER:YOURPORT;
199 | proxy_read_timeout 90;
200 | proxy_redirect http://YOURSERVER:YOURPORT https://YOURSUBDOMAIN.YOURSITEDOMAIN.com;
201 |
202 | # Set the security headers
203 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; #HSTS
204 | add_header X-Frame-Options DENY; #Prevents clickjacking
205 | add_header X-Content-Type-Options nosniff; #Prevents MIME sniffing
206 | add_header X-XSS-Protection "1; mode=block"; #Prevents cross-site scripting attacks
207 | add_header Referrer-Policy "origin";
208 | }
209 |
210 | }
211 | ```
212 |
213 | After adding these lines, type `:wqa` to save the file and exit Vim.
214 |
215 | Finally, to symlink this file to the `sites-enabled` directory, type `sudo ln -s /etc/nginx/sites-available/SUBDOMAIN.conf /etc/nginx/sites-enabled/SUBDOMAIN.conf`.
216 |
217 | To add any additional subdomains, simply copy the previous config file and replace the server_name with the new subdomain, along with the backend's IP address and port. Then symlink the new file to the `sites-enabled` directory.
218 |
219 | ## Restarting Nginx
220 |
221 | If you try to restart Nginx at this stage (`sudo systemctl restart nginx`), you'll probably see a few errors saying that the certificate files don't exist. In order to get Nginx to start, we'll have to use a temporary certificate.
222 |
223 | To obtain a temporary certificate and store it in the working directory, type `openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem`. Two files, `key.pem` and `certificate.pem` will be stored in your working directory.
224 |
225 | Now modify these two lines in your config files
226 |
227 | ```nginx
228 | ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem; # managed by Certbot
229 | ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem; # managed by Certbot
230 | ```
231 |
232 | so that they look like this:
233 |
234 | ```nginx
235 | ssl_certificate /path/to/certificate.pem; # managed by Certbot
236 | ssl_certificate_key /path/to/key.pem; # managed by Certbot
237 | ```
238 |
239 | Make sure to replace `/path/to/` with the path to your certificate and key files.
240 |
241 | After modifying these lines in each configuration, we can restart Nginx using `sudo systemctl restart nginx`.
242 |
243 | ## Obtaining Let's Encrypt TLS Certificates
244 |
245 | Now that Nginx has restarted with the new configuration, we can obtain TLS certificates from Let's Encrypt, a certificate authority that provides free certificates. To obtain a Let's Encrypt certificate, we can use Certbot.
246 |
247 | To install Certbot on a Debian-based distro, type `sudo apt install python3-certbot-nginx`.
248 |
249 | To install on a RHEL-based distro, type `sudo yum install certbot python3-certbot-nginx`.
250 |
251 | Then, to obtain certificates for your www and non-www domains, type `sudo certbot --nginx -d YOURSITEDOMAIN.com -d www.YOURSITEDOMAIN.com`.
252 |
253 | Certbot will ask for some information, including your email address, agreement to the Terms of Service, and whether or not you want to subscribe to their newsletter. Then Certbot will obtain your certificate.
254 |
255 | To obtain a certificate for any additional subdomains, type `sudo certbot --nginx -d sub.domain.com`, replacing `sub.domain.com` with the proper subdomain address.
256 |
257 | Certbot will automatically update the config files with the path to your new certificates, so you don't need to do that manually.
258 |
259 | Once you've obtained all the certificates you need, restart Nginx with `sudo systemctl restart nginx`.
260 |
261 | Now, visit each of your subdomains and ensure that they are accessible over https.
262 |
263 | ### Auto-Renewal Cronjob
264 |
265 | The last thing we should do is to set up the auto-renewal of our TLS certificates using `cron`. To do this, open the crontab for editing by typing `sudo crontab -e`.
266 |
267 | Then add the following line to the crontab to automatically try to renew the certificates at 1:00am every day:
268 |
269 | `0 1 * * * certbot renew --deploy-hook "systemctl restart nginx"`
270 |
271 | ## Conclusion
272 |
273 | In conclusion, a reverse proxy allows you to easily host multiple sites on the same IP address without exposing unnecessary ports. If you enjoyed this article, feel free to check out [my website](https://www.yeetpc.com), where I post articles about upgrading/restoring computers, securing your servers, and more. Thanks for reading and happy self-hosting!
274 |
--------------------------------------------------------------------------------
/guides/Software/virtual-private-networks/index.yml:
--------------------------------------------------------------------------------
1 | label: Virtual Private Networks
2 | icon: broadcast
3 |
--------------------------------------------------------------------------------
/guides/Software/virtual-private-networks/wireguard.md:
--------------------------------------------------------------------------------
1 | ---
2 | authors:
3 | - name: kmorton1988
4 | link: https://github.com/kmorton1988
5 | avatar: ":dragon_face:"
6 | label: WireGuard
7 | icon: dot
8 | order: alpha
9 | ---
10 |
11 | Difficulty: [!badge variant="primary" text="Medium / Intermediate"]
12 |
13 | WireGuard is a secure VPN tunnel that aims to provide a VPN that is easy to use, fast, and with low overhead. It is cross-platform, but it is the part of the Linux kernel by default with only the need of userland tools to configure and deploy it.
14 |
15 | ## Preface
16 |
17 | We are going to assume that we are working in a Linux environment to configure WireGuard with one server and at least one client. This guide assumes that this configuration is being performed as the root user or the superuser. Your distribution may require you to prefix commands with `sudo`.
18 |
19 | ## Installation
20 |
21 | You can find more details about installing WireGuard on your own operating system here: https://www.wireguard.com/install/. Please complete installation for both the server and client machine.
22 |
23 | ### Create the Keys
24 |
25 | The first step after installing WireGuard for your distribution is to generate keys. We should do this for the server first, but this will be the same for clients as well.
26 |
27 | ```bash
28 | cd /etc/wireguard && wg genkey | tee private.key | wg pubkey > public.key
29 | ```
30 |
31 | You should now have `public.key` and `private.key` files in `/etc/wireguard/`.
32 |
33 | It is important to make sure your private key **stays private**. No private key should ever leave the machine it was generated on. The client and server will only need the public keys for each other. If you are using the private keys for a client on a server, or vice-versa, you are doing something wrong.
34 |
35 | ### Server Configuration
36 |
37 | Since this is the server, we need to make a new configuration file for it in `/etc/wireguard/`. We will call it `wg0.conf`. The full path should end up being `/etc/wireguard/wg0.conf`. Please use your own private key where appropriate. You can view the contents of a text file from the command line with `cat` (e.g. `cat /path/to/text.file`).
38 |
39 | You can change the _Address_ field to use a different address space (e.g. `192.168.x.1`) if you wish. If your server or clients are already using private IP space on a LAN, **use something different**.
40 |
41 | ```
42 | [Interface]
43 | ## Private IP address for the server to use
44 | Address = 10.0.0.1/24
45 | ## When WireGuard is shutdown, flushes current running configuration to disk. Any changes made to the configuration before shutdown will be forgotten
46 | SaveConfig = true
47 | ## The port WireGuard will listen on for incoming connections. 51194 is the default
48 | ListenPort = 51194
49 | ## The server's private key. Not a file path, use the key file contents
50 | PrivateKey = PRIVATEKEY
51 | ```
52 |
53 | After this is done we should be able to start the VPN tunnel and make sure it's enabled.
54 |
55 | !!!
56 | Please consult the documentation for your Linux distribution for enabling/starting services. This guide is using system tools installed on Debian and Debian-based distributions.
57 | !!!
58 |
59 |
60 | ```bash
61 | systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
62 | ```
63 |
64 | That should be it for the server portion.
65 |
66 | ### Client Configuration
67 |
68 | The client will need keys too. Use the same procedure to [make keys](#create-the-keys) for the client as we've done for the server. Once that is done we need to create a client configuration. Let's make `wg0-client.conf` in `/etc/wireguard/`. The full path should be `/etc/wireguard/wg0-client.conf`. You will need to choose a unique IP address for the client. Everything should be the same as the server's private IP except the last octet.
69 |
70 | ```
71 | [Interface]
72 | ## This Desktop/client's private key ##
73 | PrivateKey = CLIENTPRIVATEKEY
74 |
75 | ## Client IP address ##
76 | Address = 10.0.0.CLIENTOCTET/32
77 |
78 | [Peer]
79 | ## WireGuard server public key ##
80 | PublicKey = WGSERVERPUBLICKEY
81 |
82 | ## set ACL ##
83 | ## Uncomment the next line to use VPN for VPN connections only
84 | # AllowedIPs = 10.0.0.0/24
85 | ## If you want to use the VPN for ALL network traffic, uncomment the following line instead
86 | # AllowedIPs = 0.0.0.0/0
87 |
88 | ## Your WireGuard server's PUBLIC IPv4/IPv6 address and port ##
89 | Endpoint = WGSERVERPUBLICIP:51194
90 |
91 | ## Key connection alive ##
92 | PersistentKeepalive = 20
93 | ```
94 |
95 | This should be all you need for configuring the client-end connection. We will need the private client IP you've chosen and the public client key in a bit. As with the server, we need to enable the WireGuard client service. We don't start it yet because the server still doesn't know about this client.
96 |
97 | ```bash
98 | systemctl enable wg-quick@wg0-client
99 | ```
100 |
101 |
102 | ### Configuring the Client as a Peer
103 |
104 | Back on your server, we need to add the client so the server will accept the client connection. This is where your client private IP address and public key will be used. Run the following command on the WireGuard server to add the client:
105 |
106 | ```bash
107 | wg set wg0 peer CLIENTPUBLICKEY allowed-ips CLIENTPRIVATEIP/32
108 | ```
109 |
110 | You should not need to restart the WireGuard service. Lets start the WireGuard client service on the client:
111 |
112 | ```bash
113 | systemctl start wg-quick@wg0-client
114 | ```
115 |
116 | To check that it works, ping the WireGuard server on its private IP.
117 |
118 | ```bash
119 | $ ping -c 1 10.0.0.1
120 | PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
121 | 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.071 ms
122 |
123 | --- 10.0.0.1 ping statistics ---
124 | 1 packets transmitted, 1 received, 0% packet loss, time 0ms
125 | rtt min/avg/max/mdev = 0.071/0.071/0.071/0.000 ms
126 | ```
127 |
128 | If you consider your client Internet connection stable, this next step may not be necessary. You can consider yourself done.
129 |
130 | ## WireGuard Watchdog (OPTIONAL)
131 |
132 | Next we are going to setup a small cronjob that will ping the WireGuard server on its private IP to make sure the connection is still intact. If the connection fails, the tunnel will be restarted.
133 |
134 | You can put this script anywhere, but I've opted to put it in `/usr/local/scripts/`.
135 |
136 | ```bash
137 | mkdir /usr/local/scripts
138 | ```
139 |
140 | Now for the script. I use `wg-watch.sh`. Let's assume you are going to use ``/usr/local/scripts/wg-watch.sh` for the full file path.
141 |
142 | ```bash
143 | #!/usr/bin/bash
144 | # Modified from https://mullvad.net/en/help/running-wireguard-router/
145 | # ping VPN gateway to test for connection
146 | # if no contact, restart!
147 |
148 | PING=/usr/bin/ping
149 |
150 | ## DEBIAN
151 | SERVICE=/usr/sbin/service
152 |
153 | tries=0
154 | while [[ $tries -lt 3 ]]
155 | do
156 | if $PING -c 1 10.0.0.1
157 | then
158 | echo "wg works"
159 | exit 0
160 | fi
161 | echo "wg fail"
162 | tries=$((tries+1))
163 | done
164 | echo "wg failed 3 times - restarting tunnel"
165 |
166 | ## DEBIAN
167 | $SERVICE wg-quick@wg0-client restart
168 | ```
169 |
170 | Please make sure the paths to certain binaries are congruent with your own system. If they are not, the script will fail. Some distributions put them in different places (e.g. `/bin/bash` instead of `/usr/bin/bash`). If you are not sure where they are, you can do `which binaryname` that should report the full path to the binary.
171 |
172 | ```bash
173 | $ which bash
174 | /usr/bin/bash
175 | ```
176 |
177 | Make the script executable:
178 |
179 | ```bash
180 | chmod +x /usr/local/scripts/wg-watch.sh
181 | ```
182 |
183 | Once we have that done, we need to schedule it. I choose to schedule this every five minutes, but if you want to wait longer that is up to you. Schedule the script to run on a regular basis using `cron`. You can find out more about `cron` [here](https://opensource.com/article/17/11/how-use-cron-linux).
184 |
185 | We're going to use `crontab` to add this script to the list of jobs.
186 |
187 | ```bash
188 | crontab -e
189 | ```
190 |
191 | Once the crontab editor is open, add this:
192 |
193 | ```
194 | */5 * * * * /usr/local/scripts/wg-watch.sh
195 | ```
196 |
197 | Write and close the file. Crontab should confirm that it has been updated. You should now be setup with a WireGuard VPN tunnel between a server and a client along with a script to bring the tunnel back up if it fails!
198 |
--------------------------------------------------------------------------------
/guides/Software/web-hosting/apache.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Apache
3 | icon: dot
4 | order: alpha
5 | ---
6 |
7 | !!!
8 | Coming soon!
9 | !!!
10 |
--------------------------------------------------------------------------------
/guides/Software/web-hosting/getting-a-free-domain-and-tls-certificates.md:
--------------------------------------------------------------------------------
1 | ---
2 | authors:
3 | - name: ioqy
4 | link: https://github.com/ioqy
5 | avatar: ":dragon_face:"
6 | label: Free Domain w/ TLS
7 | title: Getting a Free Domain with a TLS Certificate
8 | icon: dot
9 | order: alpha
10 | ---
11 |
12 | Difficulty: [!badge variant="success" text="Easy / Basic"]
13 |
14 | With this tutorial you will get a valid TLS certificate from Let's Encrypt without having to open any incoming ports. You can use the certificate to enable HTTPS with your reverse proxy (Apache, Nginx, Caddy, etc...) or other self hosted services. Since this only uses `acme.sh` which is a shell script it should work on everything that runs Linux.
15 |
16 | The tutorial was written for and tested with Duck DNS and deSEC, but you can (in theory, because I did sadly encounter a few bugs/incompatibilities here and there) use [every one of the 150+ DNS providers supported by `acme.sh` (there is also a second page at the end)](https://github.com/acmesh-official/acme.sh/wiki/dnsapi). If you want to use a wildcard certificate I would recommend deSEC because Duck DNS currently has a bug/incompatibility with `acme.sh`.
17 |
18 | If you want to use another DNS provider you can skip right to step [Install `acme.sh`](#install-acmesh). You will need to change the parameter `--dns YOURDNS` in all the below commands and set the necessary variables yourself according to the [acme.sh DNS API wiki](https://github.com/acmesh-official/acme.sh/wiki/dnsapi).
19 |
20 |
21 | ## Select a DynDNS Provider
22 |
23 | ### Duck DNS
24 |
25 | 1. Go to https://www.duckdns.org/ and sign in with one of the providers at the top.
26 | 2. After your are successfully logged in, enter the sub domain you want and press _add domain_. This domain name (including the `.duckdns.org` part) needs to be replaced in all commands where you see `$YOURDOMAIN`.
27 | 3. Enter either:
28 | - The local IP address of your server if your server is not accessible from the internet or the public IP address of your server if your server is accessible from the internet in the _current ip_ field and press _update ip_.
29 |
30 | The choosen sub domain name will be the one that the server/service needs to be addressed when using the certificate, for it to be valid. Since you set the sub domain to the IP address of your server it should be reachable when the sub domain name get's translated by any DNS. Depending on your home router you might need add an exception of the sub domain name to the DNS rebind protection.
31 | 4. Keep the website open, because you need it in a later step.
32 |
33 | ### deSEC
34 |
35 | 1. Go to https://desec.io/signup and create a new account. It doesn't matter what you choose for _Do you want to set up a domain right away?_ because you can add a domain afterwards.
36 | 2. Log into your deSEC account.
37 | 3. If you havent't added a domain during signup, click on the _+_ button on the right and enter the subdomain you want and add _.dedyn.io_ after your subdomain so it looks like _example.dedyn.io_. If the sub domain was added successfull there will be a popup with setup instructions which you will not need and can be closed. This domain name needs to be replaced in all commands where you see `$YOURDOMAIN`.
38 | 4. Optionally add a DNS record. Click onto your sub domain name and then the _+_ button on the right. A popup with _Create New Record Set_ will show up. Choose the _Record Set Type_ value _A_ and enter either:
39 | - The local IP address of your server if your server is not accessible from the internet or the public IP address of your server if your server is accessible from the internet in the 'IPv4 address' field and press _Save_.
40 |
41 | The choosen sub domain name will be the one that the server/service needs to be addressed when using the certificate, for it to be valid. Since you set the sub domain to the IP address of your server it should be reachable when the sub domain name get's translated by any DNS. Depending on your home router you might need add an exception of the sub domain name to the DNS rebind protection.
42 | 5. At the top menu change to _TOKEN MANAGEMENT_ and press the _+_ button on the right. A popup with _Generate New Token_ will show up. Enter a token name of your choosing (the name doesn't matter and is only for the convenience of knowing what the token is used for). Press _save_.
43 |
44 | Now there will be a green bar at in the popup saying:
45 | ```
46 | Your new token's secret value is: aaaabbbbccccddddeeeeffffgggg
47 | It is only displayed once.
48 | ```
49 | Copy the secret token value into a text editor because you'll need it later. Don't worry, you can always come back to this step and generate a new token in case you lose the secret token value.
50 |
51 |
52 | ## Install `acme.sh`
53 |
54 | 1. Run the following command on your server to install `acme.sh`:
55 | ```bash
56 | curl https://get.acme.sh | sh -s
57 | ```
58 |
59 | If you wish to receive an expiration notification email before your certificates expires you can insert your email address and install acme.sh with the following command:
60 |
61 | ```bash
62 | curl https://get.acme.sh | sh -s email=my@example.com
63 | ```
64 |
65 | You can find more information on expiration emails here: https://letsencrypt.org/docs/expiration-emails/
66 |
67 | 2. Run the command - `exec $SHELL`. This will pick up on anything new which the installation has installed.
68 |
69 |
70 | ## Configure `acme.sh`
71 |
72 | 1. First enable auto updates. This allows the script to keep itself updated:
73 | ```bash
74 | acme.sh --upgrade --auto-upgrade
75 | ```
76 | 2. Next change the default CA (Certificate Authority) to Let's Encrypt (see explanation in the remarks):
77 | ```bash
78 | acme.sh --set-default-ca --server letsencrypt
79 | ```
80 | 3. Take the token from your DynDNS provider and insert it into either one of the following commands between the quotation marks:
81 | ```bash Duck DNS
82 | export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
83 | ```
84 | ```bash deSEC
85 | export DEDYN_TOKEN="aaaabbbbccccddddeeeeffffgggg"
86 | ```
87 |
88 |
89 | ## Issuing a TLS Certificate
90 |
91 | In the following commands you need to replace `$YOURDNS` with either _dns_duckdns_ for Duck DNS or _dns_desec_ if you chose deSEC. Insert your registered sub domain in the following command to issue your first certificate:
92 |
93 | ```bash
94 | acme.sh --issue --dns $YOURDNS --domain $YOURDOMAIN
95 | ```
96 |
97 | If you have registered more domains you can add them as alternative names to the certificate by adding more `--domain $YOURDOMAIN` at the end, for example:
98 |
99 | ```sh
100 | acme.sh --issue --dns $YOURDNS --domain subdomain.example.com --domain subdomain-nextcloud.example.com --domain subdomain-vaultwarden.example.com
101 | ```
102 |
103 | The first given `--domain` of the `--issue` command will be the primary domain of the certificate and the only one domain you will need to state when running other `acme.sh` commands. I would recommend keeping the primary domain the same when adding/removing other subdomains.
104 |
105 |
106 | ## 4. Installing The Certificate to a Target Directory
107 |
108 | After the certificate is issued, `acme.sh` needs to copy the certificate to a target directory. The target directory (or at least filename) must be unique. Your `reloadcmd` command must also be for this specific certificate.
109 |
110 | The following command sets the variable `CERTIFICATE_DIRECTORY` (which is just for ease of use in the next command) with a directory of your choosing as well as creates the directory.
111 |
112 | ```bash
113 | CERTIFICATE_DIRECTORY=$HOME/certificates
114 | mkdir -p "$CERTIFICATE_DIRECTORY"
115 | ```
116 |
117 | Now tell `acme.sh` where and under which filenames it should copy the certificate (`--cert-file` and `--fullchain-file`) and key (`--key-file`) files and which command (`--reloadcmd`) it should run to restart your reverse proxy or other service.
118 |
119 | ```bash
120 | acme.sh --install-cert --domain $YOURDOMAIN --cert-file "$CERTIFICATE_DIRECTORY/certificate.pem" --fullchain-file "$CERTIFICATE_DIRECTORY/fullchain.pem" --key-file "$CERTIFICATE_DIRECTORY/key.pem" --reloadcmd "sudo service apache2 force-reload"
121 | ```
122 |
123 | In the above example we've set the directory to store the certificate files as a `certificates` directory within your home directory and to run the command `sudo service apache2 force-reload` once the certificate has been obtained.
124 |
125 | ## Automatic Renewal
126 |
127 | Certificates from Let's Encrypt are only valid for 90 days. Because of this `acme.sh` will create a daily cronjob that runs at a random time. When the task is run it will:
128 | * Renew every certificate after 60 days.
129 | * Copy the certificate and key files to their previously configured destination directory.
130 | * Run the `reloadcmd` command as previously configured.
131 |
132 |
133 | ## Notes
134 |
135 | 1. **How can I add more domain names to my certificate?**
136 | Run the command from [Issuing a TLS Certificate](#issuing-a-tls-certificate) again with all domain names (old and new) that you want in your certificate. As long as the primary domain stays the same it is not necessary to install the certificate again.
137 |
138 | After changing the domain names with the `--issue` parameter, it will not copy the new certificate to it's destination or run the `--reloadcmd` that was set with the `--install-cert` command. You will either have to do it by yourself or run the `--install-cert` command again (with all the same parameters as before) or copy the files manually from the `.acme.sh` directory in your home directory. If you don't know the parameters from last time you can look them up in the info about the certificate (see next point).
139 | 2. **Show configuration of `acme.sh`:**
140 | ```bash
141 | acme.sh --info
142 | ```
143 | 3. **Show configuration of a certificate:**
144 | ```bash
145 | acme.sh --info -d $YOURDOMAIN
146 | ```
147 | 4. **List all certificates issued with `acme.sh`:**
148 | ```bash
149 | acme.sh --list
150 | ```
151 | 5. **Remove a certificate from `acme.sh`:**
152 | ```bash
153 | acme.sh --remove -d YOURDOMAIN
154 | ```
155 | 6. **Why change the default CA to Let's Encrypt?**
156 | I did encounter bugs with the default CA of acme.sh (ZeroSSL) which where gone once I switched to Let's Encrypt.
157 |
158 | 7. **How to create a wildcard certificate:**
159 | Add `*.YOURSUBDOMAIN.YOURSITEDOMAIN.com` as an alternative domain name to your certificate:
160 | ```bash
161 | acme.sh --issue --dns dns_... --domain YOURSUBDOMAIN.YOURSITEDOMAIN.com --domain *.YOURSUBDOMAIN.YOURSITEDOMAIN.com
162 | ```
163 | In theory it works with Duck DNS, but if you add the wildcard as an alternative name there sadly is a bug or incompatibility (depending on who you want to blame) and acme.sh runs into an infitie loop. It works if you only use the wildcard domain as the primary domain name. But with only a wildcard in the certificate I don't know if this certificate will play nice with all devices, browsers and applications.
164 |
165 | If you want to use acme.sh and create a wildcard certificate desec.io works as a DNS provider.
166 |
167 | 8. **How to create a staging certificate for testing:**
168 | Add the `--test` parameter to the `--issue` command to create test (or staging) certificates which are not valid but are better if you are just testing things. The certificate will stay in the staging environment until you renew it without the `--test` parameter:
169 | ```bash
170 | acme.sh --renew -d YOURSUBDOMAIN.YOURSITEDOMAIN.com
171 | ```
172 |
173 | More on that topic here: https://letsencrypt.org/docs/staging-environment/
174 |
175 | 9. **Uninstall `acme.sh`:**
176 | ```bash
177 | acme.sh --uninstall
178 | ```
179 |
180 | and delete the `.acme.sh` directory in your home directory.
181 |
--------------------------------------------------------------------------------
/guides/Software/web-hosting/how-to-host-websites.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: How To Host Websites
3 | icon: dot
4 | order: alpha
5 | ---
6 |
7 | Difficulty: [!badge variant="primary" text="Medium / Intermediate"]
8 |
9 | This guide assumes you are able to serve content on port 80 (HTTP) and port 443 (HTTPS). It also assumes you have your own domain name and have access to create and/or update DNS records for it. For this guide we will be using Ubuntu Linux (22.04).
10 |
11 | ## Choosing a Server
12 |
13 | A server can be just about anything. You may use an old computer that isn't being uses anymore, a cheap small form factor (SFF) machine from an online store, a custom built machine that has server grade or consumer level parts, or even a Raspberry Pi!
14 |
15 | Once you've selected your hardware you'll want to select an operating system. The most popular operating system self-hosters use is Linux (commonly Ubuntu). Linux comes in many flavors to meet many needs. It is freely available and free to modify. Windows Server is usually not chosen due to licensing costs.
16 |
17 | ## Setting Up DNS
18 |
19 | Get the IP address of the machine you will use. If you're serving your content locally (ex. your home network), then the local IP address of the machine will not work (e.g. `192.168.x.x` or `10.1.3.10`). You will need to obtain your public IP address. You can find your public IP address on your router status page or by going to https://ifconfig.me/. Use that IP address when creating an A record at your DNS host.
20 |
21 | ## Network Configuration
22 |
23 | As noted above you will need to ensure port `80` and `443` are open and able to be used for your web server. If you need to perform port forwarding we recommend reviewing your routers documentation. It's possible your ISP will block common ports used for Internet traffic such as 80 (HTTP), 443 (HTTPS), 21 (FTP), and 25 (SMTP). Some ISPs will have no problem unblocking some of these ports, but it should not be expected that they will cooperate.
24 |
25 | !!!warning
26 | There may be clauses in your service agreement stating that hosting services from your home Internet connection is prohibited. While ISPs rarely take action against customers if they are found in violation of this rule, there are legitimate reasons for having such clause.
27 | !!!
28 |
29 | ## Hosting a Website with Apache
30 |
31 | 1. Login to your server via SSH.
32 |
33 | ## Hosting a Website with Nginx
34 |
35 |
--------------------------------------------------------------------------------
/guides/Software/web-hosting/index.yml:
--------------------------------------------------------------------------------
1 | label: Web Hosting
2 | icon: globe
3 |
--------------------------------------------------------------------------------
/guides/Software/web-hosting/nginx.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Nginx
3 | icon: dot
4 | order: alpha
5 | ---
6 |
7 | !!!
8 | Coming soon!
9 | !!!
10 |
--------------------------------------------------------------------------------
/guides/index.yml:
--------------------------------------------------------------------------------
1 | order: 1
2 | icon: book
3 |
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "r/SelfHosted Wiki"
3 | label: Home
4 | icon: home
5 | ---
6 |
7 | We welcome you to explore the pages here and familiarize yourself with the layout of the wiki. If you have any suggestions on how the wiki can be better or alternative oganization methods, feedback or questions in general about the wiki please create an issue [here](https://github.com/r-selfhosted/wiki/issues) or open a [pull request](https://github.com/r-selfhosted/wiki)!
8 |
9 | ## Official Pages
10 |
11 | The following are websites and pages which are considered official and supported by r/SelfHosted.
12 |
13 | - [Reddit Subreddit](https://reddit.com/r/selfhosted)
14 | - [Discord](https://discord.gg/UrZKzYZfcS)
15 | - [Matrix](https://matrix.to/#/#selfhosted:selfhosted.chat)
16 | - [Element](https://app.element.io/#/room/#selfhosted:selfhosted.chat) - Matrix Web Client
17 | - [Mastodon](https://selfhosted.chat)
18 | - [Discourse Forums](https://forum.r-selfhosted.com/)
19 |
20 | ## Getting Started
21 |
22 | The following articles are great places to get started:
23 |
24 | - [What Is Self-Hosting?](learn/what-is-self-hosting)
25 | - [What are Reverse Proxies?](learn/what-are-reverse-proxies)
26 | - [Self-Hosted Alternatives to Popular Services and Providers](learn/self-hosted-alternatives-to-popular-services-and-providers)
27 | - [How to Host Websites](guides/software/web-hosting/how-to-host-websites)
28 |
--------------------------------------------------------------------------------
/learn/common-terms-and-concepts.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Common Terms and Concepts
3 | meta:
4 | title: Explanations and Definitions for Common Terms and Concepts Related to Self-Hosting
5 | icon: project-roadmap
6 | order: alpha
7 | ---
8 |
9 | ## Servers
10 |
11 | Servers are machines whose purpose is to provide a service or content over a network. They are typically administered remotely and only connect physically to power and a network. They "serve" content or services using software daemons. Bare metal servers are not virtualized. Any service or content they offer is configured on the host system. They are not new *per-se*, but with the introduction of containerization and virtualization, the phrase has been coined to differentiate the old-school server tradition from newer techniques. Their natural habitat is the datacenter, where they live in racks to survive off electricity and network data. While they are not able to reproduce, they have no natural predators, so their population is stable. Some breeds of server can be found in network/data closets where they live in a business. Fewer are still kept in captivity in private homes. Virtual servers are servers that are run under an emulator or hypervisor to provide a server-like environment using a software envelope which may be augmented with hardware support.
12 |
13 | ## Daemons
14 |
15 | Daemons are software packages that run perpetually to provide content or a service. They differentiate servers from clients. Examples of daemons are webservers, email servers, file servers, authentication services (AD, LDAP), database servers, and many more.
16 |
17 | ### Webservers
18 |
19 | Webservers are daemons that accept HTTP requests and serve set content based on the requested host (IP address or domain name). The content can be static HTML/XML or it can be dynamic (JavaScript, PHP, FCGI, WSGI). Webservers commonly offer reverse proxy functionality, it is common to use webservers for this purpose instead. Common webservers include: Apache, Cherokee, LiteSpeed, Lighttpd, nginx, and IIS. Apache and nginx are the top webservers by market share respectively, with IIS coming in third.
20 |
21 | ## Domain Names
22 |
23 | Domain names are a word, phrase, or string that is used for navigating the Internet. They are registered to individuals or legal entities in lengths of years for a set fee. They are divided into levels, where each level is separated by a period (dot). Domain registrations include the top-level and second-level portion of a domain. All levels below are controlled by DNS at the discretion of the domain registrant. Top-level domains (TLDs) are .com, .net, .info, .edu, .org, etc. The customizable part of the domain name you can register is called the second-level domain. Third-level domains are referred to as *subdomains*.
24 |
25 | Structure: subdomain.*secondleveldomain*.**tld**
26 |
27 | E.g.: wiki.*r-selfhosted*.**com**
28 |
29 | ### Domain Registration
30 |
31 | Registering a domain name is done with a *Domain Registrar*. Prices are based on the top-level domain, but all registrations are for a period of one year minimum. Registrars come in two flavors:
32 |
33 | - Accredited: These registrars work directly with ICANN or other regional Internet registries for domain registrations.
34 | - Domain Resellers: These companies work with a "white label" registrar to resell domain registrations for a small markup.
35 |
36 | Accreditation requires quite a bit of infrastructure and vetting to make sure you can handle all aspects of registering and maintaining domains on behalf of the registrant. Resellers are popular because of low overhead and easy implementation. Many "white label" registrars have turnkey solutions for resellers to appear as independent registrars while actually reselling domain names.
37 |
38 | #### Which Is Right For You?
39 |
40 | Choosing a domain registrar is easy. Picking a domain registrar that is trustworthy and reputable is less so. Many domain registrars also offer to handle the DNS records for the domains registered with them. Many registrars have domain registration as a part of their business. Registration is usually bundled with webhosting or other related services. You may even get a domain registration for free if you agree to a year-long hosting contract with a webhost. While bundling related services together under one roof may sound convenient, it is generally not a good idea. It is recommended to have your domain registration with a registrar, DNS records with another company, and hosting with yet another entity. Common reasoning for this piece of advice is that if your service provider has a serious outage or other technical problem, it can only affect one aspect of your online presence. If you have all services under one provider, a technical issue could prevent your DNS from resolving and your website/service from being served.
41 |
42 | You can find the list of ICANN-accredited domain registrars [here](https://www.icann.org/registrar-reports/accreditation-qualified-list.html).
43 |
44 | As far as finding a reputable, trustworthy service provider, we must insist on your own research. One of the most popular forums for discussing hosting and related services is **[Web Hosting Talk](https://www.webhostingtalk.com/)**. If a relevant service provider has a bad reputation in the industry, you can surely find out about it here.
45 |
46 | ### Domain Name System
47 |
48 | The Domain Name System (DNS) is the method of defining what unique machines serve content for your domain. The important parts of DNS you have to worry about are *nameservers* and *DNS records*.
49 |
50 | #### Nameservers
51 |
52 | Nameservers are a way to declare which servers are responsible for answering record requests for your domain. Most registrars provide DNS services, but if you have your DNS provided elsewhere, you will want to provide your primary and secondary nameservers to your registrar. The nameservers to use will be provided by your DNS service provider.
53 |
54 | E.g.: `ns1.dnsnameserver.net`, `ns2.dnsnameserver.net`
55 |
56 | #### DNS Records
57 |
58 | DNS records are part of your domain name configuration called a DNS *zone*.
59 |
60 | - **SOA**: Start of Authority Records is generally handled by your DNS service provider automatically. They define:
61 | - **MNAME**: Master nameserver for the zone.
62 | - **RNAME**: Email for the domain administrator. Does not support "@", use periods. Periods before the domain name are escaped. E.g.: `some.one@example.com` => `some\\.one.example.com`.
63 | - **SERIAL**: The DNS zone **serial**, used to indicate when a zone has changed.
64 | - **REFRESH**: Time to wait for secondary nameservers to query the master.
65 | - **RETRY**: Timeout for refreshing.
66 | - **EXPIRE** Threshold time for secondary nameservers to stop attempting to reach an unresponsive master server.
67 | - **TTL**: The time to live to use for NXDOMAIN responses.
68 |
69 | **Example SOA**:
70 |
71 | ```dns-zone
72 | $TTL 86400
73 | @ IN SOA ns1.nameserver.com. postmaster.sumdomain.com. (
74 | 2020080302 ;Serial
75 | 7200 ;Refresh
76 | 3600 ;Retry
77 | 1209600 ;Expire
78 | 3600 ;Negative response caching TTL
79 | )
80 | ```
81 |
82 | The fields of a DNS zone record are:
83 |
84 | - **Domain**: Either the domain name or subdomain to create a record for.
85 | - **Time to live**: The time in seconds for a record to be cached before a new copy is requested.
86 | - **Class**: Indicative of the namespace. Usually IN (Internet namespace).
87 | - **Type**: The type of record to define.
88 | - **Content**: The content of the record. What is acceptable in this field is dependent on the type of record.
89 |
90 | There are many types of DNS records, let's go over some common ones. This list is **not** exhaustive.
91 |
92 | - **A**: A records tie the domain or subdomain to an IPv4 address.
93 | - **AAAA**: AAAA records tie the domain or subdomain to an IPv6 address.
94 | - **CNAME**: CNAME records tie the domain or subdomain to another domain or subdomain.
95 | - **MX**: MX records are used to define how mail is handled for your domain. The content of an MX record is the priority and answering server domain name. Lower preference number indicates higher priority.
96 | - **TXT**: Text records associate text data with your domain. They are used for a variety of reasons, notable for SPF or DKIM.
97 |
98 | | Domain | Time To Live | Class | Type | Content { class="compact" } |
99 | |--------|--------------|----|------|---------|
100 | | example.com. | 86400 | IN | A | 192.168.1.240 |
101 | | ipv6.example.com. | 86400 | IN | AAAA | feef:00bb:2005:1eef:fbca:544d |
102 | | www.example.com. | 86400 | IN | CNAME | example.com. |
103 | | example.com. | 86400 | IN | MX | 10 mail.mailserver.com |
104 | | example.com. | 86400 | IN | TXT | "Reserved for a purpose I am not legally required to disclose." |
105 |
106 |
107 | ## Reverse Proxies
108 |
109 | Reverse proxies are daemons that accept connections and then connect to another service based on port or host to facilitate the request. They act as a middleman instead of a traffic redirector.
110 |
111 | Typical use cases for reverse proxies are to provide a unified frontend for multiple backends or hosts. Another common use is for high-availability to provide failover or distribute load between multiple backends serving the same content.
112 |
113 | Examples of popular software capable of performing as a reverse proxy are: Squid, HAProxy, Apache, nginx, and Caddy.
114 |
115 |
116 | ## Port Forwarding
117 |
118 | Port forwarding is the function of inspecting traffic on an incoming port and redirecting it to another port or host with minimal modification. Primary purposes of this are to forward traffic to a service behind a firewall/router.
119 |
120 | Common for hosting game servers from home when running dedicated servers before developers moved to match-making. Another use for this is to open ports for BitTorrent so that you can share your vast and innumerable collection of Linux ISOs.
121 |
122 | The difference between port forwarding and a reverse proxy is that the reverse proxy will accept, process, and establish a new connection to the backend service to fulfil the request.
123 |
124 | Port forwarding inspects and alters packet headers before it is routed to its new destination. The connection is otherwise untouched.
125 |
126 | Port forwarding is a function of your firewall. Commonly at the router or other network gateway.
127 |
128 | Linux has two firewalls called `iptables` and `nftables`, with many frontends or management packages available for them. BSD-based firewalls are `pf`, `ipfw`, and `IPFilter`. The Windows firewall consists of a scarecrow holding a sign saying: "plz no tresspass".
129 |
130 | ## Containers
131 |
132 | Containers are software envelopes to isolate a piece or bundle of software and their dependencies. Containers come in many forms. A container could contain a PHP-based forum with an AMP stack (Apache, Maria DB, PHP) as dependencies. This is useful if you want an easy way to deploy software without configuring dependent software/libraries manually. Containers can also resolve software conflicts when running multiple services which depend on different versions of the same software/libraries.
133 |
134 | Popular containers are Linux Containers (LXC), jails (BSD UNIX), Kubernetes, and Docker.
135 |
136 | ## Virtualization
137 |
138 | Virtualization is a lower level form of containerization. There are many forms of virtualization that provide different sets of features/tradeoffs. In practice, it often virtualizes whole or major parts of an operating system.
139 |
140 | ### Full virtualization
141 |
142 | Full virtualization is generally understood as the containerization of a full, unmodified operating system with virtualized hardware. The virtualized OS is not host-aware. Fully virtualized guests require more overhead than paravirtualized guests. This can be mitigated with hardware support (Intel VT, AMD SVM) for virtualization instructions.
143 |
144 | Examples of this are Hyper-V, Xen, KVM/Qemu, VMware ESXi.
145 |
146 | ### Paravirtualization
147 |
148 | Paravirtualization is the practice of running a modified kernel/OS where privileged instructions are sent through an API shared with the host. It does not require the virtualization of hardware, but it does require an operating system that is modified to be used with the specific API used by your chosen virtualization method. This can be in the form of source code modifications or specialized device drivers.
149 |
150 | !!!
151 | Microsoft Windows cannot be paravirtualized.
152 | !!!
153 |
154 | Examples: Xen, Oracle VM, OpenVZ.
155 |
156 |
157 | ## Virtual private networks
158 |
159 | Virtual private networks (VPNs) are a way of networking individual machines together in software regardless of their physical or network proximity. A typical use case is for networking corporate locations together to share network resources such as file shares, intranet webservers, on-premises services, etc. Another use for a VPN is to tunnel traffic destined for a public service through to another endpoint, usually to bypass geo-location restrictions or state-imposed censorship of the Internet.
160 |
161 | Some people use VPNs so they can access their services that are behind a restrictive ISP or firewall.
162 |
163 | ## Operating Systems
164 |
165 | An operating system is the software that is responsible for running and managing your physical machine. It provides the kernel, hardware drivers, low-level software packages, libraries, and userland applications for the end-user to provide basic functions.
166 |
167 | Most consumers or end-users will use Microsoft Windows or macOS as their operating system on their desktop or laptop computers.
168 |
169 | You will commonly find that corporate IT infrastructure used to serve employees is Microsoft-based, using ActiveDomain (AD) for authentication, Exchange for email and groupware, IIS for serving websites, and MSSQL for databases.
170 |
171 | Linux or UNIX-based operating systems are the popular choice for hosting services and serving content to end-users. Examples are webhosts for serving websites, Netflix for serving movie and TV streams, DNS services for domain records, and most if not all other infrastructure needed to keep the Internet operational.
172 |
173 | Android is a Linux-based operating system used in the majority of the smartphone market. iOS is a BSD-based mobile OS used by Apple for iPhones.
174 |
175 | Embedded Linux and BSD are also used in devices like set-top boxes, smart TVs, routers, smart switches, medical equipment, flight telemetry controllers for aerospace, navigation equipment, industrial automation, etc...
176 |
--------------------------------------------------------------------------------
/learn/difficulty-tiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Difficulty Tiers
3 | title: Difficulty Tiers For Self-Hosting
4 | icon: stop
5 | order: alpha
6 | ---
7 |
8 | !!!
9 | When working with self-hosting software and services you'll find there's a varierty of difficulties. This document helps define some difficulty tiers. You'll also notice references to these difficulties throughout the guides contained in this wiki.
10 | !!!
11 |
12 | ## Easy / Basic
13 | [!badge variant="success" text="Easy / Basic"]
14 |
15 | No worries here, folks! Everything can be done with a GUI with *maybe* several commands. It may also involve some editing of text files. Instructions usually include screenshots and/or diagrams. Operating systems in this tier are Ubuntu Linux, Microsoft Windows, and macOS.
16 |
17 | ## Medium / Intermediate
18 | [!badge variant="primary" text="Medium / Intermediate"]
19 |
20 | This tier is still not very difficult, but you're expected to know how not to break things in a terminal or text-based interface. A GUI is optional, but may be used on occasion. Operating systems in this tier include the ones from the previous tier and Debian Linux, Red Hat Enterprise Linux, Rocky Linux, and Alma Linux.
21 |
22 | ## Hard / Advanced
23 | [!badge variant="warning" text="Hard / Advanced"]
24 |
25 | You are at home with a terminal and all tasks can be accomplished within it. If you break something while in the terminal you're comfortable fixing it. You understand how to fix serious system level issues. Operating systems in this tier include those previously mentioned plus Arch Linux, *BSD, Slackware Linux, and Gentoo Linux.
26 |
27 | ## Guru / Expert
28 | [!badge variant="danger" text="Guru / Expert"]
29 |
30 | You are able to compile software from source and aren't shy about surfing the web with Lynx. You are a top resource that others come to when they need help. You run [Suicide Linux](https://qntm.org/suicide) because anything less is for little babies!
31 |
--------------------------------------------------------------------------------
/learn/index.yml:
--------------------------------------------------------------------------------
1 | order: 2
2 | icon: mortar-board
3 |
--------------------------------------------------------------------------------
/learn/operating-systems.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Operating Systems
3 | icon: device-desktop
4 | order: alpha
5 | ---
6 |
7 | There are many operating systems available to meet different needs. Some are more difficult to administer than others, but there should be a solution available for whatever you want to do.
8 |
9 | While paying for a licensed product is always an option if you find the value in said product worth the cost, it is recommended to make sure that a "free" solution could not meet the same needs.
10 |
11 | #### Proprietary / Licensed
12 |
13 | - [Microsoft Windows Server](https://www.microsoft.com/en-us/windows-server/) | Windows is not usually chosen due to licensing costs.
14 | - [Unraid](https://unraid.net/) | Linux-based, but requires the purchase of a license for usage past the trial period.
15 |
16 | #### Entry Level / Easy
17 |
18 | These are operating systems that are administered with a GUI/web-based frontend to focus on ease of use.
19 |
20 | - [YunoHost](https://yunohost.org) | [Demo](https://yunohost.org/#/try)
21 | - [TrueNAS CORE](https://www.truenas.com/truenas-core/) | A FreeBSD-based NAS operating system with ZFS support. Published by [iXsystems](https://www.ixsystems.com/), [TrueNAS and FreeNAS were "Unified" in late 2021](https://www.ixsystems.com/history/).
22 | - [TrueNAS SCALE](https://www.truenas.com/truenas-scale/) | A Debian Linux NAS operating system. Published by iXsystems, and based around work done for TrueNAS CORE.
23 | - [OpenMediaVault](https://www.openmediavault.org/)
24 | - [DietPi](https://dietpi.com/) | Built for single-board computers like Raspberry Pi or Pine64 boards.
25 | - [Sandstorm](https://sandstorm.io/) | [Demo](https://alpha.sandstorm.io/apps)
26 |
27 | #### Intermediate / Headless
28 |
29 | If you are comfortable managing your server using terminal, then these options will work for you. They do a lot of hard work for you and should be simple to administer when needed.
30 |
31 | - [Ubuntu Server](https://ubuntu.com/server) | Debian-based server OS developed by Canonical Ltd.
32 | - [Rocky Linux](https://rockylinux.org/) | Fork/replacement for CentOS.
33 | - [openSUSE](https://www.opensuse.org/)
34 | - [Fedora Linux](https://getfedora.org/en/server/)
35 | - [Debian](https://www.debian.org/) | One of the two oldest Linux distributions that are still maintained. Stable, mature, and proven.
36 |
37 | #### Advanced
38 |
39 | - [Arch Linux](https://archlinux.org/) | A light, simple distribution that provides a small foundation to build on. Rich documentation and a large community-maintained third party software repository make it a solid choice for Linux veterans. Tailored for experienced users.
40 | - [Gentoo Linux](https://www.gentoo.org/) | A Linux distribution focused on building packages from source to best fit your system. Binary packages are available, but that's like, against the spirit duuude.
41 | - [Slackware Linux](http://www.slackware.com/) | The other of the two oldest Linux distributions that are still maintained today, it focuses on stability and sticking to its UNIX roots.
42 | - [FreeBSD](https://www.freebsd.org/) | Almost as old as Linux itself, it is derived from BSD UNIX as developed at the University of California in Berkley. Used by Netflix as the OS powering its digital media delivery nodes.
43 | - [Alpine Linux](https://alpinelinux.org/) | A tiny Linux distribution catering to power users who want to squeeze the most resources out of their systems.
44 |
45 | #### Niche / Other
46 |
47 | - [Proxmox VE](https://www.proxmox.com/en/proxmox-ve) | An operating system focused on the management of a virtualization environment utilizing KVM as a hypervisor.
48 | - [XCP-ng](https://xcp-ng.org/) | XenServer-based, offers a turnkey virtualization solution.
49 |
--------------------------------------------------------------------------------
/learn/self-hosted-alternatives-to-popular-services-and-providers.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: Self-Hosted Alternatives
3 | meta:
4 | title: Self-Hosted Alternatives to Popular Services and Providers
5 | icon: package-dependents
6 | order: alpha
7 | ---
8 |
9 | There will be some common choices in some common categories here for some self-hosted alternatives. A more comprehensive list of alternatives will be listed at the bottom of this page.
10 |
11 | !!!warning Warning
12 | None of the software listed on this page is endorsed or supported by r/selfhosted.
13 | !!!
14 |
15 | ## Web Servers
16 |
17 | Daemons that serve website content.
18 |
19 | - [Apache](https://httpd.apache.org/) | The most popular webserver since forever. Higher overhead than others, but most PHP applications assume it.
20 | - [nginx](https://www.nginx.com/) | Second most popular webserver today, created to run some of the biggest Russian websites.
21 | - [Lighttpd](https://www.lighttpd.net/) | A more niche webserver focusing on low overhead and high performance.
22 | - [Caddy](https://caddyserver.com/) | A fast, multi-platform web server with automatic HTTPS.
23 |
24 | ## Databases
25 |
26 | Daemons or services that store data in a structured format.
27 |
28 | - [PostgreSQL](https://www.postgresql.org/) | A popular database solution that emphasizes extensibility and standards compliance.
29 | - [Maria DB](https://mariadb.org/) | Based on MySQL, forked to maintain an open source alternative that is mostly compatible with MySQL-based applications.
30 | - [MongoDB](https://www.mongodb.com/) | A document-based NoSQL database that uses JSON-like formatting to store information.
31 | - [SQLite](https://www.sqlite.org/index.html) | Flat file database that doesn't require a running DB server.
32 |
33 | ## Content Management Systems
34 |
35 | Frontends for managing the content on your website.
36 |
37 | - [WordPress](https://wordpress.org/) | The most popular CMS by market share, uses the blog format.
38 | - [Joomla!](https://www.joomla.org/) | Another popular CMS written in PHP.
39 | - [WonderCMS](https://www.wondercms.com/) | Claims to be the smallest CMS around. Is definitely small.
40 |
41 | ## E-Commerce
42 |
43 | Software for operating and managing an e-shop.
44 |
45 | - [OpenCart](https://www.opencart.com/)
46 | - [Magento](https://magento.com/)
47 | - [PrestaShop](https://www.prestashop.com/en)
48 |
49 | ## File Synchronization
50 |
51 | Services that synchronize files across systems.
52 |
53 | - [ownCloud](https://owncloud.com/)
54 | - [Syncthing](https://syncthing.net/)
55 | - [Seafile](https://www.seafile.com/en/home/)
56 |
57 | ## Media Streaming
58 |
59 | Daemons for streaming digital media.
60 |
61 | - [Jellyfin](https://jellyfin.org/) | Media streaming server capable of handling audio, video, comics, books, and photos.
62 | - [Icecast](https://www.icecast.org/) | Operate your own Internet radio station!
63 | - [Navidrome](https://www.navidrome.org/) | Music streaming software with a web UI and compatible with Subsonic/Airsonic clients.
64 |
65 | ## Photo Galleries
66 |
67 | Software for operating a photo gallery.
68 |
69 | - [Chevereto](https://chevereto.com/free)
70 | - [Zenphoto](http://www.zenphoto.org/)
71 | - [Piwigo](http://piwigo.org/)
72 |
73 | ## Wiki Software
74 |
75 | You own personal knowledge base!
76 |
77 | - [DokuWiki](https://www.dokuwiki.org/DokuWiki) | A simple wiki that stores content in text files instead of a database.
78 | - [MediaWiki](https://www.mediawiki.org/wiki/MediaWiki) | The software that powers [Wikipedia](https://wikipedia.org).
79 | - [Cowyo](https://github.com/schollz/cowyo) | A minimal wiki/note-taking package.
80 |
81 | -----
82 |
83 | The following are considered the "master lists" of self-hosted alternatives.
84 |
85 | - [Awesome Self-Hosted](https://github.com/awesome-selfhosted/awesome-selfhosted) | A list of Free Software network services and web applications which can be hosted on your own servers
86 | - [Awesome SysAdmin](https://github.com/n1trux/awesome-sysadmin) | A curated list of amazingly awesome open-source sysadmin resources
87 |
--------------------------------------------------------------------------------
/learn/what-are-reverse-proxies.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: What Are Reverse Proxies?
3 | icon: arrow-switch
4 | order: alpha
5 | ---
6 |
7 | What can a reverse proxy do for *you*?
8 |
9 | Many services that are self-hosted have a web UI. If you have many of these services running, a reverse proxy can be a central daemon that handles requests for all of these various backends.
10 |
11 | Let's say that you have three different services running:
12 |
13 | - Node.js forum NodeBB that runs on port `8008`
14 | - Navidrome music streaming server on port `3000` through a local machine using IP `192.168.1.125`
15 | - ownCloud web UI on port `8800` on a local machine with an IP of `192.168.1.123`
16 |
17 | You have a domain name that you want to use for these but don't want an ugly URL like `http://mydomain.com:8008`. To complicate things further, these services are all on different hosts.
18 |
19 | A reverse proxy can be configured to accept requests for this domain and redirect them to a different host or port.
20 |
21 | To make your URLs pretty, the reverse proxy can be configured to redirect requests on your domain based on a folder name to a different service on your local network.
22 |
23 | - `http://mydomain.com/forum/` --> `http://localhost:8008/`
24 | - `http://mydomain.com/music/` --> `http://192.168.1.125:3000/`
25 | - `http://mydomain.com/cloud/` --> `http://192.168.1.123:8800/`
26 |
27 | As you can see, it is much nicer to reach these services through a single domain and folder than to use their port and host individually.
28 |
29 | You can even couple this with a self-hosted VPN so that these requests can be proxied to different services on different networks in different locations. All you need to do is to make sure the proxy and the services are on the same VPN and to use the VPN IP addresses.
30 |
31 | You don't have to use folders either. You can use subdomains as well such as `music.mydomain.com`, `cloud.mydomain.com`, and `forum.mydomain.com` respectively. It's all up to you and how you want to structure your services.
32 |
--------------------------------------------------------------------------------
/learn/what-is-self-hosting.md:
--------------------------------------------------------------------------------
1 | ---
2 | label: What Is Self-Hosting?
3 | icon: question
4 | order: alpha
5 | ---
6 |
7 | > **The act of providing or serving digital content or an online service typically delivered by a business.**
8 | >
9 | > The service or content is generally served locally from your own hardware. Often "self-hosters" use older Enterprise-grade hardware from their home internet connections however they also use other hosting providers hardware. This is still considered self-hosting.
10 |
11 | ---
12 |
13 | One of the easiest things to self-host with the lowest barrier to entry is a website. For the most basic website of your own, all you need is a domain name and a webserver. Then you throw a few lines of HTML in a file and you have yourself a "website". With a service like Let's Encrypt, securing the site with a SSL certificate is easy too.
14 |
15 | A lot of different services that you can self-host are "websites". There are dynamic sites with robust content management systems like Joomla!, Drupal, WordPress, or b2evolution. There are forums like phpBB, MyBB, vBulletin, Discourse, etc. Knowledge bases like DokuWiki, MediaWiki, BookStack, or Gollum are also websites. These websites only require a webserver, an interpreter (PHP), and a database (SQLite, PostgreSQL, MySQL).
16 |
17 | Just about everything these days has a web UI or frontend to make things easier. HTTP/HTML/JS are well-understood standards that are ubiquitous. There are many libraries for converting or presenting your content in a web-friendly way for almost all programming languages you can learn.
18 |
19 | It can be hard for someone unfamiliar to find the difference between the "website" frontend and the content backend. Sometimes the difference is almost non-existent. Sometimes there are many layers and systems working behind the scenes to make it happen.
20 |
21 | It may be better to say that everything can be "accessed" through a website, even if it isn't one *per-se*. And if it can't, there's probably a separate piece of software that makes a web UI for it.
22 |
23 | Examples of services with a web UI or separate web-based frontends are: BitTorrent clients like qBittorrent/Transmission, media streaming servers like Jellyfin/Navidrome, file synchronization services like Nextcloud/ownCloud/Seafile, communication services like Synapse/InspIRCd/jabberd/Mumble, and many more.
24 |
25 | Other services use the server-client model where the entire package is in two parts. The server part that runs at all time to serve content and the client part that connects to have content served to it. Examples are: game servers like Rust/Minecraft/Factorio, FTP servers, email servers, and more.
26 |
--------------------------------------------------------------------------------
/retype.yml:
--------------------------------------------------------------------------------
1 | input: .
2 | output: .retype
3 | url: wiki.r-selfhosted.com
4 | branding:
5 | title: r/SelfHosted
6 | label: Wiki
7 | edit:
8 | repo: "https://github.com/r-selfhosted/wiki/"
9 | label: Edit on GitHub
10 | editor:
11 | enabled: false
12 | favicon: static/favicon.png
13 | footer:
14 | copyright: "© Copyright {{ year }}. All rights reserved."
15 | links:
16 | - text: Home
17 | link: /
18 | icon: home
19 | - text: Discord
20 | link: https://discord.gg/UrZKzYZfcS
21 | icon: comment-discussion
22 | - text: Forums
23 | link: https://forum.r-selfhosted.com/
24 | icon: note
25 | - text: Mastodon
26 | link: https://selfhosted.cafe
27 | icon: heart
28 | - text: Reddit
29 | link: https://reddit.com/r/selfhosted
30 | icon: cross-reference
31 |
--------------------------------------------------------------------------------
/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-selfhosted/wiki/843c2bc933943d115049bb24a3f4984608011a08/static/favicon.png
--------------------------------------------------------------------------------