How I use GitHub Codespaces for prototyping and demos. Instructions.
Tags: tutorial, beginners, github
Published: 2023-03-03 13:00:44

[GitHub Codespaces](https://docs.github.com/en/codespaces) is an interactive developer environment in GitHub cloud, aka Cloud IDE, that uses VS Code and different types of containers to run User's code and expose internal ports using public URLs if needed.
I don't even remember when I used ngrok last time. Codespaces has all the needed features for my projects. You can work in codespaces with your private and public repo and other public open-source projects on GitHub.


![GitHub Codespaces](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45gk5hq93b5bah39wemy.png)

**What I've enjoyed in GitHub Codespaces:**
* Work, run and deploy your apps from any device and location
* Each developer who has a GitHub account can easily fork and run your repo following instructions
* Expose internal IP addresses and resources
* Adjust and test Interaction using Webhooks or API server

**Disadvantages:**
* CodeSpaces will be deleted after some time of inactivity. The default and maximum parameter is 30 days
* Consequently User can lose the changes if you forget to push it to a related git branch 
* Developer needs to describe how to paste and manage credentials and sensitive data in Codespaces 

List all of your Codespaces you can see on the following page [https://github.com/codespaces](https://github.com/codespaces) 

## Containers in Codespaces


![Create codespace on main](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57etb0j7ldum2e5muoyj.png)
What happens when the User opens a repository in Codespaces by clicking "Create codespace on main":
* Default Linux Universal container is deployed
* All repository source code and other files uploaded to the new Codespace 
* Cloud VS Code will be available through the users browser

Default Linux Universal supports the following programming languages: Python, Node.js, JavaScript, TypeScript, C++, Java, C#, F#, .NET Core, PHP, Go, Ruby, and Conda.

The following customization is available:
* Customize your container
* Open related file(s) in Codespace
* Provide post-create a terminal command that will run automatically
* Port Forwarding instructions

All these instructions should be described in the `.devcontainer/devcontainer.json` file. The `.devcontainer` folder should be stored in the root directory of your repo

You can configure the dev container for a repository so that codespaces created for that repository give you a tailored development environment, complete with all the tools and runtimes you need to work on a specific project. Suppose you don't define a configuration in the repository. In that case, GitHub Codespaces uses a default configuration, which contains many of the standard tools that your team might need to develop your project.

The following examples use a universal container with 4 CPUs, and after deploying the container in Codespace, we open `README.md` and `index.js` files, run the `npm start` command, and Expose an internal 3000 port with a public URL (like https://${CODESPACE_NAME}-3000.preview.app.github.dev/)


```json
{
 "image": "mcr.microsoft.com/devcontainers/universal:2",
 "hostRequirements": {
   "cpus": 4
 },
 "waitFor": "onCreateCommand",
 "updateContentCommand": "npm install",
 "postCreateCommand":"  ",
 "postAttachCommand": {
   "server": "npm start"
 },
 "customizations": {
   "codespaces": {
     "openFiles": [
       "README.md",
       "index.js"
     ]
   }
 },
 "portsAttributes": {
   "3000": {
     "label": "Application",
     "onAutoForward": "openPreview"
   }
 },
 "forwardPorts": [3000]
}
```
## Codespace environment variables

There are a few Codespace environment variables that are helpful for the topic of this article:

* `CODESPACE_NAME` - The name of the Codespace For example, `octocat-literate-space-parakeet-mld5`
* `GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN` - Returns the domain of the GitHub Codespaces forwarded port. Usually, `preview.app.github.dev`

We have a few ways how we can use and store static public URL
Print URL in the terminal and copy and paste it into a related .env file or into the source code 

The following examples help construct external URLs for the Node.js and Python Flask App.

The app is running on port 3000
```javascript
const port = 3000
app.listen(port, () => { console.log(`App listening on port ${port}`) });
``` 

And you need to get the URL for the webhooks event.

```bash
echo "https://${CODESPACE_NAME}-3000.preview.app.github.dev/webhooks/event"
```
Or if you set the env variable as
```bash
PORT=3000
```

Than, we can construct this URL by the following command
```bash
echo "https://${CODESPACE_NAME}-${PORT}.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}/webhooks/event" 
```
Expected output:

![codespace url](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dy5qv4sdqywixx9pgtt2.png)

The following code snippet deploys Flask App on port 8080

```python
if __name__ == '__main__':
    app.run(host="localhost", port=8080)
```

Let's run this command to the URL for the Flask App
```bash
echo "https://${CODESPACE_NAME}-8080.preview.app.github.dev/"
```

By default Codespace port is private.
So in the terminal, open the Port tab. Click on `Private` in the `Visibility` column, and change it to `Public`

![Codespace port](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nenzjgeoqyk28srscivm.png)

Share your tips for using Codespaces in the comments.