|
||
---|---|---|
.dockerignore | ||
.dockerizedroot | ||
.env | ||
.gitignore | ||
Dockerfile | ||
README.md | ||
docker-compose.yml | ||
dockman.sh | ||
sshd_config | ||
supervisord.conf |
README.md
React Native Dockerized
This repository aims to establish a reliable Android build environment for QA and sanity checks in React Native apps. It's designed for parallel iOS development, as 'node_modules', 'Pods', and iOS build artifacts aren't synced between the host and the container, allowing them to function independently of the Docker setup.
Things to keep in mind:
-
This does not support iOS builds. For that, you'd require a remote Mac host. While there exist Docker images for Mac, they are experimental and using them goes against Apple's EULA.
-
It's intended strictly for development purposes. The Dockerfile sets up a container that operates everything as root, using default sshd configurations.
Requirements
- Android Studio installed with
platform-tools
in your path.- Note: This is likely configured if you've already developed for Android/RN on your machine
- Docker Desktop
- OrbStack (great alternative but it will be out of its free beta soon and may not be stable)
- If you're running Linux, you can also just use the docker CLI and docker service, installed through your package manager.
- A Github and NPM account
- A React Native project to dockerize!
Installation
You will either want to dockerize an app you haven't cloned/created yet, or an existing repository on your machine.
Option 1: Cloning A New Project
Expand
Depending on whether you're starting a new project or dockerizing an existing one, there are two options:
cd ~/Projects
git clone git@github.com:my-github-org/react-native-dockerized.git my-rn-project-dockerized
cd my-rn-project-dockerized && rm -rf .git
git clone git@github.com:my-github-org/my-rn-project.git app
Option 2: An Existing Project
Expand
To dockerize an existing React Native repository, clone this repository first. Then, move your React Native repository into this repository under a folder named app.
cd ~/Projects
git clone git@github.com:my-github-org/react-native-dockerized.git my-rn-project-dockerized
mv my-rn-project my-rn-project-dockerized/app
cd my-rn-project-dockerized && rm -rf .git
Configure Github and NPM Auth
Expand
Prior to starting up the container, the image will run npm install
during the build process. This may require Github authentication if you're installing NPM packages from private Github repositories.
Github
- Create a legacy access token with all Repo-related permissions checked, and save the token in your password manager.
- Add
export GH_TOKEN="your_legacy_access_token"
to your~/.zshrc
file
- Alternatively, you could add it to the
.env
file
NPM
- If you're using private npm packages, create an access token on npm's website. Ensure it has the appropriate permissions for the packages you need.
- Add
export NPM_TOKEN="your_npm_access_token"
to your~/.zshrc
file
- Alternatively, you could add it to the
.env
file
Add dockman.sh
to your PATH
Expand - optional
If you would like to run dockman.sh
from any directory on your system, follow these steps:
-
Create a new directory named
.react-native-dockerized
in your home directory (if it doesn't already exist):mkdir -p $HOME/.react-native-dockerized
-
Copy the
dockman.sh
script into this new directory:cp ./dockman.sh $HOME/.react-native-dockerized
-
Make the script executable:
chmod +x $HOME/.react-native-dockerized/dockman.sh
-
Add the
.react-native-dockerized
directory to your PATH. The exact command depends on your shell:-
For bash:
echo 'export PATH=$PATH:$HOME/.react-native-dockerized' >> ~/.bashrc source ~/.bashrc
-
For zsh:
echo 'export PATH=$PATH:$HOME/.react-native-dockerized' >> ~/.zshrc source ~/.zshrc
Now you can run
dockman.sh
directly from inside any directory of a dockerized React Native project. -
Note: The source
command makes the changes effective immediately. You may need to restart your shell or terminal session to apply these changes if you choose not to use source
.
Usage
After completing Installation and any optional setup:
./dockman.sh up
./dockman.sh start-metro
# boot up an Android emulator before this step
./dockman.sh run-android
You're all set! The following table outlines the helper commands for managing the container, designed with the help of GPT-4. Regular Docker commands work too. Refer to dockman.sh for examples.
Command | Description |
---|---|
./dockman.sh stop-metro |
Stop the Metro server |
./dockman.sh start-metro |
Start the Metro server and reset its cache |
./dockman.sh metro-logs |
Check the server logs |
./dockman.sh connect-android |
Connect to your host machine's Android device |
./dockman.sh run-android |
Connects to your host machine's Android device, builds and deploys the app |
./dockman.sh reinstall-node-modules |
Removes the node_modules directory in the project and re-installs dependencies |
./dockman.sh clear-known-hosts |
Removes the Docker container's entries from the host's ~/.ssh/known_hosts file |
./dockman.sh shell |
Starts a bash shell in the project's directory inside the Docker container |
./dockman.sh init-ssh |
Generates an SSH key and adds it to the host's SSH config |
You may need to run sudo chmod +x ./dockman.sh
first for executable permissions.
Settings
You can adjust a few settings in the .env
file at the root of the repository. Alternatively you could add them to your shell's environment.
Variable | Description | Default |
---|---|---|
CONTAINER_NAME |
The name of the Docker container with which the script interacts. | react-native-dockerized |
SSH_KEY |
The location of the SSH key file used for secure communication with the Docker container. | ~/.ssh/id_docker_dev |
RN_PROJECT_FOLDER_NAME |
The name of the React Native project folder. This should match the name of the folder that you cloned at the root of this repository. | app |
NODE_VERSION |
The version of Node.js that will be installed by the Node Version Manager (NVM). | 16.13.0 |
NPM_TOKEN |
Token for authenticating with npm for installing npm packages. This should be a valid token associated with your npm account. | - |
GH_TOKEN |
Token for authenticating with GitHub. This is required for installing packages from private GitHub repositories. | - |
If you plan on running multiple Docker containers simultaneously, you will need to assign a unique name to each container. For instance, if you're developing two separate React Native apps, you'll need to dockerize the second app using a different container name.
Please note that modifying the RN_PROJECT_FOLDER_NAME
variable won't rename the project folder on your host machine. This variable should match the existing name of your project folder.
Remote Workspace Inside The Container:
Expand - optional
You can open a new remote workspace in your IDE to access the React Native project within this Docker container. With VS Code, you may not require SSH for this, thanks to the robust integration of the Dev Containers extension with Docker. However, if you're using VSCodium, your best bet is the Open Remote SSH extension.
Do note that VSCodium comes with certain limitations, such as the need to manually provision an SSH server and client - but hey that's the FOSS life.
To simplify the setup for a remote workspace in VSCodium, you can run init-ssh
, which will provision everything necessary. You can confirm this by running ssh root@{your.dockers.ip.address}
.
Troubleshooting
-
If hot reloading doesn't work, first check the Metro logs with
./dockman.sh metro-logs
. If the logs don't help, make sure your Metro configuration includeswatchFolders: ['/home/app'],
, replacing 'app' with the value ofRN_PROJECT_FOLDER_NAME
. This ensures changes are detected in both your local machine and the container. -
If you encounter issues connecting via SSH, try running
ssh root@{your.docker.ip.address} -v
for more debug info. The logs are typically clear and verbose enough to guide you further. -
Your
known_hosts
file may cause an error after recreating the container. In this case, run./dockman.sh clear-known-hosts
. Then SSH in again to confirm the issue is resolved, and accept the newknown_host
entry.