buncha fixes to make sure env vars are set properly before creating the image, and move npm install to dockerfile to bake it in the image

This commit is contained in:
Silas 2023-07-28 18:10:37 -04:00
parent 221f800c15
commit 0e690663fe
Signed by: silentsilas
GPG Key ID: 4199EFB7DAA34349
8 changed files with 89 additions and 63 deletions

0
.dockerizedroot Normal file
View File

5
.env
View File

@ -1,3 +1,6 @@
CONTAINER_NAME=react-native-dockerized
RN_PROJECT_FOLDER_NAME=app
SSH_KEY="~/.ssh/id_docker_dev"
SSH_KEY="id_docker_dev"
NPM_TOKEN=
GH_TOKEN=
NODE_VERSION=16.13.0

View File

@ -3,20 +3,29 @@ FROM reactnativecommunity/react-native-android
# config and update
ENV DEBIAN_FRONTEND noninteractive
ENV DOCKER=true
WORKDIR /home
RUN apt-get update
RUN mkdir /var/log/app
ARG SSH_KEY
ARG NODE_VERSION
ARG GH_TOKEN
ARG NPM_TOKEN
ARG RN_PROJECT_FOLDER_NAME
# set up NVM and use v16 LTS
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION 16.13.0
RUN . "$NVM_DIR/nvm.sh" && nvm install $NODE_VERSION && nvm alias default $NODE_VERSION && nvm use default
ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN npm install -g react-native-cli
# add gh/npm tokens and install project dependencies
RUN echo \"//github.com/:_authToken=$GH_TOKEN\" > /home/app/.npmrc
RUN echo \"//registry.npmjs.org/:_authToken=$NPM_TOKEN\" >> /home/app/.npmrc
RUN cd /home/$RN_PROJECT_FOLDER_NAME && npm install
# Install SSH server
RUN apt-get -y install openssh-server
COPY sshd_config /etc/ssh/sshd_config
@ -31,4 +40,4 @@ COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

View File

@ -15,6 +15,7 @@ Things to keep in mind:
* [Docker Desktop ](https://docs.docker.com/desktop/install/mac-install/)
* [OrbStack](https://orbstack.dev/) _(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
@ -26,6 +27,8 @@ You will either want to dockerize an app you haven't cloned/created yet, or an e
<details>
<summary>Expand</summary>
&NewLine;
Depending on whether you're starting a new project or dockerizing an existing one, there are two options:
```zsh
@ -42,6 +45,8 @@ git clone git@github.com:my-github-org/my-rn-project.git app
<details>
<summary>Expand</summary>
&NewLine;
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.
```zsh
@ -53,11 +58,36 @@ cd my-rn-project-dockerized && rm -rf .git
</details>
#### Add `dockman.sh` to your PATH
#### Configure Github and NPM Auth
<details>
<summary>Expand</summary>
&NewLine;
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
1. Create a [legacy access token](https://github.com/settings/tokens) with all Repo-related permissions checked, and save the token in your password manager.
2. Add `export GH_TOKEN="your_legacy_access_token"` to your `~/.zshrc` file
* Alternatively, you could add it to the `.env` file
#### NPM
1. If you're using private npm packages, create an [access token](https://docs.npmjs.com/creating-and-viewing-access-tokens) on npm's website. Ensure it has the appropriate permissions for the packages you need.
2. Add `export NPM_TOKEN="your_npm_access_token"` to your `~/.zshrc` file
* Alternatively, you could add it to the `.env` file
</details>
#### Add `dockman.sh` to your PATH
<details>
<summary>Expand - optional</summary>
&NewLine;
If you would like to run `dockman.sh` from any directory on your system, follow these steps:
1. Create a new directory named `.react-native-dockerized` in your home directory (if it doesn't already exist):
@ -65,9 +95,9 @@ If you would like to run `dockman.sh` from any directory on your system, follow
mkdir -p $HOME/.react-native-dockerized
```
2. Move the `dockman.sh` script into this new directory:
2. Copy the `dockman.sh` script into this new directory:
```zsh
mv /path/to/dockman.sh $HOME/.react-native-dockerized
cp ./dockman.sh $HOME/.react-native-dockerized
```
3. Make the script executable:
@ -95,16 +125,12 @@ Note: The `source` command makes the changes effective immediately. You may need
</details>
&NewLine;
Check out the other optional setup sections, especially [Configure Github Auth](#configure-github-auth) if your project has dependencies installing from a private Github repository.
## Usage
After completing [Installation](#installation) and any optional setup:
```zsh
docker-compose up
./dockman.sh up
./dockman.sh start-metro
# boot up an Android emulator before this step
./dockman.sh run-android
@ -128,36 +154,29 @@ _You may need to run `sudo chmod +x ./dockman.sh` first for executable permissio
## Settings
You can adjust a few settings in the `.env` file at the root of the repository.
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 your repository. | `app` |
| `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.
### Configure Github Auth
<details>
<summary>Expand - optional, but highly recommended</summary>
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.
1. Create a [legacy access token](https://github.com/settings/tokens) with all Repo-related permissions checked, and save the token in your password manager.
2. Add `export GH_TOKEN="your_legacy_access_token"` to your `~/.zshrc` file
* Alternatively, you could add it to the `.env` file
</details>
### Remote Workspace Inside The Container:
<details>
<summary>Expand - optional</summary>
&NewLine;
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](https://code.visualstudio.com/docs/devcontainers/containers) extension with Docker. However, if you're using VSCodium, your best bet is the [Open Remote SSH](https://open-vsx.org/vscode/item?itemName=jeanp413.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.

View File

@ -9,6 +9,11 @@ services:
- SSH_KEY=${SSH_KEY}
- RN_PROJECT_FOLDER_NAME=${RN_PROJECT_FOLDER_NAME}
- GH_TOKEN=${GH_TOKEN}
- NPM_TOKEN=${NPM_TOKEN}
- NODE_VERSION=${NODE_VERSION}
environment:
- GH_TOKEN=${GH_TOKEN}
- NPM_TOKEN=${NPM_TOKEN}
container_name: "${CONTAINER_NAME}"
volumes:
- type: bind
@ -16,6 +21,3 @@ services:
target: /home/app
ports:
- 8081:8081
environment:
- EXPO_DEVTOOLS_LISTEN_ADDRESS=0.0.0.0

View File

@ -22,10 +22,24 @@ if [[ -z "${CONTAINER_NAME}" ]]; then
fi
# Define the project directory
PROJECT_DIR="/home/app"
PROJECT_DIR="/home/$RN_PROJECT_FOLDER_NAME"
# Docker command handling
case $1 in
up)
# List of required environment variables
REQUIRED_VARS=("SSH_KEY" "GH_TOKEN" "NPM_TOKEN" "NODE_VERSION" "RN_PROJECT_FOLDER_NAME" "CONTAINER_NAME")
for VAR in ${REQUIRED_VARS[@]}; do
if [[ -z "${!VAR}" ]]; then
echo "Error: Required environment variable $VAR is not set"
exit 1
fi
done
# If we get here, all variables are set
docker-compose up
;;
stop-metro)
docker exec -it ${CONTAINER_NAME} supervisorctl stop npm
;;
@ -35,15 +49,14 @@ case $1 in
echo "Please set the RN_PROJECT_FOLDER_NAME environment variable before running the script."
exit 1
fi
docker exec ${CONTAINER_NAME} /bin/bash -c "echo \"//github.com/:_authToken=$GH_TOKEN\" > ${PROJECT_DIR}/.npmrc"
docker exec ${CONTAINER_NAME} /bin/bash -c "cd ${PROJECT_DIR} && npm install" || { echo 'npm install failed' ; exit 1; }
docker exec ${CONTAINER_NAME} /bin/bash -c "rm -f ${PROJECT_DIR}/.npmrc"
docker exec ${CONTAINER_NAME} supervisorctl start npm -- --reset-cache
docker exec ${CONTAINER_NAME} supervisorctl start npm
docker logs -f ${CONTAINER_NAME}
;;
metro-logs)
docker exec -it ${CONTAINER_NAME} cat /var/log/app/npm.log
echo "Press CTRL + C to safely exit. It won't stop the server."
docker exec -it ${CONTAINER_NAME} supervisorctl tail -f npm stdout
;;
connect-android)
@ -72,13 +85,14 @@ case $1 in
echo "Please set the SSH_KEY environment variable before running the script."
exit 1
fi
SSH_KEY_PATH="$HOME/.ssh/id_docker_dev"
# generate ssh key
if [ ! -f "${SSH_KEY}" ]; then
ssh-keygen -t ed25519 -f "${SSH_KEY}" -N ""
echo "SSH key generated at ${SSH_KEY}"
if [ ! -f "${SSH_KEY_PATH}" ]; then
ssh-keygen -t ed25519 -f ${SSH_KEY_PATH} -N ""
echo "SSH key generated at ${SSH_KEY_PATH}"
else
echo "SSH key already exists at ${SSH_KEY}"
echo "SSH key already exists at ${SSH_KEY_PATH}"
fi
# Check if Docker is running
@ -102,7 +116,7 @@ case $1 in
echo "SSH config already contains the Docker IP."
else
echo "Adding Docker IP to SSH config..."
echo -e "Host ${CONTAINER_IP}\n\tPort 22\n\tUser root\n\tPubkeyAuthentication yes\n\tIdentityFile ${SSH_KEY}" >> ~/.ssh/config
echo -e "Host ${CONTAINER_IP}\n\tPort 22\n\tUser root\n\tPubkeyAuthentication yes\n\tIdentityFile ${SSH_KEY_PATH}" >> ~/.ssh/config
echo "Docker IP added to SSH config."
fi
;;

View File

@ -1,21 +0,0 @@
#!/bin/bash
set -e
# Check if GH_TOKEN exists
if [[ -n $GH_TOKEN ]]; then
# Github auth for private npm packages
su -c "echo \"//github.com/:_authToken=$GH_TOKEN\" > /home/app/.npmrc"
fi
# install npm dependencies
su -c "cd /home/app && npm install"
# If GH_TOKEN exists, remove the token
if [[ -n $GH_TOKEN ]]; then
su -c "rm -f /home/app/.npmrc"
fi
# run supervisord
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

View File

@ -19,10 +19,10 @@ stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
[program:npm]
command=bash -c "npm start -- --reset-cache --docker"
command=npm start -- --reset-cache
user=root
autostart=false
autorestart=false
autostart=true
autorestart=true
directory=/home/app
stdout_logfile=/var/log/app/%(program_name)s.log
stderr_logfile=/var/log/app/%(program_name)s.log