<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Maxim McCain</title>
    <description>The latest articles on DEV Community by Maxim McCain (@mm-japan).</description>
    <link>https://dev.to/mm-japan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2564311%2Fdf0c26f5-e6d6-4d9e-9a5b-5fd03b2cf5b1.jpg</url>
      <title>DEV Community: Maxim McCain</title>
      <link>https://dev.to/mm-japan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mm-japan"/>
    <language>en</language>
    <item>
      <title>How I Built and Hosted My Own Server Using a Raspberry Pi: Lessons Learned</title>
      <dc:creator>Maxim McCain</dc:creator>
      <pubDate>Tue, 17 Dec 2024 06:55:46 +0000</pubDate>
      <link>https://dev.to/mm-japan/how-i-built-and-hosted-my-own-server-using-a-raspberry-pi-lessons-learned-409n</link>
      <guid>https://dev.to/mm-japan/how-i-built-and-hosted-my-own-server-using-a-raspberry-pi-lessons-learned-409n</guid>
      <description>&lt;h1&gt;
  
  
  How I Built and Hosted My Own Server Using a Raspberry Pi: Lessons Learned
&lt;/h1&gt;

&lt;p&gt;As developers, we often rely on cloud platforms like Heroku, AWS, or DigitalOcean to host our applications. But what if you could host your own projects, save money, and deepen your understanding of server management in the process? That’s exactly what I decided to do with a Raspberry Pi. In this post, I’ll share my journey, the challenges I faced, and what I learned from setting up and running my own server at home.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Build Your Own Server?
&lt;/h2&gt;

&lt;p&gt;When I started this project, I had three main goals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cost Savings&lt;/strong&gt;: Stop paying for hosting services like Heroku.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning&lt;/strong&gt;: Dive deeper into deployment, infrastructure, and DevOps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Showcasing My Work&lt;/strong&gt;: Make my portfolio and side projects accessible globally, running entirely on my own hardware.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hardware and Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raspberry Pi&lt;/strong&gt;: Affordable, energy-efficient, and surprisingly powerful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Tunnels&lt;/strong&gt;: To expose my local server to the internet securely and bypass shared-network restrictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby on Rails&lt;/strong&gt;: My portfolio and side project, &lt;strong&gt;CelebrantGPT&lt;/strong&gt;, are built on Rails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis and Sidekiq&lt;/strong&gt;: For background job processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Systemd&lt;/strong&gt;: To manage services and ensure everything starts automatically on reboot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting Up My Raspberry Pi
&lt;/h3&gt;

&lt;p&gt;The first step was to set up my Raspberry Pi as a production server. Here's what I did:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Installing Necessary Software
&lt;/h4&gt;

&lt;p&gt;I installed Ruby, Rails, PostgreSQL, Redis, and other tools needed for my Rails apps. I also installed a variety of additional tools and technologies to future-proof my server for upcoming projects, such as those that might use Python and other languages and frameworks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update the package list&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update

&lt;span class="c"&gt;# Install Ruby, Node.js (for Rails asset pipeline), and Yarn&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ruby-full nodejs yarn

&lt;span class="c"&gt;# Install PostgreSQL&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;postgresql postgresql-contrib

&lt;span class="c"&gt;# Install Redis&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;redis

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Deploying My Rails Apps
&lt;/h4&gt;

&lt;p&gt;I cloned my repositories, set up databases, and configured Rails for production. For my project, CelebrantGPT, I use Redis and Sidekiq to handle API requests as background jobs. If your project relies on similar services or technologies, you’ll need to install and configure them accordingly to ensure everything runs smoothly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone https://github.com/MM-Japan/celebrant_speech_generator.git
&lt;span class="nb"&gt;cd &lt;/span&gt;celebrant_speech_generator

&lt;span class="c"&gt;# Install gems and dependencies&lt;/span&gt;
bundle &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Set up the database&lt;/span&gt;
&lt;span class="nv"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production rails db:create db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Configuring Services with systemd
&lt;/h4&gt;

&lt;p&gt;To ensure my apps, Redis, and Sidekiq started on boot, I created systemd service files. This setup ensures that the Pi only needs to be powered on and connected to Wi-Fi to function as a server.&lt;/p&gt;

&lt;p&gt;Here’s an example for a Rails app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/systemd/system/celebrant.service
&lt;/span&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Celebrant Speech Generator&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pi&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/www/celebrant_speech_generator&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/bash -lc 'bundle exec rails server -e production'&lt;/span&gt;
&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="py"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"RAILS_ENV=production"&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exposing My Server to the Internet
&lt;/h2&gt;

&lt;p&gt;Since I live in a shared house and don’t have direct access to the router, traditional port forwarding wasn’t an option. This is where Cloudflare Tunnels came in. By routing traffic to my domains through the tunnel, I can expose the Pi's localhost to the web, making it globally accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Cloudflare Tunnels
&lt;/h2&gt;

&lt;p&gt;I installed cloudflared and created a tunnel to expose my server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install cloudflared&lt;/span&gt;
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; cloudflared-linux-arm64.deb

&lt;span class="c"&gt;# Authenticate with Cloudflare&lt;/span&gt;
cloudflared tunnel login

&lt;span class="c"&gt;# Create a new tunnel&lt;/span&gt;
cloudflared tunnel create portfolio-tunnel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a snippet of my config.yml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ~/.cloudflared/config.yml&lt;/span&gt;
&lt;span class="na"&gt;tunnel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;portfolio-tunnel&lt;/span&gt;
&lt;span class="na"&gt;credentials-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/pi/.cloudflared/portfolio-tunnel.json&lt;/span&gt;

&lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;www.maximmccain.com&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:3000&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;celebrant.maximmccain.com&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:3001&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http_status:404&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Challenges and How I Solved Them
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Debugging in Production&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Errors like "missing database user" and routing issues appeared only in production. To help reach the correct configuration for a production environment, I used journalctl to view systemd logs and debug errors. This was invaluable for troubleshooting services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View logs for a specific service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; celebrant.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;API Key Management&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ensuring API keys and credentials are secure in production is vital. If not encrypted correctly, or if committed to github accidentally, you expose your API keys to potential abuse. To avoid this, I used Rails credentials and .env files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Add to credentials.yml.enc&lt;/span&gt;
&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;openai_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your_openai_api_key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Full-Stack Understanding&lt;/strong&gt;: I learned about DNS, networking, and server management beyond coding.&lt;br&gt;
&lt;strong&gt;Automation is Key&lt;/strong&gt;: Setting up systemd services made deployment and maintenance far easier.&lt;br&gt;
&lt;strong&gt;The Value of Debugging Tools&lt;/strong&gt;: Logs and tools like curl were critical for diagnosing issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Hosting your own server might seem intimidating, but it’s incredibly rewarding. Not only does it save money, but it also gives you a deeper understanding of how applications run in production.&lt;/p&gt;

&lt;p&gt;If you’ve ever hosted your own apps or are considering it, I’d love to hear your thoughts or experiences. Let’s connect and share our learning journeys!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
