RUN CODE INSIDE DOCKER

Edit code outside docker but run inside docker

Disclaimer: The content of this blog are my views and understanding of the topic. I do not intend to demean anything or anyone. I am only trying to share my views on the topic so that you will get a different thought process and angle to look at this topic.

     Docker containerisation platform alleviates the pain of installation and setup of the dependencies required for deploying the app in various environments. This enables use to replicate the production setup on developer machine for easier bug replication and fixation. However we can leverage docker during the app development stage too. A simple example is editing the code on the host machine but running the app in the docker. This enables us to setup a developer machine quickly with bare minimum tools installed. Although, the latest version of Docker Desktop has an option to edit the files inside the container using a file editor option but that is useful for limited use cases. Our use case is for complete code editing using an IDE installed on developer's machine. Let us see how...

How to do that ?

There are two ways to do this

Rebuilding the image

In this approach we edit the code outside the docker but we rebuild the image and re-start the container using new image.

Cons

Volume Mounting

In this approach we edit the code on the host machine via some editor but the application is running inside the docker as the volume is mounted 

Note : Applicable only for development and not recommended for production code run

Create a Dockerfile for a React Project

Create an app named sample-react-app using create-react-app tool. Below is a sample folder structure for the same :

Dockerfile

FROM node:18-alpine

WORKDIR /app

The Dockerfile for this project is simply a base image on which you want to run the app and the working directory definition.

NOTE: You can add this content inline in the docker-compose.yml and get rid of this Dockerfile

Folder Structure

sample-react-app/

├── node_modules

├── public/

│   ├── index.html

│   ├── favicon.ico

│   └── manifest.json

├── src/

│   ├── App.tsx

│   ├── index.css

│   ├── index.tsx

│   ├── react-app-env.d.ts

│   └── reportWebVitals.ts

├── Dockerfile

├── docker-compose.yml

├── package.json

├── README.md

└── tsconfig.json

Create a docker-compose.yml file

Create a docker-compose.yml file with below contents and run the container using docker compose up -d command.

version: '3.8'


services:

 sample-react-app:

   build: .

   image: abm.com/sample-react-app:local

   volumes:

     - .:/app

   ports:

     - 3001:3000

   entrypoint: ["npm", "start"]

The docker-compose.yml is shown in the adjacent panel. Below are the details of various sections: 

Check the app is running

Now check the app is running and try editing some file and see changes are reflected without rebuild the image. Just a browser page refresh is what it takes

import React from "react";

import logo from "./logo.svg";

import "./App.css";


function App() {

 return (

   <div className="App App-header">

     <h1>Sample React App</h1>

   </div>

 );

}


export default App;

App.tsx

In the adjacent panel you can see the contents of App.tsx file. We changed it from the default App.tsx generated by create-react-app tool for this blog's explanation. Run the docker compose file and see that it shows a simple text "Sample React App" on the screen. Now change the text in the App.tsx to "Sample React App 1.2.3" and just refresh the browser page and you will see the changes are reflected.

Due to the volume mounting, the source code is available inside the docker container. The command we are using is npm start which is like starting up a development server which watches for file changes but inside the docker container. Check the below screenshots.

Before Editing

Content rendered before making any changes

After Editing

Content rendered after editing and page refresh

Summary

We are now able to run the code in the docker container on the developer's system. The benefit of this approach is that we can have the required dependencies defined in the Dockerfile which can prepare the required image and we don't need to install those dependencies on developer's machine. So the developer setup could be replicated easily on other developer's machine. Although we still need to install git client for cloning the code and any IDE (like Visual Studio Code) of your choice for editing the code. That is acceptable 🙂