[{"content":"Feel free to explore anything that catches your eye. You can use tags and categories to help you find something to read.\n","date":"5 November 2025","externalUrl":null,"permalink":"/blog/","section":"Blog","summary":"\u003cp\u003eFeel free to explore anything that catches your eye. You can use \u003cstrong\u003e\u003ca\n  href=\"/tags\"\u003etags\u003c/a\u003e\u003c/strong\u003e and \u003cstrong\u003e\u003ca\n  href=\"/categories\"\u003ecategories\u003c/a\u003e\u003c/strong\u003e to help you find something to read.\u003c/p\u003e","title":"Blog","type":"blog"},{"content":"","date":"5 November 2025","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"5 November 2025","externalUrl":null,"permalink":"/tags/diy/","section":"Tags","summary":"","title":"Diy","type":"tags"},{"content":"Welcome to my website, where I document my journey and share it with the world, know more about me. My blog page lists all my writings, project page lists my projects, I have worked on and, my spaces page lists my interests categorized by their own space.\n","date":"5 November 2025","externalUrl":null,"permalink":"/","section":"Home","summary":"\u003cp\u003eWelcome to my website, where I document my journey and share it with the world, know more \u003ca\n  href=\"/about\"\u003eabout me\u003c/a\u003e.\nMy \u003ca\n  href=\"/blog/\"\u003eblog\u003c/a\u003e page lists all my writings, \u003ca\n  href=\"/projects/\"\u003eproject\u003c/a\u003e page lists my projects,\nI have worked on and, my \u003ca\n  href=\"/spaces/\"\u003espaces\u003c/a\u003e page lists my interests categorized by their own space.\u003c/p\u003e","title":"Home","type":"page"},{"content":"","date":"5 November 2025","externalUrl":null,"permalink":"/tags/m365/","section":"Tags","summary":"","title":"M365","type":"tags"},{"content":" The No-BS, Warranty-Free Guide to Locking Down Your Small Business with Microsoft 365 Business Premium # Why this guide? You’re a small business owner. You don’t have an IT army or a Fortune 500 budget, but you need security that won’t let you down. Microsoft 365 Business Premium gives you enterprise-grade protection at a price that won’t break the bank—and it’s the same system we use for our big clients. It scales, it’s supported, and it works.\nThis guide is not exhaustive, but it covers everything you need to get started.\nWhy Microsoft 365 Business Premium? # Enterprise-grade security (MFA, DLP, Defender, Intune, Conditional Access) for up to 300 users. Same tools as the big guys, but priced for SMBs. Community and Microsoft support if you get stuck. New 2025 add-ons (like the Microsoft Defender Suite) bring even more advanced protection. Identity Security: Lock Down Who Can Access What # 1. Create a Break Glass Account (Mandatory) # Why? If you lock yourself out or get hacked, this is your emergency backdoor.\nSetup:\nCreate a unique username (e.g., EmergencyAdmin-YourCompany). Set a long, unique password (16+ characters, mix of letters, numbers, symbols). Write it down and store it in a physical safe. Assign the Global Administrator role. Do NOT enable MFA on this account. If MFA breaks, this account is your lifeline. Pro Tip: If you want to add MFA to this account later, you can. I would recommend to use 2 FIDO keys and store them in separate locations.\n2. License Everyone for Business Premium # Why? You need the full security suite for every user.\nSteps:\nBuy Microsoft 365 Business Premium for every human user and your Break Glass account. Assign licenses via the Microsoft Admin Center. Remove old licenses (Business Basic/Standard) to avoid conflicts. Pro Tip: Use the license portal to stop paying for old licenses.\n3. Enforce Multi-Factor Authentication (MFA) for Everyone # Why? MFA blocks 99.9% of account takeovers.\nSetup:\nCreate a Conditional Access Policy named “MFA Enforcement.” Assign to all users, but exclude your Break Glass account. Apply to all cloud apps (Teams, Outlook, SharePoint, etc.). Set access control: Grant access only if MFA is passed. Disable Security Defaults (if enabled) to use your custom policy. Pro Tip: Use the Microsoft Authenticator app for the strongest MFA.\n4. Block Legacy Authentication # Why? Legacy protocols (POP, IMAP, SMTP) don’t support MFA and are prime attack vectors.\nSetup:\nCreate a new Conditional Access Policy. Assign to all users. Set condition: Client apps → “Other clients.” Action: Block access. Pro Tip: Double-check that your Break Glass account is excluded.\nData Security: Protect Your Files and Emails # 1. Store All Data in SharePoint and OneDrive # Why? Cloud storage is more secure than local servers and protects against ransomware, theft, and device loss.\nSetup:\nMove all business data to OneDrive (personal files) and SharePoint (team files). Enable Restricted Sharing to prevent accidental external sharing. Add trusted domains if you need to share with partners. Pro Tip: Use OneDrive Known Folder Move to auto-backup user desktops and documents.\n2. Set Up Data Loss Prevention (DLP) # Why? DLP stops accidental or malicious sharing of sensitive data (credit cards, SSNs, health records).\nSetup:\nGo to the Microsoft Purview compliance portal. Create a new DLP policy: Locations: Exchange, SharePoint, OneDrive, Teams. Sensitive info types: Use built-in templates (PII, PCI, HIPAA) or create custom ones. Actions: Block, audit, notify, or encrypt sensitive data. Test in audit mode before enforcing. Pro Tip: Start with Microsoft’s default DLP templates and customize as needed.\nDevice Security: Lock Down Laptops and Phones # 1. Enroll Devices in Intune # Why? Intune lets you manage and secure both company and personal devices.\nSetup:\nGo to the Intune admin center. Enroll devices: For company devices: Use Windows Autopilot for zero-touch setup. For BYOD: Use Mobile Application Management (MAM) to secure only work apps. Create compliance policies: Require minimum OS versions. Enforce encryption (BitLocker/FileVault). Block jailbroken/rooted devices. Pro Tip: Use Intune’s built-in compliance policies for a quick start.\n2. Enable Microsoft Defender for Endpoint # Why? Defender for Endpoint stops malware, ransomware, and advanced threats.\nSetup:\nGo to Intune → Endpoint security → Microsoft Defender for Endpoint. Onboard devices: Download the onboarding package. Create a new Endpoint protection profile in Intune and assign it to all devices. Configure ASR rules (see below). Pro Tip: Use Defender’s automated investigation and response to handle threats automatically.\n3. Require Windows Defender Firewall # Why? Firewalls block unauthorized network access.\nSetup:\nGo to Intune → Endpoint security → Firewall. Create a new firewall policy: Enable the firewall. Block all inbound connections (except for necessary exceptions, like Miracast for conference rooms). Pro Tip: Test firewall rules with a pilot group before rolling out to everyone.\nMobile Device Security: Secure Phones and Tablets # 1. Set Up Application Protection Policies (MAM) # Why? MAM secures company data in work apps without managing the entire device.\nSetup:\nGo to Intune → Apps → App protection policies. Create a policy for Office apps (Outlook, Teams, OneDrive): Require MFA for app access. Prevent data sharing between work and personal apps. Wipe only company data if the device is lost or the user leaves. Pro Tip: Send users this guide to help them set up their devices.\n2. Enroll Mobile Devices in Intune (Optional) # Why? Full device management gives you more control but is more invasive.\nSetup:\nFollow Intune’s mobile enrollment guides for iOS and Android. Assign compliance policies (minimum OS, encryption, etc.). Pro Tip: For Macs, treat them as mobile devices in Intune.\nBonus: Block Non-Registered Devices (Advanced) # Why? Only allow company-managed devices to access company data.\nSetup:\nCreate a new Conditional Access Policy. Assign to all users (exclude Break Glass). Apply to all apps. Set condition: Device state → Not compliant. Action: Block access. Caution: Only use this if all users have company-managed devices. If you use Macs or Chromebooks, skip this step.\nBonus: Attack Surface Reduction (ASR) Rules (For IT-Savvy Users) # Why? ASR rules stop common attack vectors, like malicious Office macros.\nSetup:\nGo to Intune → Endpoint security → Attack surface reduction. Create a new policy: Rule: Block Office apps from creating child processes (GUID: D4F940AB-401B-4EFC-AADC-AD5F3C50688A). Mode: Start with Audit to test, then switch to Block. Pro Tip: Use Microsoft’s ASR testing guide to validate your rules.\nFinal Checklist # Task Done? Created Break Glass account ☐ Assigned Business Premium licenses ☐ Enforced MFA for all users ☐ Blocked legacy authentication ☐ Moved data to SharePoint/OneDrive ☐ Set up DLP policies ☐ Enrolled devices in Intune ☐ Enabled Defender for Endpoint ☐ Configured firewall rules ☐ Set up mobile app protection ☐ (Optional) Blocked non-registered devices ☐ (Optional) Enabled ASR rules ☐ You’re Done! Now What? # Monitor your security posture in the Microsoft 365 Defender portal. Review your Secure Score for improvement tips. Train your team on security best practices (phishing, passwords, etc.). Ask for help if you get stuck—Microsoft’s community and support are there for you. References \u0026amp; Further Reading # Microsoft 365 Business Premium Security Overview Conditional Access Best Practices 2025 Data Loss Prevention in M365 Business Premium Attack Surface Reduction Rules ","date":"5 November 2025","externalUrl":null,"permalink":"/blog/posts/m365-security-guide/","section":"Blog","summary":"Guide to setting up security with M365 Business with minimum investment and technical skills","title":"M365 Business Security Guide","type":"blog"},{"content":"","date":"5 November 2025","externalUrl":null,"permalink":"/categories/post/","section":"Categories","summary":"","title":"Post","type":"categories"},{"content":"","date":"5 November 2025","externalUrl":null,"permalink":"/tags/security/","section":"Tags","summary":"","title":"Security","type":"tags"},{"content":"","date":"5 November 2025","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"15 October 2025","externalUrl":null,"permalink":"/tags/hugo/","section":"Tags","summary":"","title":"Hugo","type":"tags"},{"content":" Warning! Under construction! ","date":"15 October 2025","externalUrl":null,"permalink":"/projects/personal-website/","section":"Projects","summary":"Personal Website using Hugo Blowfish","title":"Personal Website","type":"projects"},{"content":"","date":"15 October 2025","externalUrl":null,"permalink":"/categories/project/","section":"Categories","summary":"","title":"Project","type":"categories"},{"content":"","date":"15 October 2025","externalUrl":null,"permalink":"/projects/","section":"Projects","summary":"","title":"Projects","type":"projects"},{"content":"","date":"15 October 2025","externalUrl":null,"permalink":"/tags/website/","section":"Tags","summary":"","title":"Website","type":"tags"},{"content":"","date":"13 October 2025","externalUrl":null,"permalink":"/tags/caddy/","section":"Tags","summary":"","title":"Caddy","type":"tags"},{"content":" Introduction # Snipe-IT is an open source IT Asset Management software (ITAM). It can be self hosted or hosted on their cloud platform.\nITAM is important because it helps organizations track and manage their technology resources efficiently, ensuring proper utilization. It can help maintaining up-to-date inventory of hardware and software assets, businesses can avoid unnecessary purchases, ensure compliance with licenses, and improve security by identifying vulnerabilities or outdated systems.\nIn this tutorial I will guide you through the steps to install and configure Snipe-IT on Debian 12, setup Snipe-IT and use Caddy to automatically reverse proxy and generate an SSL certificate.\nSteps # Step 1: Pre-requisites # You need docker installed on the vps as we will use the docker to install Snipe-IT. You can follow the instuctions on the docker\u0026rsquo;s official website.\nYou also need caddy installed in your system and can follow the instructions on Caddy\u0026rsquo;s website.\nCheck and update all other applications using the following.\nsudo apt update sudo apt upgrade Step 2: Installing Snipe-IT # Now we have Docker and Caddy installed on our system we use the following command to to create a directory to install Snipe-IT in.\nCreate a directory to install the app in and navigate into it.\nmkdir snipeit cd snipeit Download the docker-compose.yml file and .env files.\ncurl https://raw.githubusercontent.com/snipe/snipe-it/master/docker-compose.yml --output docker-compose.yml followed by\ncurl https://raw.githubusercontent.com/snipe/snipe-it/master/.env.docker --output .env Use the following command to generate an APP_KEY for the .env file.\ndocker compose run --rm app php artisan key:generate --show This is the .env file you need to edit.\nYou need to edit the following\nThe default port is 8000, if you have the port in use then you need to specify another port. Enter your generated APP_KEY Enter your custom domain Docker will default to latest if you leave APP_VERSION empty! You can select the version you want from Snipe-it on docker hub # -------------------------------------------- # REQUIRED: DOCKER SPECIFIC SETTINGS # -------------------------------------------- APP_VERSION= (Leave empty for latest, or enter version) APP_PORT=8000 # -------------------------------------------- # REQUIRED: BASIC APP SETTINGS # -------------------------------------------- APP_ENV=production APP_DEBUG=false # Please regenerate the APP_KEY value by calling `docker compose run --rm app php artisan key:generate --show`. Copy paste the value here APP_KEY=enter app key here APP_URL=https://snipeit.domain.com (Enter your custom domain here) # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ identifier APP_TIMEZONE=\u0026#39;UTC\u0026#39; APP_LOCALE=en-US MAX_RESULTS=500 # -------------------------------------------- # REQUIRED: UPLOADED FILE STORAGE SETTINGS # -------------------------------------------- PRIVATE_FILESYSTEM_DISK=local PUBLIC_FILESYSTEM_DISK=local_public # -------------------------------------------- # REQUIRED: DATABASE SETTINGS # -------------------------------------------- DB_CONNECTION=mysql DB_HOST=db DB_SOCKET=null DB_PORT=\u0026#39;3306\u0026#39; DB_DATABASE=snipeit DB_USERNAME=snipeit DB_PASSWORD=changeme1234 MYSQL_ROOT_PASSWORD=changeme1234 DB_PREFIX=null DB_DUMP_PATH=\u0026#39;/usr/bin\u0026#39; DB_DUMP_SKIP_SSL=true DB_CHARSET=utf8mb4 DB_COLLATION=utf8mb4_unicode_ci # -------------------------------------------- # OPTIONAL: SSL DATABASE SETTINGS # -------------------------------------------- DB_SSL=false DB_SSL_IS_PAAS=false DB_SSL_KEY_PATH=null DB_SSL_CERT_PATH=null DB_SSL_CA_PATH=null DB_SSL_CIPHER=null DB_SSL_VERIFY_SERVER=null # -------------------------------------------- # REQUIRED: OUTGOING MAIL SERVER SETTINGS # -------------------------------------------- MAIL_MAILER=smtp MAIL_HOST=mailhog MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_TLS_VERIFY_PEER=true MAIL_FROM_ADDR=you@example.com MAIL_FROM_NAME=\u0026#39;Snipe-IT\u0026#39; MAIL_REPLYTO_ADDR=you@example.com MAIL_REPLYTO_NAME=\u0026#39;Snipe-IT\u0026#39; MAIL_AUTO_EMBED_METHOD=\u0026#39;attachment\u0026#39; # -------------------------------------------- # REQUIRED: DATA PROTECTION # -------------------------------------------- ALLOW_BACKUP_DELETE=false ALLOW_DATA_PURGE=false # -------------------------------------------- # REQUIRED: IMAGE LIBRARY # This should be gd or imagick # -------------------------------------------- IMAGE_LIB=gd # -------------------------------------------- # OPTIONAL: BACKUP SETTINGS # -------------------------------------------- MAIL_BACKUP_NOTIFICATION_DRIVER=null MAIL_BACKUP_NOTIFICATION_ADDRESS=null BACKUP_ENV=true # -------------------------------------------- # OPTIONAL: CHANGE PHP UPLOAD LIMITS (UNCOMMENT WHEN NEEDING TO BE CHANGED) # -------------------------------------------- #PHP_UPLOAD_LIMIT=10 #PHP_POST_MAX_SIZE=10 #PHP_UPLOAD_MAX_FILESIZE=10 #PHP_MEMORY_LIMIT=10 # -------------------------------------------- # OPTIONAL: SESSION SETTINGS # -------------------------------------------- SESSION_LIFETIME=12000 EXPIRE_ON_CLOSE=false ENCRYPT=false COOKIE_NAME=snipeit_session COOKIE_DOMAIN=null SECURE_COOKIES=false API_TOKEN_EXPIRATION_YEARS=40 # -------------------------------------------- # OPTIONAL: SECURITY HEADER SETTINGS # -------------------------------------------- APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1,172.16.0.0/12 ALLOW_IFRAMING=false REFERRER_POLICY=same-origin ENABLE_CSP=false CORS_ALLOWED_ORIGINS=null ENABLE_HSTS=false # -------------------------------------------- # OPTIONAL: CACHE SETTINGS # -------------------------------------------- CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync CACHE_PREFIX=snipeit # -------------------------------------------- # OPTIONAL: REDIS SETTINGS # -------------------------------------------- REDIS_HOST=null REDIS_PASSWORD=null REDIS_PORT=6379 # -------------------------------------------- # OPTIONAL: MEMCACHED SETTINGS # -------------------------------------------- MEMCACHED_HOST=null MEMCACHED_PORT=null # -------------------------------------------- # OPTIONAL: PUBLIC S3 Settings # -------------------------------------------- PUBLIC_AWS_SECRET_ACCESS_KEY=null PUBLIC_AWS_ACCESS_KEY_ID=null PUBLIC_AWS_DEFAULT_REGION=null PUBLIC_AWS_BUCKET=null PUBLIC_AWS_URL=null PUBLIC_AWS_BUCKET_ROOT=null # -------------------------------------------- # OPTIONAL: PRIVATE S3 Settings # -------------------------------------------- PRIVATE_AWS_ACCESS_KEY_ID=null PRIVATE_AWS_SECRET_ACCESS_KEY=null PRIVATE_AWS_DEFAULT_REGION=null PRIVATE_AWS_BUCKET=null PRIVATE_AWS_URL=null PRIVATE_AWS_BUCKET_ROOT=null # -------------------------------------------- # OPTIONAL: AWS Settings # -------------------------------------------- AWS_ACCESS_KEY_ID=null AWS_SECRET_ACCESS_KEY=null AWS_DEFAULT_REGION=null # -------------------------------------------- # OPTIONAL: LOGIN THROTTLING # -------------------------------------------- LOGIN_MAX_ATTEMPTS=5 LOGIN_LOCKOUT_DURATION=60 RESET_PASSWORD_LINK_EXPIRES=900 INVITE_PASSWORD_LINK_EXPIRES=1500 # -------------------------------------------- # OPTIONAL: MISC # -------------------------------------------- LOG_CHANNEL=stderr LOG_MAX_DAYS=10 APP_LOCKED=false APP_CIPHER=AES-256-CBC APP_FORCE_TLS=false GOOGLE_MAPS_API= LDAP_MEM_LIM=500M LDAP_TIME_LIM=600 Step 3: Configuring Caddy # After setting up Snipe-IT, we must configure Caddy.\nUse the following command to open the CaddyFile\nsudo nano /etc/caddy/Caddyfile Clear out the default contents and paste the following in the file. Replace snipeit.domain.com with your actual domain.\nsnipeit.domain.com { reverse_proxy localhost:8000 } Save and restart Caddy service using the following command.\nsudo systemctl restart caddy Step 4: Start Snipe-IT # After configuring Caddy, move into your snipeit directory. Start the application using the following command.\ndocker compose up -d You can access your application on the URL mentioned in the CaddyFile and begin setting up your instance.\nUpdate # Since we are using the latest tag by default due to leaving APP_VERSION empty, we simply need to restart docker using the following to update.\ndocker compose down and\ndocker compose up -d If you are using a specific version, you would need to write the newer version tag in the APP_VERSION and restart docker using the above commands to update.\nConclusion # With this, your SnipeIT instance is now fully deployed and secured behind a reverse proxy, you have control over your IT assets.\nIf you run any issues or need further help, fell free to reach out via email or open a discussion\n","date":"13 October 2025","externalUrl":null,"permalink":"/blog/posts/deploying-snipeit/","section":"Blog","summary":"Guide to self hosting Snipe-IT asset management tool using Caddy for reverse proxy","title":"Self hosting Snipe IT ITAM tool","type":"blog"},{"content":"","date":"13 October 2025","externalUrl":null,"permalink":"/tags/selfhosted/","section":"Tags","summary":"","title":"Selfhosted","type":"tags"},{"content":"","date":"13 October 2025","externalUrl":null,"permalink":"/tags/vps/","section":"Tags","summary":"","title":"Vps","type":"tags"},{"content":" Introduction # Umami is a simple, lightweight, privacy focused alternative to Google Analytics. It is known for ease of use, cookie-free tracking, GDPR compliant analytics software.\nIt is free and open source, you can use their platform for hobby projects as they have a generous free tier. You can self host it in your server for free.\nIn this tutorial I will guide you through the steps to install and configure Umami on Debian 12, setup Umami and use Caddy to automatically reverse proxy and generate an SSL certificate.\nSteps # Step 1: Pre-requisites # You need docker installed on the vps as we will use the docker to install Umami. You can follow the instuctions on the docker\u0026rsquo;s official website.\nYou also need caddy installed in your system and can follow the instructions on Caddy\u0026rsquo;s website.\nCheck and update all other applications using the following.\nsudo apt update sudo apt upgrade Step 2: Installing Umami # Now we have Docker and Caddy installed on our system we use the following command to pull the Umami Git repository and then movie into the pulled directory.\ngit clone https://github.com/umami-software/umami.git \u0026amp;\u0026amp; cd umami/ Now we needs to make to adjustments to the Umami docker compose file. First, run the following command to generate a random string of characters, then copy it into the APP_SECRET in the file.\nopenssl rand -base64 32 Second change the ports to 127.0.0.1:3000:3000 in the file, it is to enhance security and ensure all traffic goes through your reverse proxy (Caddy).\nservices: umami: image: ghcr.io/umami-software/umami:postgresql-latest ports: - \u0026#34;127.0.0.1:3000:3000\u0026#34; environment: DATABASE_URL: postgresql://umami:umami@db:5432/umami DATABASE_TYPE: postgresql APP_SECRET: \u0026#34;paste your app secret here\u0026#34; depends_on: db: condition: service_healthy init: true restart: always healthcheck: test: [\u0026#34;CMD-SHELL\u0026#34;, \u0026#34;curl http://localhost:3000/api/heartbeat\u0026#34;] interval: 5s timeout: 5s retries: 5 db: image: postgres:15-alpine environment: POSTGRES_DB: umami POSTGRES_USER: umami POSTGRES_PASSWORD: umami volumes: - umami-db-data:/var/lib/postgresql/data restart: always healthcheck: test: [\u0026#34;CMD-SHELL\u0026#34;, \u0026#34;pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}\u0026#34;] interval: 5s timeout: 5s retries: 5 volumes: umami-db-data: If port 3000 is being used by some other application, then you need to change the port in the docker compose file and CaddyFile. Step 3: Configuring Caddy # After setting up Umami, we must configure Caddy.\nUse the following command to open the CaddyFile\nsudo nano /etc/caddy/Caddyfile Clear out the default contents and paste the following in the file. Replace umami.domain.com with your actual domain.\numami.domain.com { reverse_proxy localhost:3000 } Save and restart Caddy service using the following command.\nsudo systemctl restart caddy Step 4: Start Umami # After configuring Caddy, move into your Umami directory. Start Umami using the following command.\nsudo docker compose up -d This will pull the necessary images, start the containers in the background, and set Umami up and running at port 3000.\nYou can check if everything is running properly using\nsudo docker ps -a This will list all running containers. You should see both the umami and umami-db services listed and marked as Up.\nYou can now access Umami through your domain specified in CaddyFile.\numami.domain.com Log in using the default credentials\nUsername: admin Password: umami Before doing anything else, I strongly advise creating/ changing the admin username to something unique and change the a strong password. You can also create a new admin and delete the default one. Update # To update your Umami installation, simply pull the latest files from Github using\ngit pull After downloading the updated files. Simply restart docker.\ndocker compose down Followed by.\ndocker compose up -d Conclusion # With this, your Umami instance is now fully deployed and secured behind a reverse proxy, you have control over your analytics.\nFrom here, you can start adding websites, creating new users, setting up custom events.\nIf you run any issues or need further help, fell free to reach out via email or open a discussion\n","date":"11 October 2025","externalUrl":null,"permalink":"/blog/posts/deploying-umami/","section":"Blog","summary":"Guide to self hosting Umami analytics using Caddy for reverse proxy","title":"Self hosting Umami Analytics","type":"blog"},{"content":" Introduction # Plane is a modern project management platform. It is open source and offers a generous free plan and also a community edition.\nWe are using the community edition of Plane. You can know about Plane\u0026rsquo;s editions here.\nIn this tutorial I will guide you through the steps to install and configure Plane on Debian 12, setup Plane and use Caddy to automatically reverse proxy and generate an SSL certificate.\nSteps # Step 1: Pre-requisites # You need docker installed on the vps as we will use the docker to install Plane. You can follow the instuctions on the docker\u0026rsquo;s official website.\nYou also need caddy installed in your system and can follow the instructions on Caddy\u0026rsquo;s website.\nCheck and update all other applications using the following.\nsudo apt update sudo apt upgrade Step 2: Installing Plane # Now we have Docker and Caddy installed on our system we use the following command to to create a directory to install plane in.\nmkdir plane Move into the directory using.\ncd plane Download the latest stable release.\ncurl -fsSL -o setup.sh https://github.com/makeplane/plane/releases/latest/download/setup.sh Make the file executable\nchmod +x setup.sh Run the setup file using\n./setup.sh You will be prompted with options to run, select 1 to install, it will create a folder plane-app and will download the docker-compose.yaml and `plane.env\u0026rsquo; files.\nPress 8 to exit.\nNavigate into the plane-app directory using\ncd plane-app Open and edit the plane.env file using\nsudo nano plane.env Edit the following\nLISTEN_HTTP_PORT=80 to 8080 LISTEN_HTTPS_PORT=443 to 4430 WEB_URL=https://plane.domain.com (replace with your domain) CORS_ALLOWED_ORIGINS=https://plane.domain.com (replace with your domain) Port 80 and 443 are being used by Caddy, you need to add different ports in plane.env. Ports such as 8080 and 4430. This is your finished plane.env, you have no need to edit the docker-compose.yaml file.\nAPP_DOMAIN=localhost APP_RELEASE=v1.0.0 WEB_REPLICAS=1 SPACE_REPLICAS=1 ADMIN_REPLICAS=1 API_REPLICAS=1 WORKER_REPLICAS=1 BEAT_WORKER_REPLICAS=1 LIVE_REPLICAS=1 LISTEN_HTTP_PORT=8080 LISTEN_HTTPS_PORT=4430 WEB_URL=https://plane.domain.com DEBUG=0 CORS_ALLOWED_ORIGINS=https://plane.domain.com API_BASE_URL=http://api:8000 #DB SETTINGS PGHOST=plane-db PGDATABASE=plane POSTGRES_USER=plane POSTGRES_PASSWORD=plane POSTGRES_DB=plane POSTGRES_PORT=5432 PGDATA=/var/lib/postgresql/data DATABASE_URL= # REDIS SETTINGS REDIS_HOST=plane-redis REDIS_PORT=6379 REDIS_URL= # RabbitMQ Settings RABBITMQ_HOST=plane-mq RABBITMQ_PORT=5672 RABBITMQ_USER=plane RABBITMQ_PASSWORD=plane RABBITMQ_VHOST=plane AMQP_URL= # If SSL Cert to be generated, set CERT_EMAIl=\u0026#34;email \u0026lt;EMAIL_ADDRESS\u0026gt;\u0026#34; CERT_ACME_CA=https://acme-v02.api.letsencrypt.org/directory TRUSTED_PROXIES=0.0.0.0/0 SITE_ADDRESS=:80 CERT_EMAIL= # For DNS Challenge based certificate generation, set the CERT_ACME_DNS, CERT_EMAIL # CERT_ACME_DNS=\u0026#34;acme_dns \u0026lt;CERT_DNS_PROVIDER\u0026gt; \u0026lt;CERT_DNS_PROVIDER_API_KEY\u0026gt;\u0026#34; CERT_ACME_DNS= # Secret Key SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 # DATA STORE SETTINGS USE_MINIO=1 AWS_REGION= AWS_ACCESS_KEY_ID=access-key AWS_SECRET_ACCESS_KEY=secret-key AWS_S3_ENDPOINT_URL=http://plane-minio:9000 AWS_S3_BUCKET_NAME=uploads FILE_SIZE_LIMIT=5242880 # Gunicorn Workers GUNICORN_WORKERS=1 # UNCOMMENT `DOCKER_PLATFORM` IF YOU ARE ON `ARM64` AND DOCKER IMAGE IS NOT AVAILABLE FOR RESPECTIVE `APP_RELEASE` # DOCKER_PLATFORM=linux/amd64 # Force HTTPS for handling SSL Termination MINIO_ENDPOINT_SSL=0 # API key rate limit API_KEY_RATE_LIMIT=60/minute DOCKERHUB_USER=artifacts.plane.so/makeplane PULL_POLICY=if_not_present CUSTOM_BUILD=false Save and close the file.\nStep 3: Configuring Caddy # After setting up Plane, we must configure Caddy.\nUse the following command to open the CaddyFile\nsudo nano /etc/caddy/Caddyfile Clear out the default contents and paste the following in the file. Replace plane.domain.com with your actual domain.\nplane.domain.com { reverse_proxy localhost:8080 } Save and restart Caddy service using the following command.\nsudo systemctl restart caddy Step 4: Start Plane # After configuring Caddy, move into your plane-app directory. Start Plane using the following command.\nRun the setup file using\n./setup.sh Select 2, this will pull the necessary images, start the containers in the background, and set Plane up and running at port 8080.\nYou can check if everything is running properly using\nsudo docker ps -a This will list all running Plane containers, services listed and marked as Up.\nYou can now access Plane through your domain specified in CaddyFile.\nplane.domain.com You will be introduced to God mode in your first visit, following the instructions you can setup your plane instance and admin user.\nUpdate # Run the setup file using\n./setup.sh Select 5 to upgrade and then select 4 to restart, this will upgrade and then restart Plane.\nConclusion # With this, your Plane instance is now fully deployed and secured behind a reverse proxy, you have control over your project management.\nFrom here, you can start adding projects, views, and creating new users.\nIf you run any issues or need further help, fell free to reach out via email or open a discussion\n","date":"7 October 2025","externalUrl":null,"permalink":"/blog/posts/deploying-plane/","section":"Blog","summary":"Guide to self hosting Planem project management tool using Caddy for reverse proxy","title":"Self hosting Plane PM tool","type":"blog"},{"content":" Warning! Under construction! ","date":"11 March 2025","externalUrl":null,"permalink":"/spaces/movie_space/","section":"Spaces","summary":"“Movies are a machine that generates empathy.” Roger Ebert","title":"Movie Space","type":"spaces"},{"content":"","date":"11 March 2025","externalUrl":null,"permalink":"/tags/movies/","section":"Tags","summary":"","title":"Movies","type":"tags"},{"content":"","date":"11 March 2025","externalUrl":null,"permalink":"/tags/music/","section":"Tags","summary":"","title":"Music","type":"tags"},{"content":" Warning! Under construction! These are the soundtracks of my life, music I like listening to all the time.\nThese OST are awesome and really set the mood for working.\nWarhammer 40K: Mechanicus OST # Guillaume David is extremely talented. Mechanicus OST has a bass drop on a pipe organ, very similar to the Intestellar OST. Ixion OST # Mechanicus by Archotechna # ","date":"11 March 2025","externalUrl":null,"permalink":"/spaces/music_space/","section":"Spaces","summary":"“Without music, life would be a mistake.” Friedrich Nietzsche","title":"Music Space","type":"spaces"},{"content":"","date":"11 March 2025","externalUrl":null,"permalink":"/categories/spaces/","section":"Categories","summary":"","title":"Spaces","type":"categories"},{"content":"Welcome to Spaces where I explore and post about different aspects of my passion.\n","date":"11 March 2025","externalUrl":null,"permalink":"/spaces/","section":"Spaces","summary":"\u003cp\u003eWelcome to \u003cstrong\u003eSpaces\u003c/strong\u003e where I explore and post about different aspects of\n\u003cstrong\u003emy passion\u003c/strong\u003e.\u003c/p\u003e","title":"Spaces","type":"spaces"},{"content":"","date":"11 March 2025","externalUrl":null,"permalink":"/tags/tech/","section":"Tags","summary":"","title":"Tech","type":"tags"},{"content":" Warning! Under construction! ","date":"11 March 2025","externalUrl":null,"permalink":"/spaces/tech_space/","section":"Spaces","summary":"“Any sufficiently advanced technology is indistinguishable from magic.” Arthur C. Clarke","title":"Tech Space","type":"spaces"},{"content":"","date":"11 March 2025","externalUrl":null,"permalink":"/tags/tv/","section":"Tags","summary":"","title":"Tv","type":"tags"},{"content":" Warning! Under construction! ","date":"11 March 2025","externalUrl":null,"permalink":"/spaces/tv_space/","section":"Spaces","summary":"“TV is chewing gum for the eyes.” Frank Lloyd Wright","title":"TV Space","type":"spaces"},{"content":" Warning! Under construction! ","date":"1 January 2025","externalUrl":null,"permalink":"/blog/posts/mumbai/","section":"Blog","summary":"Random photos and notes about Mumbai","title":"Musings about Mumbai","type":"blog"},{"content":"","date":"1 January 2025","externalUrl":null,"permalink":"/tags/personal/","section":"Tags","summary":"","title":"Personal","type":"tags"},{"content":"","date":"1 January 2025","externalUrl":null,"permalink":"/tags/travel/","section":"Tags","summary":"","title":"Travel","type":"tags"},{"content":" About Me # Hello there! 👋\nMy name is Manav Mehta — an IT enthusiast, problem solver, and unapologetic tech aficionado. Welcome to my corner of the internet — a space where I document my journey through technology, learning, and the occasional digital experiment.\nWhile much of what I share revolves around IT operations, software, and automation, I also like to explore broader tech themes — from IoT tinkering to process frameworks like ITIL.\nOpinions expressed here are entirely my own.\nMy Journey # Technology has always been a part of my life — from the whirring sound of dial-up connections to the first time I typed a command in Linux. Here’s how it all began and where it’s taken me so far.\nEarly Days of Computing # Windows 2000 When Windows 2000 first booted on my screen, it felt like pure magic. Solitaire, pixelated icons, and that nostalgic startup sound — they were small windows (pun intended) into a world of endless curiosity. Back then, computers ran on less than a gigabyte of RAM, and every scratch on the silver installation CD was a potential tragedy. RoadRash was my first introduction to gaming, and I still remember the joy it brought.\nWindows 7 I skipped Windows Vista (thankfully, in hindsight) and jumped straight into Windows 7 — easily the most reliable OS experience I’ve had. It powered my early gaming sessions and countless experiments. My love affair with Windows probably peaked here.\nWindows 8 And then came Windows 8 — the OS that finally nudged me toward Linux. A touch-optimized interface made little sense on a desktop, but I still have fond memories of the Windows Phone era, especially my trusty Nokia Lumia 525. Microsoft’s dream of a unified OS was ahead of its time, just not quite ready.\nUbuntu \u0026amp; Beyond Like many seeking refuge from Windows 8, I found solace in Ubuntu. It was fast, intuitive, and came with a learning curve I grew to love. Command-line navigation, debugging, and system checks became part of my daily rhythm. Later, work and college projects brought me back to Windows (via WSL), but Linux has remained close to my heart.\nKDE \u0026amp; Linux Experiments Today, KDE Plasma is my go-to desktop environment — a perfect blend of flexibility and aesthetics. I’m currently experimenting with Debian 13, though I’ve spent time with OpenSUSE, Fedora, Mint, and Zorin over the years. (Confession: I’ve never used Arch, but I admire those who do!)\nHobbyist to Tech Enthusiast # My tech journey started as a hobby — helping friends and family troubleshoot computers, modding games, and fixing software issues (often for pocket money). Those early experiences planted the seed for what became a lifelong passion: understanding how technology works and how it can be made to work better.\nAreas of Expertise # IT Operations I specialize in making IT invisible — seamless, reliable, and intuitive. My goal is to ensure systems communicate flawlessly, automate workflows where possible, and let technology quietly empower people rather than frustrate them.\nITIL and Beyond Throughout my career, I’ve immersed myself in the ITIL framework — from incident and change management to IT asset and service management. Well-defined processes aren’t just documentation to me; they’re the blueprint for ensuring technology serves business needs effectively.\nPython — My Swiss Army Knife Python is my language of choice — versatile enough for automation, web development, data analysis, and IoT applications. It’s the tool I reach for when I need to turn ideas into reality quickly and cleanly.\nInternet of Things (IoT) My career began in an IoT startup, where I wrote Python for Raspberry Pi and C++ for Arduino. That experience gave me exposure to both software and hardware — and even pushed me into broader roles like product management, training interns, and engaging directly with customers.\nOther Interests I’ve also dabbled in C#, Java, and R. While Python remains my primary tool, I find R particularly elegant for statistical analysis — and I plan to revisit it as I explore more data-driven projects in the future.\nContact Me # Whether you’re here for collaboration, discussion, or just to say hi — I would love to hear from you! Say Hi! → You can use my social links on the home page. Technē Musings # Technē (τέχνη) — the ancient Greek word for art, craft, or the knowledge behind making something.\nMusings — thoughts, reflections, contemplations.\nTogether, Technē Musings is my open notebook — a living journal where I share what I’m learning, building, and thinking about. It’s my way of connecting with fellow curious minds who find beauty in the craft of technology.\nContinue # Curious to explore more? You can find my work and thoughts across these sections:\nProjects — ongoing and completed builds Writings — essays, tutorials, and reflections TV Space — thoughts on shows I’m watching Tech Space — deep dives and experiments Music Space — soundtracks to code by Movie Space — where technology meets storytelling ","externalUrl":null,"permalink":"/about/","section":"Home","summary":"\u003ch2 class=\"relative group\"\u003eAbout Me\n    \u003cdiv id=\"about-me\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#about-me\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eHello there! 👋\u003c/p\u003e\n\u003cp\u003eMy name is \u003cstrong\u003eManav Mehta\u003c/strong\u003e — an IT enthusiast, problem solver, and unapologetic tech aficionado.\nWelcome to my corner of the internet — a space where I document my journey through technology, learning, and the occasional digital experiment.\u003c/p\u003e","title":"About Me","type":"page"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":" Privacy Policy # Effective Date: October 1, 2025\nAt vanam.dev, your privacy is important. This website is designed to respect your privacy:\nNo personal data is collected by this site. Web analytics are performed using Umami, a cookieless analytics tool. Any data collected (e.g., page views, referrers, browser info) is anonymous and cannot identify individual users. Cookies: This website does not use cookies. Contact: If you have questions about privacy, you can reach us at contact@vanam.dev. By using this website, you agree to the practices described in this Privacy Policy.\nDistribution Rights # All content on vanam.dev, including text, images, and code snippets, is authored by the website owner unless otherwise noted.\nMost content is open source and may be freely reproduced, republished, or used commercially. For questions regarding content use, contact contact@vanam.dev. Terms and Conditions # By accessing or using vanam.dev, you agree to the following terms:\nUse of Content\nContent is provided for informational and educational purposes. You may not use this website to violate any laws or infringe on the rights of others. Accuracy of Information\nWhile every effort is made to ensure accuracy, the website owner makes no guarantees regarding the completeness or correctness of content. Limitation of Liability\nvanam.dev and its owner are not liable for any damages resulting from the use or inability to use this website. External Links\nThis website may link to other sites. The website owner is not responsible for the content or practices of external websites. Changes to Terms\nThese terms may be updated at any time without prior notice. Continued use of the website constitutes acceptance of updated terms. Governing Law\nThese terms are governed by the laws of the jurisdiction where the website owner resides. Contact: For questions regarding these legal statements, email contact@vanam.dev.\nFootnote: Some portions of this legal text were generated with the assistance of large language models (LLMs).\n","externalUrl":null,"permalink":"/legal/","section":"Home","summary":"\u003ch2 class=\"relative group\"\u003ePrivacy Policy\n    \u003cdiv id=\"privacy-policy\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#privacy-policy\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eEffective Date:\u003c/strong\u003e October 1, 2025\u003c/p\u003e","title":"Legal","type":"page"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]