Rails Pacific 2016

Server Infrastructure for Rails in 2016

Server Infrastructure for Rails in 2016

by Richard Lee

In Richard Lee's presentation at Rails Pacific 2016 titled "Server Infrastructure for Rails in 2016," he discusses contemporary trends in server infrastructure for Rails applications, drawing from his experiences at Cook, a recipe sharing website. The talk highlights the complexity developers face when transitioning code from development to production, emphasizing that while writing Rails code can be enjoyable, deploying it can be daunting. Lee presents several key strategies for improving server infrastructure in a Rails context:

  • Immutable Infrastructure with Docker: Containerizing applications is presented as a robust solution, enabling consistent environments from development to production. Docker, with its recent updates, has become stable and widely accepted in production settings. Lee encourages Rails developers to adopt Docker, despite initial apprehensions.

  • CI/CD Flow for Containerized Applications: Lee outlines the importance of continuous integration and continuous deployment. He details challenges faced when building Docker images in CI/CD environments, particularly with caching issues that can slow down builds. He recommends bringing your own CI server to manage persistence and speed up builds effectively.

  • Centralized Logging and Monitoring Systems: Lee emphasizes the necessity of a centralized logging system due to multiple small applications running concurrently. He shares his experience with Fluentd to manage logs, advocating for structured logging to facilitate easier analysis and troubleshooting.

  • Server Performance Tuning Best Practices: He discusses optimizing server performance through modern application architectures. Recommendations include using threaded servers like Puma instead of Unicorn, highlighting the advantages of shared processes in concurrent tasks. Lee stresses the importance of careful environment configuration to minimize issues when scaling applications.

Overall, Richard Lee underscores the importance of adopting these practices and technologies to improve the reliability, speed, and scalability of Rails applications in production environments. He concludes by encouraging developers to embrace these trends to alleviate deployment challenges and improve application performance.

00:00:13.309 I'm really honored to be one of the only two speakers at the Rails Pacific conference held in Taiwan. To be honest, the title of my talk, 'Server Infrastructure for Rails in 2016,' may sound a bit boring. Every time I put a year in my talk title, I feel like it won't be useful in the next year. However, I had the chance to talk with some Ruby and Rails friends about their work, and many of them expressed their feelings about deploying their Rails code. Many people complain about the confusion and panic they feel when trying to put their Rails code onto real-world servers.
00:00:35.370 We concluded that writing Rails code is fun, but running Rails applications can be challenging. I even had a conversation with a friend who has worked on many Rails projects. I asked him, 'Why don't you use Rails at work?' He simply replied that his boss was not familiar with it and expected them to upload code in a way that it would run automatically, like uploading PHP files via FTP. Today, I want to present some new concepts about server infrastructure, explaining how you can improve it to make your Rails applications run faster.
00:01:19.590 Let me introduce myself; I work for I Cook, which is just another recipe-sharing website using Rails. I've been focusing on Rails development for over ten years and have gained experience with infrastructure, which is why I'm here today. You can find me on Twitter under my username, so feel free to connect with me. If you have any feedback, please reach out, whether through email or social media.
00:02:12.930 Our website allows users to upload recipes either through our web platform or our mobile native app. Our main revenue comes from collaborations with brands and customers. You can see some promotional content on the right side of our homepage. Most of our recipes are curated by our community, which plays a significant role, especially when it comes to putting the right recipes under different categories. For example, during summer, people might be looking for refreshing ice cream recipes, and we need to showcase them prominently on our site.
00:02:58.530 Like many tech companies, we face various challenges while running our business. Despite the technical difficulties, we encounter unique hurdles because we operate multiple applications. Our main website serves as a social platform, but we also have e-commerce functionalities and a video site, as videos can better convey concepts in cooking than just text and images. Therefore, we’ve created different small websites, including Cook IQ TV and Cook IQ Market, and we are working on organizing them into distinct projects rather than lumping everything into a massive application.
00:04:06.600 One challenge we face is that our team members develop various small projects and want to get them online quickly. However, as our development grows, managing the complexities also compounds. Sometimes I think it can be confusing for newcomers, especially when they need to install various dependencies. For instance, if you want to install Jekyll, you'll need to handle Node.js and other dependencies first.
00:04:22.490 The process of onboarding new developers is also cumbersome. When I onboard someone, I explain that they need to install the Ruby specifications, Node.js, and other dependencies, like imagemagick. All these requirements often make the Rails environment quite complex. So, today's agenda is as follows: first, I will introduce how to containerize your app. Many of you might have heard about Docker, which is an important technology nowadays. I'll talk about how to make your Rails app more container-friendly, share experiences about setting up containers, and show you how to enable automated builds every time you push a commit.
00:05:03.560 Then I will demonstrate how to implement centralized logging and monitoring. Given that we have multiple small applications, logging into every server and checking log files is not practical. Finally, I’ll discuss recent improvements in the Ruby ecosystem and how to optimize your Rails server performance by configuring your environment.
00:05:59.259 Let’s begin with containerizing your app. Many of you might think of Docker when you hear about container technology. Even if you have used Heroku for your Rails deployments, you might already be benefiting from containerization. In fact, I would recommend using Heroku for your first deployment. This way, you can get used to a cloud-based environment without the hassle of configuration.
00:06:35.440 Docker is fairly stable nowadays, and it is a common question among friends whether using Docker in production is safe. In my experience, we have been running our projects in a Docker environment for about six months without major issues. Most of the bugs encountered were resolved with community contributions. I can confidently say that using Docker in production is viable now. Many companies, including large corporations like De Beers and Google, are now adopting Docker, and it’s getting easier to set up. Docker has also simplified the installation process, which is now straightforward for both Mac and Linux environments.
00:07:38.900 You might have heard that setting up Docker on Macs can be troublesome, but with the introduction of Docker for Mac, this has changed. It provides a simple package that can be installed like a normal application, making it very user-friendly. It eliminates the need for VirtualBox, making the entire process much simpler. If you’re a Yahoo employee, I recommend researching Docker support there since it can help you build an environment quickly.
00:08:14.450 Stay updated with the latest Docker tutorials. Since Docker has evolved significantly, ensure you check the tutorial versions to avoid confusion when following outdated instructions. In my case, I distinctively introduced Docker by comparing it to writing Rails code, which is usually straightforward. With Rails, there are many libraries available for user authentication and other functionalities. Docker is similar in that it boasts a strong community and offers a variety of ready-to-use base images.
00:08:59.230 For instance, there’s a Ruby base image that features Ruby and common libraries, allowing you to quickly set up your Docker environment. You can select from several base images available in Docker's repository. After choosing one, you can simply copy your project files into the Docker image and run commands to install additional dependencies. Setting up a minimal Docker environment is much simpler compared to traditional virtual machine images.
00:09:58.940 In traditional virtualization, you often build an image for an entire operating system, but with containers, you typically create an image for a specific process. This efficiency is what makes containers attractive; you can run your Rails app by specifying what you need directly in the Dockerfile and running it. I’m going to show you a simple example of a Docker setup for a Rails application, where the first line uses a Ruby base image. The next steps involve installing dependencies and setting up the project files. After that, you can run your Rails server with just a few commands.
00:10:57.880 This straightforward setup mirrors our actual work case quite closely. We enhance it by selecting the right base image and adding project files, as well as any required gems. The simplicity is emphasized by the Docker environment, allowing for quick iteration and deployment.
00:11:54.560 I also want to talk about some principles introduced by the Heroku co-founder, outlining the characteristics of a good web app. One key principle is to use environment configuration. This means avoiding hardcoding all configurations into your codebase, instead relying on environment variables for sensitive information. With Docker, you can apply the same principles. For instance, when handling assets, ensuring they are included within the container rather than being uploaded elsewhere.
00:13:14.160 This enables you to deploy changes without the risk of having inconsistent versions of assets. A recommended approach is to run only one process per container. Many frameworks utilize background processing solutions such as sidekiq. When using Docker, it's advisable to separate these processes into different containers— one for the web server and one for background tasks like sidekiq. By keeping one process per container, you can manage resources more effectively.
00:14:19.199 Another point is to utilize environment variable settings, similar to Heroku, so you can quickly define configurations when running your Docker containers. For example, you may set environment variables to manage database configurations or static file serving within your Rails application.
00:15:00.610 With the introduction of several environment variables within Rails itself, you can configure your project to write logs to standard output, which is crucial when deploying in containers. When using Docker, it is essential to direct your logs to standard output, as this facilitates the collection of logs by container management systems. I'll delve deeper into centralized logging solutions later.
00:15:59.927 To wrap up this section, I recommend ensuring your Rails app is container-ready even if you don’t plan to use Docker immediately. This might involve transitioning your configuration files to use environment variables, allowing for a smoother migration in the future.
00:16:42.297 I previously mentioned the significant advantages of containerizing your Rails app, but the real-world challenges remain, particularly regarding continuous integration and delivery. Building Docker images can be time-consuming, and our initial experience with CircleCI showed that testing could take significantly longer as dockerized builds run, sometimes upwards of 15 minutes.
00:17:29.264 Therefore, we manage our own CI servers to ensure our builds are efficient. By maintaining a persistent file system within our CI environment, we can carry dependencies without rebuilding everything from scratch each time. We leverage Jenkins for continuous integration, which simplifies Docker management and builds on existing patterns.
00:18:27.510 While many public CI services can optimize Docker build times through reusable cache layers, this approach can lead to inconsistency if not managed well. That’s where Jenkins shines; it allows us control over our build environment ensuring faster builds and less downtime.
00:19:37.910 Moreover, we can save Docker images in a shared filesystem, which speeds up build times as we avoid caching issues frequently encountered in public CI services. Even utilizing Docker Hub has been complimentary; it lets us retrieve images and build efficiently without losing consistency.
00:20:24.309 To enhance logging and monitoring in a containerized environment, we adopted Fluentd, which allows us to consolidate logs from multiple services into one location. It enables us to efficiently channel error logs and application logs into a centralized logging system. Fluentd integrates smoothly with Docker, processing logs in a unified manner, which is essential for maintaining oversight of distributed applications.
00:21:30.810 Furthermore, implementing Fluentd within your workflow can facilitate enriching your logs with contextual data, making it easier to troubleshoot. By configuring your log outputs correctly, you can pipeline logs into various destinations, whether it's an AWS service or an internal logging solution.
00:22:23.150 For Rails applications, integrating logging gems like Lograge can help format logs cleanly into single lines, which enhances your debugging capabilities. With Docker, you readily support logging into standard output, enabling you to collect those logs seamlessly.
00:23:15.430 Lastly, I want to address performance tuning for your server. Many factors contribute to the overall performance of your Rails application. Using a threaded web server like Puma can often yield better results compared to a non-threaded server. We’ve found users shifting towards Puma because of its capacity to manage multiple requests simultaneously, enabling high concurrency.
00:24:11.120 By optimizing your application server configurations and leveraging background job processing, such as Sidekiq or Resque, you can see significant performance boosts. For example, Sidekiq allows your application to process multiple jobs concurrently, making it more efficient compared to traditional single-threaded job processing.
00:25:09.620 The overall takeaway today is to approach your Rails application infrastructure with a mindset towards containerization and optimizing performance. Consider transitioning to a modern stack and rethinking legacy approaches. Modern practices can yield substantial performance uplift and provide your team with the flexibility to scale.
00:26:08.940 In summary, I want to propose a few trends that I believe will shape the Rails infrastructure landscape. First, start considering containerization for your applications. Regardless of whether you're using Docker or Heroku, modernizing your deployment strategies can simplify your processes.
00:27:03.560 Second, effectively address caching issues within your continuous integration environment to enhance efficiency and consistency. Building on that, prioritize establishing a centralized logging system early in your development lifecycle, enabling better oversight and troubleshooting capabilities for your applications.
00:27:58.890 Lastly, consider serious performance tuning with your app servers. Invest time in evaluating server types suitable for your workload and explore utilizing frameworks and tools that enable high concurrency and efficiency.
00:28:46.680 As I conclude this talk, I want to emphasize that while transitioning to these practices may seem daunting, investing in these improvements will pay off in better performance, developer experience, and infrastructure management. Thank you for your attention today, and I encourage you to consider whether your current setup can adapt to these proposed trends.
00:29:35.610 Before I finish, just a quick note that I’m hiring for various positions at my company. If you're interested, please come chat with me. I hope you found this session valuable!