RUN CODE INSIDE DOCKER
Edit code outside docker but run inside docker
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
It is not a efficient approach since the time is lost in rebuilding the image and re-starting the container
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:
build: It defines a build tag that will use the Dockerfile for building, however, the Dockerfile does not have any build steps hence it only means that it will use node base image and define the working directory as per the Dockerfile.
image: It specifies the name of the image that should be built using base node image.
volumes: This is an important configuration which specifies my local folder (i.e. volume) is mounted inside the docker container and the destination in the container is /app. It means you local code will be available inside docker at given path.
ports: The port binding is showing that your machine port (3001) is pointing to container port (3000). Which means the app should be running on port 3000 inside the docker container.
entrypoint: It specifies npm start command to be executed during the container startup.
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 🙂