<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Shaun Chuah</title><description>IBD gastroenterologist and Clinical Senior Research Fellow at the University of Glasgow, building Foundry120 and ChatIBD for clinical research and care.</description><link>https://shaunchuah.com/</link><language>en-gb</language><item><title>Building the Research Operating System We Needed</title><link>https://shaunchuah.com/posts/building-the-research-operating-system/</link><guid isPermaLink="true">https://shaunchuah.com/posts/building-the-research-operating-system/</guid><description>Why we built Foundry120, a research operating system for translational science, and how its AI agent, Helix, turns plain-English questions into governed queries.</description><pubDate>Thu, 04 Jun 2026 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A while ago I wrote about the challenge of &lt;a href=&quot;https://shaunchuah.com/posts/multiomic-data-orchestration/&quot;&gt;orchestrating multi-omic data&lt;/a&gt; in translational research. That post described the problem. This one is about what we did next - we built &lt;a href=&quot;https://www.foundry120.com&quot;&gt;Foundry120&lt;/a&gt;, a research operating system for translational science.&lt;/p&gt;
&lt;h2 id=&quot;the-problem-restated&quot;&gt;The Problem, Restated&lt;/h2&gt;
&lt;p&gt;In modern translational research, the hard part is no longer generating data. Sequencing is cheap. Assays are routine. You can now do 6000 genes at subcellular resolution and pin their x,y coordinates?! Most groups are drowning in data, not starved of it.&lt;/p&gt;
&lt;p&gt;The hard part is knowing what you actually have. What samples exist? What clinical data do they link to? What clinical phenotype/treatment outcome are you looking for? Who is allowed to use them? Are they ready for the next research question, or do they need cleaning first, or do we need to recruit more participants?&lt;/p&gt;
&lt;p&gt;In practice, the answers to these questions live in too many places. Samples are tracked in one spreadsheet, clinical data sits in RedCap or even more excel files, omics outputs are scattered across different computers and hard drives, and the protocols and consent documents are in a shared drive somewhere. As I said in the earlier post, these files tend to be spread over multiple computers and held by different individuals. When you want to ask a simple question - ‘how many UC patients with anti-TNF failure have both microbiome data and biopsy samples?’ - you end up hunting multiple individuals down.&lt;/p&gt;
&lt;p&gt;This is the gap Foundry120 was built to close. It came out of years of running multi-site studies and the pain of experiencing the same problems over and over again.&lt;/p&gt;
&lt;h2 id=&quot;three-layers&quot;&gt;Three Layers&lt;/h2&gt;
&lt;p&gt;The earlier post ended on a principle I keep coming back to: embrace the complexity rather than fight it. You cannot force genomics, clinical records, proteomics, and histology into one tidy schema without losing something important. So instead of flattening everything, Foundry120 just accepts the complexity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Organise.&lt;/strong&gt; Sample and study tracking across multiple sites. This is foundational - knowing what physically exists. We now track over 30,000 samples, supporting six clinical studies as of writing, and seventeen sample types. Get this layer wrong and nothing above it can be trusted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Centralise.&lt;/strong&gt; This layer, which I have spent years thinking about, links clinical datasets, omics outputs, and documents together while preserving the data structures that already exist.  Let’s be honest, nobody has the time to make every file/folder structure the same.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Accelerate.&lt;/strong&gt; This is the layer that turns a well-organised data estate into answers. This is where the agentic AI unlock is.&lt;/p&gt;
&lt;h2 id=&quot;agentic-ai-as-a-unifying-force&quot;&gt;Agentic AI as a Unifying Force&lt;/h2&gt;
&lt;p&gt;This is the part I find most exciting, and it changes how I think about the whole problem. Helix is our AI agent, and building it is where my &lt;a href=&quot;https://shaunchuah.com/posts/agentic-ai-and-the-future-of-medicine/&quot;&gt;thinking about agentic AI in medicine&lt;/a&gt; stopped being a thought experiment.&lt;/p&gt;
&lt;p&gt;The idea is simple to state and hard to do well: a researcher asks a question in plain English, and Helix turns it into an approved query over governed data, returning charts and cohort summaries. ‘Show me samples belonging to patients with a particular genotype we are investigating’ should be a sentence, not a data request that takes a fortnight.&lt;/p&gt;
&lt;p&gt;In my agentic AI post I mentioned that the real unlock is tool calling - connecting probabilistic models to deterministic systems so an LLM can perform specific, reliable tasks. Helix is exactly that pattern applied to research data. It calls into a governed query layer that knows what data exists, what is allowed, and what links to what. The intelligence is in translating intent into the right query; the safety is in the deterministic layer underneath.&lt;/p&gt;
&lt;p&gt;We implemented a huge amount of context engineering/tool design given current model performance, which is extremely interesting and I have no doubt that as more capable models arrive, we can hopefully simplify some of these things we do to optimise LLM context windows.&lt;/p&gt;
&lt;p&gt;For decades, the only way to integrate inconsistent datasets was to standardise them first. You agreed on a schema (if you even manage to), then forced every source to conform to it (almost impossible) - the classic data warehouse approach. In the &lt;a href=&quot;https://shaunchuah.com/posts/multiomic-data-orchestration/&quot;&gt;orchestration post&lt;/a&gt; I explained why that breaks down for research: the data is dynamic and unstructured, the analysis requirements keep changing, and you cannot even define the ‘grain’ the way a retailer can for sales data. So you were left with a bad choice. Either expend an enormous amount of effort to harmonise the data, or leave everything fragmented and pay the cost every time you ask a question. In fact, it was totally unworkable.&lt;/p&gt;
&lt;p&gt;Agentic AI offers a third option, and this is the genuinely new thing. An LLM agent is comfortable with messiness in a way that traditional programming is not. It can all sorts of data (within certain limits and design choices), and reason about how they relate - even when one study calls a field &lt;code&gt;dob&lt;/code&gt;, another calls it &lt;code&gt;date_of_birth&lt;/code&gt;, and a third buried it in free text. The reconciliation that used to demand a fixed, upfront schema can now happen at query time, semantically, on demand.&lt;/p&gt;
&lt;p&gt;In other words, the agent becomes the integration layer. Not by forcing every dataset into one shape, but by understanding many shapes at once and bridging between them. This is exactly what lets the Centralise layer keep its promise of preserving existing structures. You no longer have to choose between standardisation and flexibility - the AI absorbs the inconsistency so the humans do not have to.&lt;/p&gt;
&lt;p&gt;I want to be careful not to oversell this. This is still extremely early. The agent still needs the deterministic layer underneath to ground it (and for heavier bioinformatic workflows we have to specify the parameters properly), and it still needs evals - a flexible reasoner over wrong data is just a faster way to be confidently wrong. But the direction is clear. For the first time, heterogeneity is not purely a tax to be paid. Handled well, agentic AI turns a pile of disparate, inconsistent datasets into something you can actually interrogate as a whole.&lt;/p&gt;
&lt;h2 id=&quot;what-30000-samples-taught-me&quot;&gt;What 30,000 Samples Taught Me&lt;/h2&gt;
&lt;p&gt;A few lessons stand out from building this for real rather than in theory.&lt;/p&gt;
&lt;p&gt;The boring layer is the most important one. Sample tracking is unglamorous, but it is the bedrock - an AI query layer sitting on messy provenance just produces confident wrong answers faster. Most of the value of Helix comes from the Organise and Centralise layers being right first.&lt;/p&gt;
&lt;p&gt;Meeting people where they are beats forcing a migration. The fastest way to kill adoption is to tell a research group that their existing workflow was wrong. Preserving existing structures and linking across them, rather than replacing them, is what made this usable.&lt;/p&gt;
&lt;p&gt;And governance is critical. In clinical research the audit trails, queries, tool calls and reasoning chain are needed to analyse how an answer was generated and importantly, to debug and improve the system when the agent gets it wrong.&lt;/p&gt;
&lt;h2 id=&quot;where-this-goes&quot;&gt;Where This Goes&lt;/h2&gt;
&lt;p&gt;In the agentic AI post I imagined ‘software-defined’ hospitals - data-sharing, AI integration, and rapid iteration as core principles rather than afterthoughts. Research infrastructure is the same story one step upstream. If we want AI agents that can reason over clinical and molecular data, they need a governed, well-organised substrate to reason over. That substrate does not build itself and is probably the most challenging issue preventing AI from achieving its promised benefits.&lt;/p&gt;
&lt;p&gt;Foundry120 is my attempt at building it. It is still early, but we are gaining huge value, time savings, and we see our team members spend more time focusing on fun and interesting research questions instead of trudging through tedious spreadsheets.&lt;/p&gt;
&lt;p&gt;And a sign of how fast this all moves: in my &lt;a href=&quot;https://shaunchuah.com/posts/agentic-ai-and-the-future-of-medicine/&quot;&gt;last post&lt;/a&gt; I was discussing Grok Code Fast 1 and GPT-5-Codex. Both have already aged like milk - at this point of writing, we’re on Opus 4.8 and GPT-5.5.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update: I talked through how Foundry120 came about on &lt;a href=&quot;https://talkpython.fm/episodes/show/560/building-a-research-os-from-django-to-30-000-samples&quot;&gt;Talk Python To Me, episode 560&lt;/a&gt;, and presented it at the &lt;a href=&quot;https://www.youtube.com/watch?v=ldIfC6bIJhw&quot;&gt;Microsoft Academic Research Exchange&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content:encoded><category>AI</category><category>Data engineering</category><category>Translational research</category></item><item><title>Agentic AI and the Future of Medicine</title><link>https://shaunchuah.com/posts/agentic-ai-and-the-future-of-medicine/</link><guid isPermaLink="true">https://shaunchuah.com/posts/agentic-ai-and-the-future-of-medicine/</guid><description>What agentic AI coding tools suggest for medicine: grounding LLMs, tool calling, an IBD surveillance agent and the software-defined hospital.</description><pubDate>Mon, 06 Oct 2025 09:54:00 GMT</pubDate><content:encoded>&lt;p&gt;I didn’t expect AI to change the way I code this much. This year alone, two models — Grok Code Fast 1 and GPT-5-Codex — have transformed how I work. Grok handles the small stuff, like fixing my poorly named variables. GPT-5-Codex, on the other hand, can build entire features on its own — for example, adding speech input with the Web Speech API.&lt;/p&gt;
&lt;p&gt;These tools show what’s now possible with “agentic AI” — models that can think and act for themselves. What once took weeks now takes hours, freeing up time to write posts like this (a rarity lately!). It’s hard to describe how revolutionary this feels. After years of managing several software projects, I finally have real help.&lt;/p&gt;
&lt;p&gt;When I return to an old project, I can just ask these models for a quick summary or even to add new features, instead of spending hours catching up. Boring but necessary jobs — like writing tests, cleaning up code, and updating dependencies — are now handled automatically. That’s made me far more productive and lets me focus on the creative work: architecture and design.&lt;/p&gt;
&lt;h2 id=&quot;thinking-about-large-language-models-llms-in-medicine&quot;&gt;Thinking about Large Language Models (LLMs) in Medicine&lt;/h2&gt;
&lt;p&gt;Watching these AI agents evolve makes me think about the future of LLMs in medicine, especially in inflammatory bowel disease. Two ideas stand out: &lt;strong&gt;tool calling&lt;/strong&gt; and &lt;strong&gt;agentic architectures&lt;/strong&gt;. Tool calling connects probabilistic and deterministic systems, so LLMs can perform specific tasks. Agentic architectures allow LLMs to decide which tools to use. This is a real game changer - it means we can automate complex workflows.&lt;/p&gt;
&lt;p&gt;But before that, the first step for medical applications is learning to ground an LLM in up-to-date and reliable medical knowledge. Just a few years ago, when ChatGPT first appeared, many criticised its hallucinations and inaccuracies. Fast-forward to today, and things are very different. I thought it’d be interesting to see if we can ground an LLM like ChatGPT in robust medical knowledge, which led to the launch of &lt;a href=&quot;https://www.chatibd.com&quot;&gt;ChatIBD&lt;/a&gt; - a fun project to test how well this tech works in practice. Although it is not perfect, I think it is surprisingly good. It’s also a glimpse into what future clinician-AI partnerships might look like.&lt;/p&gt;
&lt;p&gt;Once LLMs are grounded in reliable medical knowledge, we can then apply tool calling and agentic architectures.&lt;/p&gt;
&lt;h2 id=&quot;thought-experiment---the-ibd-surveillance-ai-agent&quot;&gt;Thought Experiment - The IBD Surveillance AI Agent&lt;/h2&gt;
&lt;p&gt;Let’s take a concrete example: an AI agent that manages IBD surveillance scopes. This feels technically feasible today. Here’s how it would work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The trigger - for example, in an outpatient IBD clinic, opening the EPR of a patient triggers the agent to begin.&lt;/li&gt;
&lt;li&gt;The AI agent uses the patient ID to lookup endoscopy/pathology reports and clinic letters, understanding the patient context - things like disease duration, extent, presence of PSC etc.&lt;/li&gt;
&lt;li&gt;Next, we add the relevant/up-to-date guidelines into its reasoning chain.&lt;/li&gt;
&lt;li&gt;Using all the right context, the agent then works out the appropriate interval for the next colonoscopy.&lt;/li&gt;
&lt;li&gt;It interfaces with the endoscopy booking system to find suitable slots.&lt;/li&gt;
&lt;li&gt;It presents a summary to the clinician and patient for review - allowing humans to account for things like holidays etc.&lt;/li&gt;
&lt;li&gt;Once confirmed, the appointment is booked.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Done right, this can improve adherence to surveillance guidelines, reduce the workload on clinicians and administrative staff, and improve patient outcomes. In addition, when guidelines change, updating the AI agent’s information will immediately send the change everywhere, ensuring that all patients receive care based on the latest evidence.&lt;/p&gt;
&lt;p&gt;The biggest challenge here isn’t AI, it’s the hospital’s existing software setup. Hospitals need sandbox environments to test and connect with existing EPRs (electronic patient records), which most large systems simply don’t have or are hidden behind a wall of bureaucracy. Hospitals will also need to build specific APIs (application programming interfaces) that allow AI systems to retrieve data from current databases. EPR systems have to become open and interoperable, but current vendor incentives rarely align with that.&lt;/p&gt;
&lt;h2 id=&quot;the-software-defined-hospital&quot;&gt;The ‘Software-Defined’ Hospital&lt;/h2&gt;
&lt;p&gt;Smaller, more agile hospital systems will likely be the first to adopt these AI workflows. Large hospital systems are likely to be hampered by legacy systems and procurement processes that are not agile enough to keep up with the rapid pace of AI development. Smaller hospitals can try and test new AI tools faster - much like how startups move quicker than large corporations. These changes could improve patient care and cut costs.&lt;/p&gt;
&lt;p&gt;Just like how Tesla, BYD and other new car manufacturers came up with the idea of the ‘software-defined’ vehicle, we’ll likely see ‘software-defined’ hospitals too. Data sharing, AI integration, and rapid iteration are going to be the core principles that enable future AI workflows.&lt;/p&gt;
&lt;p&gt;Interestingly, I think developing countries may actually leapfrog here. With fewer legacy constraints, bureaucracy, and stronger incentives for cost efficiency, they can iterate and adopt next-gen EPR systems purpose-built for AI workflows much faster.&lt;/p&gt;
&lt;p&gt;A quick word on regulation - too much could slow progress here. These systems are complex and too much bureaucracy could push the best builders elsewhere. We need people who understand the tech to strike the right balance - encouraging innovation while maintaining robust systems for safety and oversight.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That said, we’re in an exciting time for medicine. Scalable tools and smarter workflows will take away tedious tasks and make being a doctor much more enjoyable. These technologies will boost every doctor’s productivity, letting us focus on the many other parts of the job that matter most. I look forward to seeing how this space develops over the next few years.&lt;/p&gt;
</content:encoded><category>AI</category><category>IBD</category></item><item><title>Multi-omic Data Orchestration</title><link>https://shaunchuah.com/posts/multiomic-data-orchestration/</link><guid isPermaLink="true">https://shaunchuah.com/posts/multiomic-data-orchestration/</guid><description>Over the last few years, one of the key challenges we have faced in our multi-omic translational studies is the orchestration of multi-omic datasets.</description><pubDate>Fri, 13 Dec 2024 09:02:45 GMT</pubDate><content:encoded>&lt;p&gt;Over the last few years, one of the key challenges we have faced in our multi-omic translational studies is the orchestration of multi-omic datasets. In this blog post, I summarise some of the strategies we have employed to manage this complexity, after dedicating significant time to considering this problem.&lt;/p&gt;
&lt;h2 id=&quot;industry-data-warehousing&quot;&gt;Industry Data Warehousing&lt;/h2&gt;
&lt;p&gt;I recommend the Kimball book on data warehousing (&lt;em&gt;The Data Warehouse Toolkit: The Definitive Guide to Dimensional Modelling&lt;/em&gt;) as a starting guide to see what other people have done in tackling ‘big data’.&lt;/p&gt;
&lt;p&gt;The concept of dimensional modelling is also interesting because, in IBD studies, one of the big challenges is modelling drug data properly. I have personally seen all sorts of techniques used to model drug data, but each has its own shortcomings when performing complex analyses on them.&lt;/p&gt;
&lt;h2 id=&quot;the-challenge&quot;&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;Having said that, the data warehouse approach is not entirely applicable to research data workflows. It tends to be more suited to high-volume transactional data, where the data is relatively static and well-structured. In research, the data is often dynamic and unstructured, and the analysis requirements are constantly changing. This makes it difficult to design a data warehouse that can accommodate all possible analysis scenarios. It is hard to define the ‘grain’ compared to, for example, sales data for a retailer.&lt;/p&gt;
&lt;p&gt;Multi-omic data is complex and often requires a lot of data wrangling to get it into a format that is suitable for analysis. This is especially true when dealing with data from multiple sources, such as genomics, transcriptomics, proteomics, metabolomics, and clinical data. Each of these data types has its own unique characteristics and processing pipelines.&lt;/p&gt;
&lt;p&gt;Another major issue, particularly when working in a group, is that these data files tend to be spread over multiple computers and held by different individuals. How do we approach this complexity?&lt;/p&gt;
&lt;h2 id=&quot;embrace-the-complexity&quot;&gt;Embrace the Complexity&lt;/h2&gt;
&lt;p&gt;Initially, I spent a lot of time thinking about how to simplify things, but with experience, I have learned that we must embrace the complexity of this data landscape. This means that we must be prepared to integrate data from multiple sources, in multiple formats, and at multiple scales. This is not a trivial task and requires a lot of careful planning and coordination.&lt;/p&gt;
&lt;p&gt;I like to break down data into the following model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Structured data:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;RedCap/SQL databases.&lt;/li&gt;
&lt;li&gt;CSV/excel files.&lt;/li&gt;
&lt;li&gt;Easy to extract and transform.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unstructured data:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Raw -omic files such as fastq.&lt;/li&gt;
&lt;li&gt;Processed -omic files such as gene expression matrices, variant call files.&lt;/li&gt;
&lt;li&gt;Other types of unstructured file data such as video, images, histology slides etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-strategy&quot;&gt;The Strategy&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Structured data should be extracted, transformed, and loaded into a downstream database.&lt;/li&gt;
&lt;li&gt;Unstructured data should be stored in cloud object storage such as AWS S3 or Azure Blob Storage. This allows for easy programmatic access and therefore the ability to integrate these data files with structured data.&lt;/li&gt;
&lt;li&gt;Team members should be able to access both raw and processed files at certain stages necessary for their work. For example the seurat object used in single-cell analysis pipelines is a very specific data structure that needs accommodation.&lt;/li&gt;
&lt;li&gt;Use a data orchestrator to coordinate and manage the complexity of the data landscape.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;data-orchestrator&quot;&gt;Data Orchestrator&lt;/h2&gt;
&lt;p&gt;A data orchestrator is a tool that allows you to define data pipelines in code and automates the transformation, integration, and loading of data from multiple sources. This unifies and streamlines data processing workflows and can save team members a lot of time, providing easy access for someone with microbiome expertise to access genomic data and integrate the two.&lt;/p&gt;
&lt;p&gt;Another benefit of defining data transformations in code is the ability to version control your data pipelines, ensuring they are reproducible. This is particularly important for addressing the replicability issue in research, especially with increasingly complex data processing workflows.&lt;/p&gt;
&lt;p&gt;Another significant advantage is the ability to standardize the data dictionary across different studies. Often, researchers use slightly varied names or coding schemes for their variables. A data orchestrator enables you to define transformations and centralize the data dictionary, facilitating the integration of datasets and the reuse of data collected at considerable time and expense.&lt;/p&gt;
&lt;p&gt;There are a number of data orchestrators, and the most established is Apache Airflow, widely used in industry. However, it is a complex piece of software that takes significant expertise to set up and maintain. Managed services are offered by cloud providers, but they are expensive.&lt;/p&gt;
&lt;h2 id=&quot;dagster&quot;&gt;Dagster&lt;/h2&gt;
&lt;p&gt;Having tried a number of these tools, we have settled on &lt;a href=&quot;https://dagster.io/&quot;&gt;Dagster&lt;/a&gt;. Dagster adopts a declarative approach to data assets rather than a functional programming approach seen in other orchestrators. It also allows for easy scheduling and testing of data pipelines. More importantly, it is relatively easy for a small team to set up and run. We run it using Docker Compose and secure it with Caddy as a reverse proxy.&lt;/p&gt;
&lt;p&gt;We use Dagster to extract data from multiple sources and present it within G-Trac (our Django app) as a unified view. G-Trac maintains access control and audit logs for all data access. Team members can now visit a single point for all their data needs.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Investing time in solving this issue is worth it, as it enables data re-use and scalability, which are essential for comprehending the high-dimensional biological datasets produced by the latest biotechnologies. We’ll monitor our progress, and I may provide updates in the future.&lt;/p&gt;
&lt;p&gt;If you face a similar challenge, I recommend you look into data orchestrators, particularly Dagster. They can help tame the complexity of multi-omic data and provide a unified view of your data landscape. Having said that, none of this is trivial, so feel free to connect on X/Twitter if you have any questions.&lt;/p&gt;
</content:encoded><category>Data engineering</category><category>IBD</category><category>Translational research</category></item><item><title>How to Handle Big Data Uploads in Django</title><link>https://shaunchuah.com/posts/how-to-handle-big-data-uploads-in-django/</link><guid isPermaLink="true">https://shaunchuah.com/posts/how-to-handle-big-data-uploads-in-django/</guid><description>Handling non-trivial big data file uploads (think &gt;5gb/file) in Django can be challenging.</description><pubDate>Sun, 10 Dec 2023 18:59:15 GMT</pubDate><content:encoded>&lt;h2 id=&quot;traditional-file-uploads-in-django&quot;&gt;Traditional File Uploads in Django&lt;/h2&gt;
&lt;p&gt;Handling non-trivial big data file uploads (think &amp;gt;5gb/file) in Django can be challenging. A typical file upload storage strategy in Django is to use django-storages and an Amazon S3 backend. In the traditional way, your browser uploads the file directly to Django which then transmits the data to S3.&lt;/p&gt;
&lt;p&gt;This creates two problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Django needs to have enough memory to hold your uploaded file for retransmission.&lt;/li&gt;
&lt;li&gt;The Django worker receiving the file upload is blocked until the upload is finished.&lt;/li&gt;
&lt;li&gt;Streaming the upload onwards to S3 doubles the amount of bandwidth used.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-if-we-could-instead-upload-directly-into-aws-s3-while-registering-the-upload-with-django&quot;&gt;What if we could instead upload directly into AWS S3 while registering the upload with Django?&lt;/h2&gt;
&lt;p&gt;I stumbled across this excellent article by Radoslav Georgiev of HackSoft: &lt;a href=&quot;https://www.hacksoft.io/blog/direct-to-s3-file-upload-with-django&quot;&gt;https://www.hacksoft.io/blog/direct-to-s3-file-upload-with-django&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It’s a slightly complicated set-up but in essence, when the browser wants to perform an upload, it tells Django so and Django gives it a pre-signed S3 URL which will accept the upload.&lt;/p&gt;
&lt;p&gt;The upload is then performed directly by the browser to S3. On completion, S3 lets the browser know it was successful and the browser then informs Django that the upload is successful.&lt;/p&gt;
&lt;p&gt;This forms the basis of big data handling in Django and allows browsers to connect directly to S3 which in itself is an amazing capability. I highly recommend you check out the linked tutorial above!&lt;/p&gt;
</content:encoded><category>Data engineering</category><category>Web development</category></item><item><title>Launching Nextflow Pipelines From the Cloud</title><link>https://shaunchuah.com/posts/launching-nextflow-pipelines-from-the-cloud/</link><guid isPermaLink="true">https://shaunchuah.com/posts/launching-nextflow-pipelines-from-the-cloud/</guid><description>How to set up an Ubuntu server on DigitalOcean, install Nextflow and launch your pipelines from the cloud.</description><pubDate>Thu, 28 Apr 2022 18:29:04 GMT</pubDate><content:encoded>&lt;h2 id=&quot;why-bother-setting-up-another-server-to-manage-your-nextflow-pipeline&quot;&gt;Why bother setting up another server to manage your Nextflow pipeline?&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Avoid premature termination of the pipeline&lt;/strong&gt;. When you run a Nextflow pipeline from your local computer, your local computer is managing the tasks and communicating with Azure as jobs are completed. Depending on the complexity of your pipeline, this may be a long time (couple of days!). If your wi-fi router accidentally comes unplug or the connection is broken, the pipeline will terminate prematurely. While you could recover from this using &lt;code&gt;-resume&lt;/code&gt;, you can avoid the risks of disconnection by using a cloud server, which is designed to run 24/7, to orchestrate this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Location independence&lt;/strong&gt;. You can start a pipeline from home (wfh being the consequence of covid) and perhaps go elsewhere and check in later.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Free up your local computer for other things&lt;/strong&gt;. You do not have to keep your local computer running Nextflow constantly - just start the pipeline in the cloud and continue on with your usual day.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;obtaining-a-cloud-server&quot;&gt;Obtaining a cloud server&lt;/h2&gt;
&lt;p&gt;Plenty of hosting providers provide you with access to a VPS (Virtual Private Server) running Ubuntu 20.04. My recommendation is DigitalOcean - fantastic documentation, much cheaper compared to AWS/Azure/GCP, good performance and reliability in my experience. The $5/month server is what I personally use and is more than capable of handling Nextflow.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-an-ubuntu-server-on-digitalocean&quot;&gt;Setting up an Ubuntu server on DigitalOcean&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://shaunchuah.com/media/do_droplet_creation.png&quot; alt=&quot;DigitalOcean VPS Setup&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;server-authentication&quot;&gt;Server authentication&lt;/h3&gt;
&lt;p&gt;For authentication, select SSH key to access your server from the terminal (mac/linux) or using PuTTY (windows):
&lt;img src=&quot;https://shaunchuah.com/media/do_droplet_ssh.png&quot; alt=&quot;DigitalOcean SSH Setup&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;logging-in-to-the-server&quot;&gt;Logging in to the server&lt;/h2&gt;
&lt;p&gt;Once your server is set up, log in to it.&lt;/p&gt;
&lt;p&gt;Mac/Linux:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;ssh&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -i&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;private_key.pe&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; root@&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;server_i&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Windows I suggest using the PuTTy client. Depending on your choice of VPS and platform, you may wish to consult this guide: &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-20-04&quot;&gt;https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-20-04&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
&lt;p&gt;Install Java and screen first.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; apt&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; apt&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; default-jre&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; screen&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will install Nextflow in /nextflow. You can change this location if you wish.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; /nextflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -s&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; https://get.nextflow.io&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt; bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then need to add this directory to PATH. Doing this allows you to type &lt;code&gt;nextflow&lt;/code&gt; directly into the terminal. Open .bashrc file to begin.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;nano&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; ~/.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the bottom, add the following line:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; PATH&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;“/nextflow:$PATH”&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# this line is optional&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; NXF_DEFAULT_DSL&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# I am using DSL1 as per the docs when I was setting up my pipeline.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# If you are using DSL1 you will need to add this to .bashrc.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save and exit with &lt;code&gt;Ctrl+X&lt;/code&gt; and &lt;code&gt;yes&lt;/code&gt;. Next, we need to source the file.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; ~/.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;check-nextflow-works&quot;&gt;Check Nextflow works&lt;/h2&gt;
&lt;p&gt;If everything is installed correctly, typing &lt;code&gt;nextflow&lt;/code&gt; into the terminal should show the program help screen.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;nextflow&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;clone-and-run-the-pipeline&quot;&gt;Clone and run the pipeline&lt;/h2&gt;
&lt;p&gt;Now it’s time to bring in your pipeline using the power of git.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; clone&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;your_nextflow_pipeline_repositor&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;y&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, I would put in&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; clone&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; https://github.com/shaunchuah/cfdna_nextflow/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and this will bring in my pipeline at &lt;code&gt;~/cfdna_nextflow&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For my pipeline I would need to clone &lt;code&gt;sample_credentials.json&lt;/code&gt; to &lt;code&gt;credentials.json&lt;/code&gt; and fill it in with my Azure credentials.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; ~/cfdna_nextflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;cp&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; sample_credentials.json&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; credentials.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;nano&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; credentials.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can launch the pipeline!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;nextflow&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; pipeline.nf&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -resume&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -profile&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now your cloud server is orchestrating the cloud cluster! But let’s take this one step further…&lt;/p&gt;
&lt;h2 id=&quot;use-screen-to-launch-long-running-pipelines&quot;&gt;Use screen to launch long-running pipelines&lt;/h2&gt;
&lt;p&gt;Reference: &lt;a href=&quot;https://www.howtogeek.com/662422/how-to-use-linuxs-screen-command/&quot;&gt;https://www.howtogeek.com/662422/how-to-use-linuxs-screen-command/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here’s what I do when launching pipelines that may take days to weeks to complete. Create a screen session:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;screen&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If this is the first time, there will be some text. Hit enter and it all disappears but you are now in a screen session. Try any command - eg. &lt;code&gt;nextflow&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To detach from the screen session, hit &lt;code&gt;Ctrl+A&lt;/code&gt; and &lt;code&gt;D&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To list all screen sessions type &lt;code&gt;screen -ls&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To reattach to the screen session type &lt;code&gt;screen -r&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I launch my pipelines from within screen and hit &lt;code&gt;Ctrl+A&lt;/code&gt; and &lt;code&gt;D&lt;/code&gt; to detach. Now I can safely close my SSH connection to the server and the pipeline will remain running. Reconnect to the server and type &lt;code&gt;screen -r&lt;/code&gt; and you will see that the pipeline remains running. This nifty trick will help avoid pipelines terminating because of flaky connections and give you true mobility to perform bioinformatics from anywhere with an internet connection.&lt;/p&gt;
&lt;p&gt;It also means that in 2022, you no longer need powerful desktop computers to run bioinformatics anymore. All you need is a credit card and you can access vast computing power way beyond any single machine is capable of.&lt;/p&gt;
&lt;p&gt;I hope you’ve found this series helpful. If this has helped you please let me know on Twitter!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Bonus: If you want to take this even further, you could have a powerful cloud server to develop on using VSCode Remote Containers. Check out &lt;a href=&quot;https://github.com/features/codespaces&quot;&gt;GitHub Codespaces&lt;/a&gt; as an example of this.&lt;/em&gt;&lt;/p&gt;
</content:encoded><category>Bioinformatics</category><category>Nextflow</category></item><item><title>Setting Up Azure With Nextflow</title><link>https://shaunchuah.com/posts/setting-up-azure-with-nextflow/</link><guid isPermaLink="true">https://shaunchuah.com/posts/setting-up-azure-with-nextflow/</guid><description>Why I chose Azure over AWS and Google Cloud for Nextflow, and a step-by-step guide to running pipelines with Azure Batch and Storage.</description><pubDate>Wed, 18 Aug 2021 18:27:01 GMT</pubDate><content:encoded>&lt;p&gt;We will cover getting your nextflow pipeline up and running in the cloud using Azure. First thing to note, this process will take some time so sit back, grab a coffee and take your time working through each section.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Useful References&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nextflow documentation &lt;a href=&quot;https://www.nextflow.io/docs/edge/azure.html&quot;&gt;here&lt;/a&gt;.
Nextflow blog post &lt;a href=&quot;https://www.nextflow.io/blog/2021/introducing-nextflow-for-azure-batch.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;Let’s start with some context. I’m working with a small team of immunology researchers who are following their scientific questions which has led  into genomics. We don’t have any bioinformatics setup and are starting from nothing - which is probably going to be the case for many newcomers as NGS technology continues to become more accessible (for example Nanopore sequencing).&lt;/p&gt;
&lt;p&gt;The University has a compute cluster but it is equally challenging to get up and running there as on the cloud. In 2021, if you are starting from scratch, I would recommend a cloud-first approach as the cloud allows scalability way beyond any high performance compute cluster at a fraction of the cost. Also, you can access the cloud from anywhere and do not have to setup VPNs etc. to use a university network.&lt;/p&gt;
&lt;h2 id=&quot;why-azure-over-gcpaws&quot;&gt;Why Azure over GCP/AWS?&lt;/h2&gt;
&lt;p&gt;When I first attempted to get Nextflow up and running in the cloud, naturally AWS (Amazon Web Services) was the first contender. For those of you new to cloud computing, AWS is the most established player having been around the longest.&lt;/p&gt;
&lt;p&gt;However, following the Nextflow documentation requires you to create a custom Amazon Machine Image that has awscli installed and no matter how many different attempts I tried, I just couldn’t get it to work properly. I suspect updates to Amazon’s infrastructure have changed the previous instructions available on the internet.&lt;/p&gt;
&lt;p&gt;After Amazon, I tried Google Cloud using their Cloud Life Sciences API and Nextflow. It was incredibly easy to get things up and running however I soon ran into limitations on vCPU quota. Google limits new accounts to 8 vCPUs even though you have put your credit card on and upgraded your account.&lt;/p&gt;
&lt;p&gt;When I contacted Google Support about increasing the quota, they replied and suggested contacting one of their partners and sent a link with a list of maybe a hundred companies, of which you would have no idea who would do bioinformatics. Also, I’m really not interested in going through a third party to get my account running. I might also mention my slight worry that Google does not have a great track record of supporting their non-advertising projects. &lt;a href=&quot;https://killedbygoogle.com/&quot;&gt;See Here&lt;/a&gt; (I will never forget Google Reader!)&lt;/p&gt;
&lt;p&gt;Finally, after much time spent on the above two, I had nothing to lose giving Azure a try. Initially, Azure’s interface was almost as complex as AWS. However, once you set it up, &lt;strong&gt;Azure support were the most responsive in getting your vCPU quota up&lt;/strong&gt;. Within 30 minutes of setting up my account I obtained 48 vCPUs and subsequently had it increased to 128 with very little hassle at all.&lt;/p&gt;
&lt;p&gt;Therefore, if you’re going to do what I did, I would highly recommend you try Azure first and this is my documentation of what worked in the end after about 2 weeks of effort.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-your-azure-account&quot;&gt;Setting Up Your Azure Account&lt;/h2&gt;
&lt;p&gt;Let’s kick things off. First, sign up for an &lt;a href=&quot;https://azure.microsoft.com&quot;&gt;Azure&lt;/a&gt; account (that pretty much goes without saying).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shaunchuah.com/media/azure_dashboard.png&quot; alt=&quot;Azure dashboard&quot;&gt;
&lt;em&gt;Azure Cloud Dashboard&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here’s the important bit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Once you have your Azure account, within Azure, you need to create two accounts: one Azure Batch account and one Azure Storage account.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;batch-and-storage-account-creation&quot;&gt;Batch and Storage Account Creation&lt;/h3&gt;
&lt;p&gt;Login into Azure Portal and search for ‘batch’ in the top bar. You should then click on Batch accounts. Create a batch account name and the location where you want to run your compute. When you are creating your batch account, it will ask you to associate a storage account - now is a good time to create your storage account as well.&lt;/p&gt;
&lt;h3 id=&quot;create-a-storage-container&quot;&gt;Create A Storage Container&lt;/h3&gt;
&lt;p&gt;Once you have your storage account, enter it and click on containers in the left menubar. Then click ‘+ container’ and set up a ‘blob’ - this is equivalent to Amazon S3 and will function as the filesystem Azure Batch will read and write files to.&lt;/p&gt;
&lt;h3 id=&quot;get-your-account-keys&quot;&gt;Get Your Account Keys&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://shaunchuah.com/media/batch_account.png&quot; alt=&quot;Batch account keys&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Batch account:&lt;/strong&gt; Enter your batch account and click ‘Keys’ in the left menubar. Take a note of the name and key1.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shaunchuah.com/media/storage_account.png&quot; alt=&quot;Storage account keys&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Storage account:&lt;/strong&gt; Enter your storage account and click ‘Access Keys’ in the left menubar. Again, take note of the storage account name and key1.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That’s it for this step. Now it’s time to setup Nextflow.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;configuring-nextflow&quot;&gt;Configuring Nextflow&lt;/h2&gt;
&lt;p&gt;I’m going to show you an example configuration here and explain it in detail. The details of your configuration will depend on your pipeline and compute requirements. I hope this serves as an easy template to follow. See the previous post for the nextflow pipeline.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;profiles {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  az {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;reads &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/test_data/*/*_{R1,R2}_*.fastq.gz&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;outdir &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/test_reports&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;bowtie2_reference_index &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/bt2_index.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;kraken2_db &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/k2_standard_8gb_20210517.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;metaphlan_db &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/metaphlan_db.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;cpus &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      process&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;executor &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;azurebatch&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      workDir &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/work/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      azure {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          storage {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountName &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;storageAccountName&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountKey &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;storageAccountKey&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          batch {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              location &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;uksouth&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountName &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;batchAccountName&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountKey &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;batchAccountKey&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              autoPoolMode &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              pools {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                  auto {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                      vmType &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;Standard_D16_v3&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                      maxVmCount &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                      autoScale &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  az_prod {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;reads &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/data/*/*_{R1,R2}_*.fastq.gz&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;outdir &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/reports&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;bowtie2_reference_index &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/bt2_index.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;kraken2_db &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/k2_standard_20210517.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;metaphlan_db &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/metaphlan_db.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;cpus &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      process&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;executor &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;azurebatch&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      workDir &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/production_work/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      azure {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          storage {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountName &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;storageAccountName&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountKey &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;storageAccountKey&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          batch {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              location &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;uksouth&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountName &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;batchAccountName&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              accountKey &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt; azure_config[&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;batchAccountKey&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              autoPoolMode &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              pools {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                  auto {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                      vmType &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;Standard_D16_v3&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                      maxVmCount &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                      autoScale &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;                  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;create-test-and-production-profiles&quot;&gt;Create test and production profiles&lt;/h3&gt;
&lt;p&gt;In your nextflow.config file - set up profiles. I’ve set up two profiles which are almost identical. One is for testing and the other is when you actually want to run the real workflow. In the following example my test profile is named ‘az’ and the production profile is ‘az_prod’. Feel free to change it to what you want.&lt;/p&gt;
&lt;h3 id=&quot;lets-break-it-down&quot;&gt;Let’s break it down&lt;/h3&gt;
&lt;p&gt;First, let’s start with pipeline parameters. This will probably be different to your application. I’ve identified where my data resides and where I want my reports to be placed.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;reads &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/data/*/*_{R1,R2}_*.fastq.gz&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;outdir &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/reports&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-major-points-to-note-here&quot;&gt;2 Major Points to Note Here&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;bowtie2_reference_index &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/bt2_index.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;kraken2_db &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/k2_standard_20210517.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;metaphlan_db &lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;az://scgenomics/metaphlan_db.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt; Azure’s containers doesn’t work like a real filesystem. When using reference databases I found that the pipeline doesn’t read folders. What I’ve done is zipped up the reference DBs and unzipped them in the process so that the database is copied over to the VM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Second Point&lt;/strong&gt; I would upload a copy of the reference database to your storage account. This is because pulling files from your storage account to the VM is really fast whereas if you asked the VM to download the database from the original external servers you are going to cause two major problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It’s much slower downloading a database from S3 to Azure.&lt;/li&gt;
&lt;li&gt;You’re going to incur high bandwidth transfer costs both for yourself and for the team hosting the database. Not a great idea to download 20GB everytime you run a single process.&lt;/li&gt;
&lt;li&gt;Be nice and considerate to the kind folks who host the databases&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Therefore, download a single copy of the reference database, zip it up and put it in your storage container.&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;  params.cpus&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This just allows me to tweak the number of cores and is completely optional. My local machine has only 4 while I use 16 core VMs on Azure. On the process side of Nextflow I declare the cpus option as a variable that allows me to tweak the entire pipeline with a change of a single number.&lt;/p&gt;
&lt;p&gt;Here’s a brief snippet to give you an idea (pipeline.nf file):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; bowtie2&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    container&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;biocontainers/bowtie2:v2.4.1_cv1&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    cpus&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$params&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;.cpus&quot;.toInteger&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;finally-the-magic&quot;&gt;Finally the magic&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;  process.executor&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;azurebatch&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;  workDir&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;az://scgenomics/production_work/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;  azure&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;      storage&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          accountName&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; azure_config[&quot;storageAccountName&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          accountKey&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; azure_config[&quot;storageAccountKey&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;      batch&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          location&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;uksouth&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          accountName&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; azure_config[&quot;batchAccountName&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          accountKey&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; azure_config[&quot;batchAccountKey&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          autoPoolMode&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;          pools&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;              auto&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;                  vmType&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;Standard_D16_v3&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;                  maxVmCount&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;                  autoScale&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;              }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This block configures Azure Batch settings. You will see that I run &lt;code&gt;Standard_D16_v3&lt;/code&gt; machines and I use up to 8 VMs for my pipeline. Have a look at &lt;a href=&quot;https://azure.microsoft.com/en-gb/pricing/details/virtual-machines/series/&quot;&gt;Azure’s VMs&lt;/a&gt; to have an idea of what machines are available. Your settings for this will be entirely dependent on your quotas and what you’re trying to run. Since kraken2 requires 64GB of RAM those are the VMs I’ve selected.&lt;/p&gt;
&lt;h2 id=&quot;separating-credentials-out-of-nextflow-config&quot;&gt;Separating Credentials Out of Nextflow Config&lt;/h2&gt;
&lt;p&gt;I’m assuming you are using git to version track your code. There are other tutorials on how to do that so look it up if you don’t. Personally I commit my code to GitHub and would suggest you do something similar as it will allow further cool automations that I will cover in the future.&lt;/p&gt;
&lt;p&gt;In the above section you will notice this block of code which is different from what Nextflow’s documentation is.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;accountName&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; azure_config[&quot;batchAccountName&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;accountKey&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; azure_config[&quot;batchAccountKey&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’m going to explain how to separate out your credentials from your nextflow.config file. You will often hear people scream &lt;strong&gt;‘Don’t commit your credentials to git!’&lt;/strong&gt; They are right of course - if people get hold of your credentials they could run their pipelines on your credit card!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;However, how to avoid doing this is often unclear and leaves beginners wondering what they are supposed to do instead..&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;how-i-separate-credentials-out&quot;&gt;How I Separate Credentials Out&lt;/h3&gt;
&lt;p&gt;I have my credentials in a separate JSON file named &lt;code&gt;credentials.json&lt;/code&gt; that is added to the &lt;code&gt;.gitignore&lt;/code&gt; file to avoid committing that to the repo.&lt;/p&gt;
&lt;p&gt;Here is the json file which is literally 6 lines that you can fill in and rename to &lt;code&gt;credentials.json&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    &quot;storageAccountName&quot;&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    &quot;storageAccountKey&quot;&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    &quot;batchAccountName&quot;&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    &quot;batchAccountKey&quot;&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure you add the line &lt;code&gt;credentials.json&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt; file. If you don’t have &lt;code&gt;.gitignore&lt;/code&gt;, create one.&lt;/p&gt;
&lt;p&gt;Now open &lt;code&gt;nextflow.config&lt;/code&gt; and at the top here’s what I’ve got:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; groovy.json.JsonSlurper&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; JsonSlurper&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; JsonSlurper&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;azure_config&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; JsonSlurper.parse&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; File&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;&quot;./credentials.json&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows nextflow.config to read your &lt;code&gt;credentials.json&lt;/code&gt; file which is in the same directory as the config file.&lt;/p&gt;
&lt;p&gt;Side note: due to relative file naming you do need to run nextflow in the root directory of your repo.&lt;/p&gt;
&lt;p&gt;That’s it, 9 lines of code and a &lt;code&gt;.gitignore&lt;/code&gt; file to protect you from exposing your sensitive information on the internet!&lt;/p&gt;
&lt;h2 id=&quot;running-test-and-production-pipelines&quot;&gt;Running Test and Production Pipelines&lt;/h2&gt;
&lt;p&gt;To run my test pipeline (my pipeline file is named pipeline.nf, other common names include main.nf):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;nextflow&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; pipeline.nf&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -resume&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -profile&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; az&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To run production:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;nextflow&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; pipeline.nf&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -resume&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -profile&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; az_prod&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can watch Azure Batch spin up VMs in Azure Portal.&lt;/p&gt;
&lt;h2 id=&quot;requesting-a-quota-increase&quot;&gt;Requesting A Quota Increase&lt;/h2&gt;
&lt;p&gt;Go to your batch account, click ‘quotas’ in the sidebar and then there is a button ‘Request quota increase’. Fill that in for your desired VM and Microsoft Support will hopefully quickly approve that.&lt;/p&gt;
&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;The above steps should get you up and running initially on your own cloud supercomputer. However, you will quickly realise that this launches the pipeline from your local machine and as you know, real production pipelines can run for hours. During this time, your computer needs to remain active as it is the main controller for scheduling and arranging jobs.&lt;/p&gt;
&lt;p&gt;In a future article, I will cover launching pipelines from a cloud server or ‘head node’ and using &lt;code&gt;screen&lt;/code&gt; to keep long running processes active. This will let you launch pipelines from anywhere and turn off your main computer. You can even code directly on your cloud machine using VSCode Remote. Once you’ve tried this you will never go back!&lt;/p&gt;
</content:encoded><category>Bioinformatics</category><category>Nextflow</category></item><item><title>How to Create Your Bioinformatics Pipeline with Nextflow</title><link>https://shaunchuah.com/posts/bioinformatics-pipeline-with-nextflow/</link><guid isPermaLink="true">https://shaunchuah.com/posts/bioinformatics-pipeline-with-nextflow/</guid><description>What a bioinformatics pipeline is, why I chose Nextflow over Snakemake, and how to build one from Docker containers.</description><pubDate>Thu, 12 Aug 2021 18:24:45 GMT</pubDate><content:encoded>&lt;p&gt;Now that you know how to run bioinformatics software in Docker containers, it’s time to connect them up. If you’ve missed the last post the link is here: &lt;a href=&quot;https://shaunchuah.com/posts/getting-started-with-docker-for-bioinformatics&quot;&gt;Getting started with Docker for bioinformatics.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;content-overview&quot;&gt;Content Overview&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;What is a pipeline?&lt;/li&gt;
&lt;li&gt;Nextflow vs Snakemake&lt;/li&gt;
&lt;li&gt;Using Nextflow and Docker containers to create your pipeline&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-is-a-pipeline-anyway&quot;&gt;What is a pipeline anyway?&lt;/h2&gt;
&lt;p&gt;The term ‘pipeline’ is thrown around a lot in bioinformatics. In simple terms, it refers to the programs that have to be run in a certain order to complete the analysis. Some of these programs take the outputs of earlier programs and process them in order to achieve a specific objective.&lt;/p&gt;
&lt;p&gt;This can be as simple as a couple of programs or it can become a messy spider web. A basic example would be: raw fastq files from the sequencer –&amp;gt; passing it through an aligner against the human genome –&amp;gt; variant calling.&lt;/p&gt;
&lt;p&gt;NF core have a nice set of pipelines &lt;a href=&quot;https://nf-co.re/pipelines&quot;&gt;here&lt;/a&gt; including much more complex ones.&lt;/p&gt;
&lt;h2 id=&quot;how-to-get-started&quot;&gt;How to get started&lt;/h2&gt;
&lt;p&gt;There are two key frameworks that I will point you to: &lt;a href=&quot;https://www.nextflow.io/&quot;&gt;nextflow&lt;/a&gt; and &lt;a href=&quot;https://snakemake.readthedocs.io/en/stable/&quot;&gt;snakemake&lt;/a&gt;. These are the programs that will run your programs for you and orchestrate the input and output files.&lt;/p&gt;
&lt;h2 id=&quot;nextflow-vs-snakemake&quot;&gt;Nextflow vs Snakemake&lt;/h2&gt;
&lt;p&gt;Disclaimer: this is my personal opinion on this topic. Try both and make up your mind as to which suits your thought process better.&lt;/p&gt;
&lt;h3 id=&quot;1-the-programming-language-difference-doesnt-matter&quot;&gt;1. The programming language difference doesn’t matter&lt;/h3&gt;
&lt;p&gt;Snakemake is based on python whereas nextflow uses groovy (which is like python for java). Initially when I first came across these comparisons I immediately jumped to snakemake as I’m pretty comfortable with python.&lt;/p&gt;
&lt;p&gt;Having tried both now, I would say that since you need to learn the pipeline syntax anyway, the actual difference between python and groovy is pretty minimal.&lt;/p&gt;
&lt;h3 id=&quot;2-the-biggest-difference-is-the-thinking-direction-of-the-pipeline&quot;&gt;2. The biggest difference is the ‘thinking direction’ of the pipeline&lt;/h3&gt;
&lt;p&gt;Let me explain what I mean. In snakemake you have to ‘think backwards’ and work your way from the desired output towards the input. I find nextflow way more intuitive in that you think about your pipeline in sequence of how you run your programs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here’s how you have to think in snakemake:&lt;/strong&gt; I need output C which comes from program B and to get program B to run you need the output of program A.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Compared to nextflow:&lt;/strong&gt; With my input files I run it in program A and then take it to program B. Output C will result.&lt;/p&gt;
&lt;h3 id=&quot;3-why-i-switched-to-nextflow-the-separation-of-how-the-pipeline-is-run-from-what-the-pipeline-is&quot;&gt;3. Why I switched to Nextflow: The separation of how the pipeline is run from what the pipeline is&lt;/h3&gt;
&lt;p&gt;The key reason why I switched from snakemake to nextflow is ‘the decoupling of pipeline execution’ or in plain terms, the separation of where and how your pipeline is run and what the pipeline actually does. The series of steps is described in the main file while the execution can be controlled by the configuration. We will cover pipeline execution in a separate article.&lt;/p&gt;
&lt;h2 id=&quot;nextflow-pipeline&quot;&gt;Nextflow Pipeline&lt;/h2&gt;
&lt;p&gt;It is now time to go into more detail on setting up your pipeline in nextflow. Here’s an example pipeline which takes in Illumina paired reads, runs them through fastqc and bowtie2 and perform some simple statistics on the aligned file.&lt;/p&gt;
&lt;h3 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Install Nextflow&lt;/li&gt;
&lt;li&gt;Install Docker&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-set-up-and-define-your-input-and-outputs&quot;&gt;1. Set up and define your input and outputs&lt;/h3&gt;
&lt;p&gt;First we set up a couple of parameters that can be easily changed depending on whether you are running test files vs actual data. These parameters can be modified in your config profiles.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; main.nf&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;#!/usr/bin/env nextflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; PIPELINE&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; PARAMETERS&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; HERE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Input&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;params.reads&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$baseDir&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;/data/*/*_{R1,R2}_*.fastq.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Report&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;params.outdir&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;reports&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Reference&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Genomes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;params.bowtie2_reference_index&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$baseDir&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;/reference_db/bowtie2/bt2_index.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;bowtie2_db_ch&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Channel.value&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;file(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;params&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;bowtie2_reference_index&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-create-channels-and-feed-your-input-into-them&quot;&gt;2. Create ‘channels’ and feed your input into them&lt;/h3&gt;
&lt;p&gt;In nextflow, there is this concept of ‘channels’. The basic premise is simple - each channel represents one file that can only be consumed once (unless it’s a ‘value channel’). Think of channels as pipes that you can feed files into which can be used only once.&lt;/p&gt;
&lt;p&gt;In this example, we generate the channels using the fromFilePairs method and create 2 channels - &lt;code&gt;fastqc_reads&lt;/code&gt; and &lt;code&gt;reads_for_alignment&lt;/code&gt;. *side note this is using the standard nextflow language rather than their newer DSL2.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;reads&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; Channel.fromFilePairs&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;params.reads&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;reads.into&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; fastqc_reads&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;reads_for_alignment&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3-now-lets-have-a-look-at-our-first-process-and-break-it-down&quot;&gt;3. Now let’s have a look at our first process and break it down&lt;/h3&gt;
&lt;p&gt;Here is the process block - this process is named &lt;code&gt;fastqc_run&lt;/code&gt; but you can change this to whatever name suits.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; fastqc_run&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    publishDir&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$params&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;.outdir/fastqc/&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$sample_id&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;/&quot;,&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; mode:&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;copy&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    container&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;biocontainers/fastqc:v0.11.9_cv8&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    cpus&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    input:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    tuple&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; val&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;sample_id&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; file&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;reads_file&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; fastqc_reads&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    output:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    file&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &quot;*_fastqc.{zip,html}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    script:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    fastqc &lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$reads_file&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt; -o . --threads ${&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;task&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;cpus&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In general, there are 4 components to each process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A configuration block&lt;/li&gt;
&lt;li&gt;Process inputs&lt;/li&gt;
&lt;li&gt;Process outputs&lt;/li&gt;
&lt;li&gt;Script that runs the desired program&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s break down the above process codeblock into the 4 components.&lt;/p&gt;
&lt;h4 id=&quot;configuration&quot;&gt;Configuration&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  publishDir &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;$params.outdir/fastqc/$sample_id/&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;, mode&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;copy&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  container &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&apos;biocontainers/fastqc:v0.11.9_cv8&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  cpus &lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;publishDir&lt;/code&gt; This allows you to copy the output files of this process to a desired location for easy access. Note that by default it creates a shortcut link to the actual file location and you have to explicitly specify for it to copy and give you the actual file.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;container&lt;/code&gt; &lt;strong&gt;This is where the real magic happens.&lt;/strong&gt; If you specify a publicly available Docker container, Nextflow will seamlessly pull the container in, run the script and generate the output that you’re looking for. *side note on the config you will need to specify docker enabled as true.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cpus&lt;/code&gt; This specifies the amount of CPUs you wish to run for this process. You can also specify memory options and will help in autoscaling your cloud computation needs. In general this option is useful if you are using VMs of varying size and works quite well with Google Cloud.&lt;/p&gt;
&lt;h4 id=&quot;inputs&quot;&gt;Inputs&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;  input&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  tuple val(sample_id), file(reads_file) from fastqc_reads&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Channel.fromFilePairs&lt;/code&gt; method generates a tuple &lt;code&gt;[wildcard value, [the pair of files for processing]]&lt;/code&gt;. Read &lt;a href=&quot;https://www.nextflow.io/docs/latest/channel.html#fromfilepairs&quot;&gt;here&lt;/a&gt; for full documentation.&lt;/p&gt;
&lt;p&gt;So when we call it into the input, we assign the variable name &lt;code&gt;sample_id&lt;/code&gt; to the wildcard value and call the files &lt;code&gt;reads_file&lt;/code&gt;. As a side note, if you need to access the first file you can call &lt;code&gt;reads_file[0]&lt;/code&gt; to do so and the second file is &lt;code&gt;reads_file[1]&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;outputs&quot;&gt;Outputs&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;  output&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;  file &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;*_fastqc.{zip,html}&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we are telling nextflow to expect a zip file and a html file from the output of fastqc. Since we declared &lt;code&gt;publishDir&lt;/code&gt; above, nextflow will then copy these files to the report directory.&lt;/p&gt;
&lt;h4 id=&quot;script&quot;&gt;Script&lt;/h4&gt;
&lt;p&gt;Finally, let’s tell nextflow how to run fastqc!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;  script&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  fastqc &lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$reads_file&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; -o . --threads ${task.cpus}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A couple of comments. &lt;code&gt;-o .&lt;/code&gt; tells fastqc to place the output in the current working directory - this will be located in nextflow’s work directory. &lt;code&gt;--threads ${task.cpus}&lt;/code&gt; is how we parallelise fastqc to take advantage of the available cpus for this process.&lt;/p&gt;
&lt;h3 id=&quot;4-here-is-how-the-pipeline-continues&quot;&gt;4. Here is how the pipeline continues&lt;/h3&gt;
&lt;p&gt;The code below is hopefully pretty straightforward. The output from bowtie2 is split into two channels &lt;code&gt;aligned_ch&lt;/code&gt; and &lt;code&gt;stats_ch&lt;/code&gt;. &lt;code&gt;stat_ch&lt;/code&gt; is sent to samtools to run flagstat and &lt;code&gt;aligned_ch&lt;/code&gt; continues on for onward processing in the next steps of the pipeline.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;groovy&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;process bowtie2 {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    container &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&apos;biocontainers/bowtie2:v2.4.1_cv1&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    cpus &lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;    input&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    tuple val(sample_id), file(reads_file) from reads_for_alignment&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    file db from bowtie2_db_ch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;    output&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    tuple val(sample_id), file(&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&apos;*.sam&apos;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;) into aligned_ch, stats_ch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;    script&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    tar -xvf &lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    bowtie2 -t -p ${task.cpus} -x bowtie2/GRCh38_bowtie2 -1 ${reads_file[0]} -2 ${reads_file[1]} -S ${sample_id}.sam&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;process samtools_flagstat {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    publishDir &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$params&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;outdir&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;/samtools_flagstat/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    container &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&apos;biocontainers/samtools:v1.9-4-deb_cv1&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    cpus &lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    tag &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$sample_id&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;    input&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    tuple val(sample_id), file(sam_file) from stats_ch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;    output&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;    path &lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;${sample_id}_flagstat.txt&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#005CC5&quot;&gt;    script&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    samtools flagstat -@ ${task.cpus} &lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;$sam_file&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &amp;gt; ${sample_id}_flagstat.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#032F62&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The above is a simple introduction to using nextflow to pull in containers and orchestrate a pipeline. It is well worth investing some time to automate your pipeline - write your code once and use it forever!&lt;/p&gt;
&lt;p&gt;More importantly, this is one step closer to creating your cloud genomics supercomputer. We will cover this next.&lt;/p&gt;
</content:encoded><category>Bioinformatics</category><category>Nextflow</category></item><item><title>Getting Started With Docker for Bioinformatics</title><link>https://shaunchuah.com/posts/getting-started-with-docker-for-bioinformatics/</link><guid isPermaLink="true">https://shaunchuah.com/posts/getting-started-with-docker-for-bioinformatics/</guid><description>How to run bioinformatics tools such as bowtie2 in Docker containers instead of installing them, and where to find ready-made images.</description><pubDate>Thu, 05 Aug 2021 18:23:00 GMT</pubDate><content:encoded>&lt;p&gt;Next generation sequencing is becoming much more accessible to researchers in 2021. As you stare at the freshly minted .fastq files, you’re wondering - how do I go about analysing this?&lt;/p&gt;
&lt;p&gt;After a stint on Google, you decide that you want to run bwa-mem/bowtie2 and then send the output into samtools. Next thing you know, you’re trying to install half a dozen bioinformatic programs on your new ubuntu machine. You run into dependency hell or else conda seems to be stuck solving god knows what and this quickly eats up half your day.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stop wasting your time installing software - there is a secret to bypass all of this - Docker!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://shaunchuah.com/media/docker2.png&quot; alt=&quot;Docker logo&quot;&gt;&lt;/p&gt;
&lt;p&gt;What is Docker? Here’s a &lt;a href=&quot;https://www.youtube.com/watch?v=Gjnup-PuquQ&quot;&gt;quick 100 second introduction&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are Docker containers for most bioinformatic tools. Instead of installing software, all you have to do is specify the Docker image and you’re ready to run the program!&lt;/p&gt;
&lt;h2 id=&quot;heres-the-secret&quot;&gt;Here’s the secret&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -it&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -v&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;&amp;lt;path to your files&amp;gt;:/data&apos;&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;container&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; your&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; choic&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#D73A49&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This immediately spins up the shell version of the bioinformatic tool and you can immediately run the commands needed to execute the program.&lt;/p&gt;
&lt;h3 id=&quot;bowtie2-example&quot;&gt;Bowtie2 Example&lt;/h3&gt;
&lt;p&gt;Assuming your directory structure looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;sequencing_data/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; reads/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;│&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  ├─&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; sample_id/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;│&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  │&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  ├─&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; read_1.fastq.gz&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;│&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  │&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  ├─&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; read_2.fastq.gz&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;├─&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; bowtie2/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;│&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;  ├─&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; GRCh38_bowtie2.fa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -it&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -v&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; &apos;~/sequencing_data:/data&apos;&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; biocontainers/bowtie2:v2.4.1_cv1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt;bowtie2&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -t&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; 4&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -x&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; bowtie2/GRCh38_bowtie2&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -1&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; reads/sample_id/read_1.fastq.gz&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -2&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; reads/sample_id/read_2.fastq.gz&lt;/span&gt;&lt;span style=&quot;color:#005CC5&quot;&gt; -S&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt; output.sam&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;heres-the-breakdown-of-the-magic&quot;&gt;Here’s the breakdown of the magic&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;-it&lt;/strong&gt;: This opens an interactive shell into the running container&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;-v ‘path-you-want-to-access:/data’&lt;/strong&gt;: This is the key command that binds your computer’s files into the container. For most biocontainers the target is /data but this may need tweaked depending on the container. This allows the program in the container to access and compute the files on your local computer. Understanding this was the key bit that unlocked the power of Docker in my mind.&lt;/p&gt;
&lt;h2 id=&quot;how-to-find-docker-containers&quot;&gt;How to find Docker containers&lt;/h2&gt;
&lt;p&gt;For most things, just google the tool you want and add Docker eg. ‘bwa docker’, ‘metaphlan docker’&lt;/p&gt;
&lt;p&gt;Here are a list of public container registries with amazing software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/u/biobakery&quot;&gt;https://hub.docker.com/u/biobakery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/u/biocontainers&quot;&gt;https://hub.docker.com/u/biocontainers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/u/staphb&quot;&gt;https://hub.docker.com/u/staphb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Give this a try - 10-15 mins of experimenting will save you days of time and you will never have to manage dependencies anymore!&lt;/p&gt;
&lt;h2 id=&quot;what-next&quot;&gt;What next?&lt;/h2&gt;
&lt;p&gt;Once you have got your head round using Docker for your bioinformatics, the next thing that comes to mind is to automate the containers locally on your computer so that you can easily run 100 read files at the touch of a button. I will cover this in a future article.&lt;/p&gt;
</content:encoded><category>Bioinformatics</category></item><item><title>Architectural Approaches to Building Websites</title><link>https://shaunchuah.com/posts/architectural-approaches-to-building-websites/</link><guid isPermaLink="true">https://shaunchuah.com/posts/architectural-approaches-to-building-websites/</guid><description>A beginner&apos;s guide to the four main ways to build a website: plain HTML, full-stack CMS, decoupled JavaScript frontends and JAMstack static site generators.</description><pubDate>Thu, 01 Jul 2021 18:19:49 GMT</pubDate><content:encoded>&lt;p&gt;This article is for people who are new to web development, lost in the myriad of web frameworks and are asking themselves:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What are the real differences in the frameworks?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Having spent the last year getting up to speed with the state of the web, I’m going to summarise the 4 major architectural approaches to launching a new website in 2021. Although I describe them as discrete categories, in reality they exist on a continuum and some frameworks will blur the lines between these categories (eg. NextJS). For the beginner though, it is helpful to have a rough overview of the major choices available to you.&lt;/p&gt;
&lt;h2 id=&quot;1-traditional-htmlcssjavascript&quot;&gt;#1 Traditional HTML/CSS/Javascript&lt;/h2&gt;
&lt;p&gt;The original way websites were build. Just pure html, css and maybe a bit of javascript. Throw in a css framework or sprinkle a bit of javascript. Ideal for one-page brochure websites which do not need constant updates of content, at a stretch maybe up to 2-3 pages. If you’re planning anything bigger, try one of the other options below.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Deployment Methods&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Grab index.html and all associated files and SFTP it to apache or nginx or CDN of your choice&lt;/li&gt;
&lt;li&gt;A better way - Setup a git repo on github and use git clone into your apache/nginx server. Makes updating website a matter of running git pull.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt; Fast to develop, extremely easy to customise, easy to deploy, easy to scale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt; Does not suit websites which have more than one page or content that needs updated regularly.&lt;/p&gt;
&lt;h2 id=&quot;2-full-stack-cms&quot;&gt;#2 Full Stack CMS&lt;/h2&gt;
&lt;p&gt;Examples: Wordpress, Django, Ruby on Rails, Laravel&lt;/p&gt;
&lt;p&gt;These are the traditional server side frameworks which still run most of the web today. The magic here is that the website is connected to a backend database which can hold different content and render the content into html based on templates. These frameworks also allow for user authentication and storing things like contact form data.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Deployment Methods&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Usually custom to the framework. Generally requires installing a few pieces of software on your server. Think of the traditional LAMP stack (Linux Apache MySql PHP).&lt;/li&gt;
&lt;li&gt;Use docker to automate the framework deployment steps.&lt;/li&gt;
&lt;li&gt;Some webhost may offer one-click deployment eg of Wordpress&lt;/li&gt;
&lt;li&gt;Platform as a service eg. Heroku&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt; Well used, well documented, tried and tested way of having a website hosting content which can be updated easily.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt; Need to deploy, monitor and look after database backend.&lt;/p&gt;
&lt;h2 id=&quot;3-decoupled-javascript-frontendapi-backend&quot;&gt;#3 Decoupled Javascript Frontend/API Backend&lt;/h2&gt;
&lt;p&gt;Examples: React/Vue + Django Rest Framework/Laravel/Ruby on Rails, React/Vue/Mobile Frontend + AWS Amplify/Google Firebase (Backend as a service)&lt;/p&gt;
&lt;p&gt;The trendiest way to build websites in 2021. Pick a frontend javascript framework and communicate with databases via an API gateway. Makes for very slick websites and web applications on par with desktop apps.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Deployment Methods&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;More involved than #2. Deploy both the frontend and the backend.&lt;/li&gt;
&lt;li&gt;Docker is highly recommended here.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt; Amazingly slick and interactive websites. Easy to split work between multiple developers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt; Need to deploy, monitor and look after two projects. Double the work of the traditional frameworks.&lt;/p&gt;
&lt;h2 id=&quot;4-full-jamstack-static-site-generation&quot;&gt;#4 Full JAMStack Static Site Generation&lt;/h2&gt;
&lt;p&gt;Examples: Hugo, Jekyll, GatsbyJS, Docusaurus, VuePress, Gridsome&lt;/p&gt;
&lt;p&gt;Number 3 and 4 are similar in concepts at first glance. The slight difference is that these full on static site generators are more suited for webpages where the content can be preloaded (eg blogs, articles) and less suited for web applications which have users interacting with the database (such as chat apps/social media).&lt;/p&gt;
&lt;p&gt;The key concept is that before the site is deployed, the engine pulls all the content and all the code and spits out html/javascript/css files. These files are then deployed like #1 to a server or to a CDN for global scaling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt; Can create single page websites (like this blog) which do not reload the browser when navigating between pages. Makes the website feel really slick.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt; This is for websites rather than web applications (use #3 instead). Initial learning curve on the generator of choice.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The right architectural choice will depend on the scope of what you’re building and the expected scale/audience. Brochure websites are different to blogs which are different to web applications.&lt;/p&gt;
&lt;p&gt;Something important to note is that web projects are often unpredictable and tend to grow in size and complexity with time. You may reach a point where you need to consider a rework of the architecture (usually this is a good problem to have if your site traffic is growing!).&lt;/p&gt;
&lt;p&gt;Choosing the right approach and avoiding premature optimisation will avoid wasted effort and speed your time to deployment.&lt;/p&gt;
</content:encoded><category>Web development</category></item><item><title>The State of Web Development</title><link>https://shaunchuah.com/posts/the-state-of-web-development/</link><guid isPermaLink="true">https://shaunchuah.com/posts/the-state-of-web-development/</guid><description>Returning to web development in 2021 during a research fellowship: code editors, CSS and JavaScript frameworks, backend APIs and cloud deployment.</description><pubDate>Tue, 29 Jun 2021 18:01:06 GMT</pubDate><content:encoded>&lt;p&gt;I’ve had to dabble in a bit of web development over the past year as part of my research fellowship and having not done this for a while, I have accrued a couple of thoughts I want to share.&lt;/p&gt;
&lt;h2 id=&quot;my-background&quot;&gt;My background&lt;/h2&gt;
&lt;p&gt;First, a bit of background. Growing up, I’ve had the privilege of witnessing the birth and evolution of the modern internet. From the days of 56kbps dial-up modems which gets taken out by lightning(!) occasionally and back when Yahoo was the default home page for everybody (remember those days?). This was before MySpace and Friendster.&lt;/p&gt;
&lt;p&gt;As I got through secondary school, that was my first real encounter with web development. We had to do group projects which involved making a webpage around a particular topic. Something like a wiki in the days when Wikipedia was barely around. I handcoded webpages with &lt;strong&gt;notepad&lt;/strong&gt;. Yes, those days.&lt;/p&gt;
&lt;h2 id=&quot;lets-talk-code-editors&quot;&gt;Let’s talk code editors&lt;/h2&gt;
&lt;p&gt;In 2021, I am glad to report I no longer use notepad. Now VSCode seems to be the defacto IDE and certainly is the one I would recommend. There is &lt;em&gt;AI code autocompletion&lt;/em&gt;. What?! Just incredibly amazing. In fact, this blog is written purely in VSCode.&lt;/p&gt;
&lt;p&gt;Nowhere has this evolution in IDEs been more impressive to me than in the world of Javascript coding. I used to waste countless hours hunting for that missing curly brace in Notepad which screwed up the entire program. And in fact, I hated JavaScript for that very reason. Now with eslint and autoformatting, JavaScript is a complete breeze and a joy to write. Let’s not go into its idiosyncracies.&lt;/p&gt;
&lt;h2 id=&quot;how-about-css-frameworks&quot;&gt;How about CSS frameworks?&lt;/h2&gt;
&lt;p&gt;CSS is still probably one of the toughest things to get right. And then Bootstrap by Twitter came along and allowed everybody to stop handwriting CSS from scratch every single time. After that, the mobile revolution happened and websites had to accommodate a ridiculous number of screen sizes.&lt;/p&gt;
&lt;p&gt;Now in 2021, it seems that all the jazz is around tailwindcss and rightly so. Initially I struggled to get my head around it. Why write things like:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#22863A&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;bg-blue-100 mb-4 rounded shadow&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#22863A&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How is this different from html in the pre-CSS days?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-light&quot; style=&quot;background-color:#fff;color:#24292e; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#22863A&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#6F42C1&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#032F62&quot;&gt;&quot;background: blue;&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#22863A&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#24292E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and that brings me onto:&lt;/p&gt;
&lt;h2 id=&quot;javascript-frameworks&quot;&gt;Javascript frameworks&lt;/h2&gt;
&lt;p&gt;The biggest difference in 2021 vs say 2010 are javascript frameworks - ReactJS is number one today, followed by Vue, Svelte, Angular, Alpine JS. When you make the conceptual switch from building whole web pages to building components, that’s when the logic of tailwindcss really shines.&lt;/p&gt;
&lt;p&gt;These frameworks allow you to build amazingly interactive websites that pretty much outstrip desktop applications in every way. The only desktop applications that are better installed in your machine are things like games which use tremendous amounts of horsepower.&lt;/p&gt;
&lt;h2 id=&quot;backend-frameworks&quot;&gt;Backend frameworks&lt;/h2&gt;
&lt;p&gt;Backend frameworks in 2021 have now transformed into APIs that serve a variety of clients - whether web or mobile app. Again another major conceptual shift. In the pre-Ruby on Rails days you had to be a php wizard or know some cgi to interact with a database. In fact, the reason why Wordpress was so popular was because it allowed you to quickly set up a website with a database on what we used to call a LAMP stack.&lt;/p&gt;
&lt;h2 id=&quot;deploying-to-the-cloud&quot;&gt;Deploying to the cloud&lt;/h2&gt;
&lt;p&gt;Deploying a website in 2021 has never been easier. Gone are the days of having to actually tinker with a physical machine and hook it up to your ISP’s network in order to serve your first static web page ever. In 2021, a solo developer can single handedly build a web application that can scale across the entire world as long as you have a big enough credit card limit!&lt;/p&gt;
&lt;h2 id=&quot;the-web-is-still-the-future&quot;&gt;The web is still the future&lt;/h2&gt;
&lt;p&gt;If there is one thing you can bet on, it’s that the web is still the future. Although some may feel that the space has matured and there are a ton of tech giants, when you go into actual industries you will see that there are still a ton of things in the real world that haven’t made the technological shift.&lt;/p&gt;
&lt;p&gt;As someone who has been doing more real world stuff than being in the tech space, seeing the state of the web in 2021 has pretty much blown my mind. Companies that manage to get their heads round the above changes will rise while those who ignore them will have an increasingly tough time.&lt;/p&gt;
&lt;p&gt;If you need any further convincing, I will just say one word - covid.&lt;/p&gt;
</content:encoded><category>Web development</category></item></channel></rss>