diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/01.en.md b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/01.en.md
new file mode 100644
index 000000000..1e806e36a
--- /dev/null
+++ b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/01.en.md
@@ -0,0 +1,347 @@
+---
+SPDX-License-Identifier: MIT
+path: "/tutorials/install-and-configure-appflowy-with-hetzner-object-storage"
+slug: "install-and-configure-appflowy-with-hetzner-object-storage"
+date: "2024-12-03"
+title: "Install and configure AppFlowy with Hetzner Object Storage"
+short_description: "A guide on how to setup your own AppFlowy Cloud server using Hetzner Object Storage."
+tags: ["AppFlowy", "Object Storage", "Cloud"]
+author: "Stefan Weiberg"
+author_link: "https://github.com/suntorytimed"
+author_img: "https://avatars.githubusercontent.com/u/2744377"
+author_description: ""
+language: "en"
+available_languages: ["en"]
+header_img: "header-4"
+cta: "cloud"
+---
+
+## Introduction
+
+[AppFlowy](https://appflowy.io/) is an open-source alternative to Notion. In this tutorial we are going to setup our own [AppFlowy Cloud](https://docs.appflowy.io/docs/appflowy/product/appflowy-cloud) server using the official documentation by AppFlowy. We will connect AppFlowy to the [Hetzner Object Storage](https://docs.hetzner.com/storage/object-storage). When you add images or videos to a document, AppFlowy will save them in your Object Storage Bucket and access them from there. This tutorial won't cover how you create a new project called "AppFlowy" or a new server. We will purely focus on setting up AppFlowy, setting up a Bucket and connecting it to our AppFlowy Cloud server.
+
+### Prerequisites
+
+* Server
+ * [git](https://git-scm.com/downloads/linux), [Docker and docker-compose](https://docs.docker.com/engine/install/#supported-platforms) already installed
+ Verify with `git -v`, `docker -v`, `docker compose version`
+ * Access via SSH
+
+* DNS entry for your desired (sub-)domain to your server
+* Optional: Dedicated Hetzner Cloud project called "AppFlowy" to pool your resources together
+
+## Step 1 - Create a Bucket
+
+First, create a new Bucket in the Hetzner [Cloud Console](https://console.hetzner.cloud/).
+For a step-by-step guide, see "[Creating a Bucket](https://docs.hetzner.com/storage/object-storage/getting-started/creating-a-bucket)".
+
+As the name of the Bucket, we choose `appflowy` and add a UUID after it to make it unique. We can create the Bucket with private visibility, as the access will happen via the server.
+
+Example:
+
+> **LOCATION**
+> Falkenstein
+>
+> **NAME/URL**
+> `appflowy-.fsn1.your-objectstorage.com`
+>
+> **VISIBILITY**
+> ⊙ Private
+
+After successfully creating the Bucket, open it and copy the URL of the Bucket, by clicking on it.
+Paste the URL into a file for later.
+
+![Copy the URL of your Bucket](images/bucket_url.png)
+
+Next, click on "Manage credentials" on the same screen to access the page for S3 credential creation.
+For a step-by-step guide, see "[Generating S3 keys](https://docs.hetzner.com/storage/object-storage/getting-started/generating-s3-keys)".
+
+Choose a description for your new credentials, for example "AppFlowy".
+Copy and store your access key and secret key for later usage.
+
+## Step 2 - Set up your AppFlowy Cloud server
+
+SSH into your server or use the Hetzner Cloud Console terminal to access your server via the web frontend.
+
+### Step 2.1 - Clone the AppFlowy Cloud repository
+
+Clone the AppFlowy Cloud repository to your desired location and `cd` into the cloned repository:
+
+```bash
+git clone https://github.com/AppFlowy-IO/AppFlowy-Cloud
+cd AppFlowy-Cloud
+```
+
+### Step 2.2 - Setup the nginx proxy of AppFlowy Cloud to use your SSL certificate
+The `AppFlowy-Cloud` directory should include the following files:
+
+```yml
+AppFlowy-Cloud
+├─ docker-compose.yml
+└─ nginx/ssl/
+ ├─ certificate.crt
+ └─ private_key.key
+```
+
+`docker-compose.yml` points to the SSL certificate like this:
+
+```yaml
+ volumes:
+ - ./nginx/nginx.conf:/etc/nginx/nginx.conf
+ - ./nginx/ssl/certificate.crt :/etc/nginx/ssl/certificate.crt
+ - ./nginx/ssl/private_key.key :/etc/nginx/ssl/private_key.key
+```
+
+Put your SSL certificate and private key into the files in `AppFlowy-Cloud/nginx/ssl/` or adjust the location in the `docker-compose.yml` to point to your own certificates.
+
+---------
+
+Alternatively you can create a Let's Encrypt SSL certificate via DNS challenge on the Hetzner DNS service by using lego:
+
+* Create SSL certificate
+ ```bash
+ go install github.com/go-acme/lego/v4/cmd/lego@latest
+ sudo ~/go/bin/lego --domains="appflowy.example.com" --email="admin@example.com" --http run
+ ```
+ You should now have the following files:
+ ```yml
+ AppFlowy-Cloud
+ ├─ docker-compose.yml
+ └─ .lego/certificates/
+ ├─ appflowy.example.com.crt
+ └─ appflowy.example.com.key
+ ```
+
+* Adjust the `docker-compose.yml` to point to the output folder of lego:
+ ```yml
+ nginx:
+ restart: on-failure
+ image: nginx
+ ports:
+ - ${NGINX_PORT:-80}:80 # Disable this if you are using TLS
+ - ${NGINX_TLS_PORT:-443}:443
+ volumes:
+ - ./nginx/nginx.conf:/etc/nginx/nginx.conf
+ - ./.lego/certificates/appflowy.example.com.crt:/etc/nginx/ssl/certificate.crt
+ - ./.lego/certificates/appflowy.example.com.key:/etc/nginx/ssl/private_key.key
+ ```
+
+## Step 3 - Edit `docker-compose.yml`
+
+Open `docker-compose.yml` with you favourite text editor and make the following changes:
+
+* Remove the minio service
+
+ Remove the minio service by deleting the following lines:
+
+ ```yml
+ # You do not need this if you have configured to use your own s3 file storage
+ minio:
+ restart: on-failure
+ image: minio/minio
+ environment:
+ - MINIO_BROWSER_REDIRECT_URL=http://localhost/minio
+ - MINIO_ROOT_USER=${APPFLOWY_S3_ACCESS_KEY:-minioadmin}
+ - MINIO_ROOT_PASSWORD=${APPFLOWY_S3_SECRET_KEY:-minioadmin}
+ command: server /data --console-address ":9001"
+ volumes:
+ - minio_data:/data
+ ```
+
+* Remove the minio_data volume
+
+ Don't forget to remove the `minio_data` volume from the volumes at the end of the `docker-compose.yml`. Only the `postgres_data `volume should remain:
+
+ ```yml
+ volumes:
+ postgres_data:
+ ```
+
+
+* Edit or remove the ai service
+
+ If you have an openai api key, add it in the ai service.
+ If you don't have an openai api key, comment out the ai service.
+
+ ```yml
+ ai:
+ restart: on-failure
+ image: appflowyinc/appflowy_ai:${APPFLOWY_AI_VERSION:-latest}
+ environment:
+ - OPENAI_API_KEY=${APPFLOWY_AI_OPENAI_API_KEY}
+ - APPFLOWY_AI_SERVER_PORT=${APPFLOWY_AI_SERVER_PORT}
+ - APPFLOWY_AI_DATABASE_URL=${APPFLOWY_AI_DATABASE_URL}
+ ```
+
+## Step 4 - Edit `deploy.env`
+
+Now we need to adjust the `deploy.env` file to use our own passwords and point to the Hetzner Object Storage. I recommend to keep the order of values identical, as we are going to commit our changes locally. This makes rebasing easier.
+
+* At the time of creation of this tutorial you should adjust the following values with your own password and SMTP configuration:
+
+ ```env
+ # replace the value of ${POSTGRES_PASSWORD} with a secure password
+ # change the secret
+ # change your database name if needed
+ POSTGRES_PASSWORD="securepassword"
+ GOTRUE_JWT_SECRET=hello456
+
+ # replace with your own SMTP configuration
+ # you will need this to send out magic links for login
+ GOTRUE_SMTP_HOST=smtp.gmail.com
+ GOTRUE_SMTP_PORT=465
+ GOTRUE_SMTP_USER=email_sender@some_company.com
+ GOTRUE_SMTP_PASS=email_sender_password
+ GOTRUE_SMTP_ADMIN_EMAIL=comp_admin@some_company.com
+ APPFLOWY_MAILER_SMTP_HOST=smtp.gmail.com
+ APPFLOWY_MAILER_SMTP_PORT=465
+ APPFLOWY_MAILER_SMTP_USERNAME=email_sender@some_company.com
+ APPFLOWY_MAILER_SMTP_PASSWORD=email_sender_password
+
+ # configure your admin account
+ GOTRUE_ADMIN_EMAIL=admin@example.com
+ GOTRUE_ADMIN_PASSWORD=password
+
+ # input your (sub-)domain, which you configured in the Hetzner DNS service
+ API_EXTERNAL_URL=https://appflowy.example.com
+ ```
+
+* Remove the following lines, as we won't use those services:
+
+ ```env
+ # PgAdmin
+ # Optional module to manage the postgres database
+ # You can access the pgadmin at http://your-host/pgadmin
+ # Refer to the APPFLOWY_DATABASE_URL for password when connecting to the database
+ PGADMIN_DEFAULT_EMAIL=admin@example.com
+ PGADMIN_DEFAULT_PASSWORD=password
+
+ # Portainer (username: admin)
+ PORTAINER_PASSWORD=password1234
+
+ # Cloudflare tunnel token
+ CLOUDFLARE_TUNNEL_TOKEN=
+ ```
+
+* And finally configure your Object Storage:
+
+ ```conf
+ APPFLOWY_S3_USE_MINIO=true
+ APPFLOWY_S3_MINIO_URL=https://appflowy-5d3f1744a2494fb5b49c983e3eff3e17.fsn1.your-objectstorage.com # this is where the previously copied Object Storage URL is pasted
+ APPFLOWY_S3_ACCESS_KEY= # paste your previously generated access key from the S3 credentials
+ APPFLOWY_S3_SECRET_KEY= # paste your previously generated secret key from the S3 credentials
+ APPFLOWY_S3_BUCKET=appflowy # this isn't really the name of your Bucket, but the root folder in your Bucket
+ #APPFLOWY_S3_REGION=us-east-1
+ ```
+
+## Step 5 - Start AppFlowy Cloud
+
+Now that `docker-compose.yml` and `deploy.env` are ready, you can commit your changes and start the Docker containers.
+
+* Add and commit your changes `optional`
+
+ We use git to store our changes in the git log and make it easier to pull updates from upstream. By using this method every change of defaults in the `deploy.env` and `docker-compose.yml` will result in merge conflicts when pulling an update, which you need to resolve before restarting/updating your server.
+
+ ```bash
+ git add deploy.env docker-compose.yml
+ git commit -m "my own AppFlowy deployment on Hetzner Cloud"
+ ```
+
+* Start the AppFlowy Cloud server
+
+ Start your AppFlowy Cloud server via `docker compose` (or `docker-compose`, depending on your installation method):
+
+ ```bash
+ docker compose --env-file deploy.env up -d
+ ```
+
+You should now be able to access the web UI via your domain:
+
+```https
+https://appflowy.example.com
+```
+
+Use `docker ps` to check the status of the Docker containers. If you run into any issues, run `docker compose logs`.
+
+## Step 6 - Install and configure AppFlowy Application
+
+Go to [appflowy.io](https://appflowy.io/) and download the AppFlowy Application on your local device.
+
+After the AppFlowy Application is installed on your local device, open the application and log in as "Anonymous".
+
+![Login as Anonymous](images/appflowy_login-anonymous.png)
+
+Now click on the gear icon to open the settings.
+
+![Open settings](images/appflowy_setting.png)
+
+In the settings:
+
+* Navigate to "Cloud Settings"
+* Change the value of Cloud server to "AppFlowy Cloud Self-hosted"
+* Enable the sync
+* Enter the URL of your cloud server as "Base URL"
+* Restart AppFlowy.
+
+![Restart AppFlowy](images/appflowy_setting-restart.png)
+
+After the restart, you might not be able to login again. To login again, you will need the magic link as explained in the next step.
+
+## Step 7 - User creation and login
+
+Open a browser and navigate to the URL of your server. The admin frontend will open up and you can login with the admin credentials you previously defined in `deploy.env`. Via the invite page, you can now create/invite new users:
+
+![Invite new users](images/user_invite.png)
+
+When you invite a new user, they will receive a magic link for login. If they didn't receive a mail, you can manually create a magic link by clicking "Admin" in the top right and navigating to "List Users". Click "More Info" next to the user you just invited and select "Generate Invite Link".
+
+When you follow the magic link, it will automatically log into the local AppFlowy Application. Your AppFlowy Application should now save images and videos in your Hetzner Object Storage Bucket.
+
+In the web frontend, you also have the option to directly open AppFlowy with the account you logged into the web frontend with.
+
+![Open AppFlowy](images/open_appflowy.png)
+
+## Step 8 - Check if Object Storage works
+
+AppFlowy should use the Object Storage for storing your images and videos. Open up the AppFlowy Application on your local device and add an image in a random page.
+
+![Add image to a random page in AppFlowy](images/image_appflowy.png)
+
+You can now check in your Hetzner Cloud Console if the file got created in the Bucket.
+
+![Check if image is uploaded to the object storage](images/image_console.png)
+
+## Conclusion
+
+We have setup our own AppFlowy Cloud server using the Hetzner Object Storage.
+
+##### License: MIT
+
+
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_login-anonymous.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_login-anonymous.png
new file mode 100644
index 000000000..90c719194
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_login-anonymous.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_setting-restart.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_setting-restart.png
new file mode 100644
index 000000000..5e14dd403
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_setting-restart.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_setting.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_setting.png
new file mode 100644
index 000000000..570906137
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/appflowy_setting.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/bucket_url.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/bucket_url.png
new file mode 100644
index 000000000..1aa919ca4
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/bucket_url.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/image_appflowy.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/image_appflowy.png
new file mode 100644
index 000000000..d53d843d9
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/image_appflowy.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/image_console.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/image_console.png
new file mode 100644
index 000000000..f092c63d2
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/image_console.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/open_appflowy.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/open_appflowy.png
new file mode 100644
index 000000000..1429be9a1
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/open_appflowy.png differ
diff --git a/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/user_invite.png b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/user_invite.png
new file mode 100644
index 000000000..1d0abe125
Binary files /dev/null and b/tutorials/install-and-configure-appflowy-with-hetzner-object-storage/images/user_invite.png differ