├── .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 --------------------------------------------------------------------------------