Newer
Older
# Setup your development environment <!-- omit in toc -->
## Table of contents <!-- omit in toc -->
- [Introduction](#introduction)

Yassine Doghri
committed
- [Pre-requisites](#pre-requisites)
- [(recommended) Develop inside the app Container with VSCode](#recommended-develop-inside-the-app-container-with-vscode)
- [(not-recommended) Develop outside the app container](#not-recommended-develop-outside-the-app-container)

Yassine Doghri
committed
- [Install Castopod Host's dependencies](#install-castopod-hosts-dependencies)
- [Initialize and populate database](#initialize-and-populate-database)
- [Start hacking](#start-hacking)
- [Going Further](#going-further)
- [Useful docker / docker-compose commands](#useful-docker--docker-compose-commands)
- [Known issues](#known-issues)

Yassine Doghri
committed
- [Allocation failed - JavaScript heap out of memory](#allocation-failed---javascript-heap-out-of-memory)
- [Files created inside container are attributed to root locally (Linux)](#files-created-inside-container-are-attributed-to-root-locally-linux)
## Introduction

Yassine Doghri
committed
Castopod Host is a web app based on the `php` framework
[CodeIgniter 4](https://codeigniter.com).
To setup a dev environment, we use [Docker](https://www.docker.com/). A
`docker-compose.yml` and `Dockerfile` are included in the project's root folder
to help you kickstart your contribution.
> Know that you don't need any prior knowledge of Docker to follow the next
> steps. However, if you wish to use your own environment, feel free to do so!

Yassine Doghri
committed
## Pre-requisites

Yassine Doghri
committed
0. Install [docker](https://docs.docker.com/get-docker).

Yassine Doghri
committed
1. Clone Castopod Host project by running:

Yassine Doghri
committed
```bash
git clone https://code.podlibre.org/podlibre/castopod-host.git
```
2. Create a `.env` file with the minimum required config to connect the app to
the database and use redis as a cache handler:

Yassine Doghri
committed
```ini
CI_ENVIRONMENT="development"

Yassine Doghri
committed
# By default, this is set to true in the app config.
# For development, this must be set to false as it is
# on a local environment
app.forceGlobalSecureRequests=false

Yassine Doghri
committed

Yassine Doghri
committed
app.baseURL="http://localhost:8080/"
app.mediaBaseURL="http://localhost:8080/"

Yassine Doghri
committed
admin.gateway="cp-admin"
auth.gateway="cp-auth"

Yassine Doghri
committed
database.default.hostname="mariadb"
database.default.database="castopod"
database.default.username="podlibre"
database.default.password="castopod"

Yassine Doghri
committed
cache.handler="redis"
cache.redis.host = "redis"

Yassine Doghri
committed
# You may not want to use redis as your cache handler
# Comment/remove the two lines above and uncomment
# the next line for file caching.
#cache.handler="file"
```

Yassine Doghri
committed
> _NB._ You can tweak your environment by setting more environment variables
> in your custom `.env` file. See the `env` for examples or the
> [CodeIgniter4 User Guide](https://codeigniter.com/user_guide/index.html)
> for more info.

Yassine Doghri
committed
3. (for docker desktop) Add the repository you've cloned to docker desktop's
`Settings` > `Resources` > `File Sharing`

Yassine Doghri
committed
## (recommended) Develop inside the app Container with VSCode

Yassine Doghri
committed
If you're working in VSCode, you can take advantage of the `.devcontainer/`
folder. It defines a development environment (dev container) with preinstalled
requirements and VSCode extensions so you don't have to worry about them. All
required services will be loaded automagically!

Yassine Doghri
committed
1. Install the VSCode extension
[Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
2. `Ctrl/Cmd + Shift + P` > `Open in container`
> The VSCode window will reload inside the dev container. Expect several
> minutes during first load as it is building all necessary services.
**Note**: The dev container will start by running Castopod Host's php server.
During development, you will have to start [Vite](https://vitejs.dev)'s dev
server for compiling the typescript code and styles:
```bash
# run Vite dev server
npm run dev
```
If there is any issue with the php server not running, you can restart them
using the following commands:
```bash
# run Castopod host server
php spark serve --host 0.0.0.0
```

Yassine Doghri
committed
3. You're all set! 🎉

Yassine Doghri
committed
You're now **inside the dev container**, you may use the VSCode console
(`Terminal` > `New Terminal`) to run any command:

Yassine Doghri
committed
```bash
# PHP is installed
php -v

Yassine Doghri
committed
# Composer is installed
composer -V

Yassine Doghri
committed
# npm is installed
npm -v

Yassine Doghri
committed
# git is installed
git version
```

Yassine Doghri
committed
For more info, see
[VSCode Remote Containers](https://code.visualstudio.com/docs/remote/containers)

Yassine Doghri
committed
## (not-recommended) Develop outside the app container

Yassine Doghri
committed
You do not wish to use the VSCode devcontainer? No problem!

Yassine Doghri
committed
1. Start docker containers manually:

Yassine Doghri
committed
Go to project's root folder and run:

Yassine Doghri
committed
```bash
# starts all services declared in docker-compose.yml file
# -d option starts the containers in the background
docker-compose up -d

Yassine Doghri
committed
# See all running processes (you should see 3 processes running)
docker-compose ps

Yassine Doghri
committed
# Alternatively, you can check all docker processes
docker ps -a

Yassine Doghri
committed
```

Yassine Doghri
committed
> The `docker-compose up -d` command will boot 4 containers in the
> background:
>

Yassine Doghri
committed
> - `castopod-host_app`: a php based container with CodeIgniter4 requirements

Yassine Doghri
committed
> installed

Yassine Doghri
committed
> - `castopod-host_redis`: a [redis](https://redis.io/) database to handle

Yassine Doghri
committed
> queries and pages caching

Yassine Doghri
committed
> - `castopod-host_mariadb`: a [mariadb](https://mariadb.org/) server for

Yassine Doghri
committed
> persistent data

Yassine Doghri
committed
> - `castopod-host_phpmyadmin`: a phpmyadmin server to visualize the mariadb

Yassine Doghri
committed
> database.

Yassine Doghri
committed
2. Run any command by prefixing them with `docker-compose run --rm app`:

Yassine Doghri
committed
```bash
# use PHP
docker-compose run --rm app php -v

Yassine Doghri
committed
# use Composer
docker-compose run --rm app composer -V

Yassine Doghri
committed
# use npm
docker-compose run --rm app npm -v

Yassine Doghri
committed
# use git
docker-compose run --rm app git version
```

Yassine Doghri
committed

Yassine Doghri
committed
## Install Castopod Host's dependencies

Yassine Doghri
committed

Yassine Doghri
committed
1. Install php dependencies with [Composer](https://getcomposer.org/)

Yassine Doghri
committed

Yassine Doghri
committed
```bash
composer install
```

Yassine Doghri
committed

Yassine Doghri
committed
> **Note:**
>
> The php dependencies aren't included in the repository. Composer will check
> the `composer.json` and `composer.lock` files to download the packages with
> the right versions. The dependencies will live under the `vendor/` folder.
> For more info, check out the
> [Composer documentation](https://getcomposer.org/doc/).

Yassine Doghri
committed
2. Install javascript dependencies with [npm](https://www.npmjs.com/)

Yassine Doghri
committed
```bash
npm install
```

Yassine Doghri
committed
> **Note:**
>
> The javascript dependencies aren't included in the repository. Npm will
> check the `package.json` and `package.lock` files to download the packages
> with the right versions. The dependencies will live under the `node_module`
> folder. For more info, check out the
> [NPM documentation](https://docs.npmjs.com/).

Yassine Doghri
committed
3. Generate static assets:

Yassine Doghri
committed
```bash
# build all static assets at once
npm run build:static
# build specific assets

Yassine Doghri
committed
npm run build:icons
npm run build:svg
```

Yassine Doghri
committed
> **Note:**
>
> The static assets generated live under the `public/assets` folder, it
> includes javascript, styles, images, fonts, icons and svg files.

Yassine Doghri
committed
## Initialize and populate database

Yassine Doghri
committed
> **Note:**
>
> You may skip this section if you go through the install wizard (go to
> `/cp-install`).

Yassine Doghri
committed
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
1. Build the database with the migrate command:
```bash
# loads the database schema during first migration
php spark migrate -all
```
You may need to undo the migration (rollback):
```bash
# rolls back database schema (deletes all tables and their content)
php spark migrate:rollback
```
2. Populate the database with the required data:
```bash
# Populates all required data
php spark db:seed AppSeeder
```
You may choose to add data separately:
```bash
# Populates all categories
php spark db:seed CategorySeeder
# Populates all Languages
php spark db:seed LanguageSeeder
# Populates all podcasts platforms
php spark db:seed PlatformSeeder
# Populates all Authentication data (roles definition…)
php spark db:seed AuthSeeder
```
3. (optionnal) Populate the database with test data:
```bash
# Populates test data (login: admin / password: AGUehL3P)
php spark db:seed TestSeeder
# Populates with fake podcast analytics
php spark db:seed FakePodcastsAnalyticsSeeder
# Populates with fake website analytics
php spark db:seed FakeWebsiteAnalyticsSeeder
```
TestSeeder will add an active superadmin user with the following credentials:
- username: **admin**
- password: **AGUehL3P**
## Start hacking
You're all set! Start working your magic by updating the project's files! Help
yourself to the
[CodeIgniter4 User Guide](https://codeigniter.com/user_guide/index.html) for
more insights.
To see your changes, go to:

Yassine Doghri
committed
- [localhost:8080](http://localhost:8080/) for the Castopod Host app
- [localhost:8888](http://localhost:8888/) for the phpmyadmin interface:

Yassine Doghri
committed
- username: **podlibre**
- password: **castopod**
---
## Going Further
### Useful docker / docker-compose commands
```bash
# monitor the app container

Yassine Doghri
committed
docker-compose logs --tail 50 --follow --timestamps app
# interact with redis server using included redis-cli command

Yassine Doghri
committed
docker exec -it castopod-host_redis redis-cli
# monitor the redis container
docker-compose logs --tail 50 --follow --timestamps redis
# monitor the mariadb container

Yassine Doghri
committed
docker-compose logs --tail 50 --follow --timestamps mariadb
# monitor the phpmyadmin container

Yassine Doghri
committed
docker-compose logs --tail 50 --follow --timestamps phpmyadmin
# restart docker containers
docker-compose restart
# Destroy all containers, opposite of `up` command
docker-compose down

Yassine Doghri
committed
# Rebuild app container
docker-compose build app
```
Check [docker](https://docs.docker.com/engine/reference/commandline/docker/) and
[docker-compose](https://docs.docker.com/compose/reference/) documentations for
more insights.
## Known issues

Yassine Doghri
committed
### Allocation failed - JavaScript heap out of memory

Yassine Doghri
committed
This happens when running `npm install`.
👉 By default, docker might not have access to enough RAM. Allocate more memory
and run `npm install` again.
### Files created inside container are attributed to root locally (Linux)
You may use Linux user namespaces to fix this on your machine:

Yassine Doghri
committed
> **Note:**
>
> Replace "username" with your local username
1. Go to `/etc/docker/daemon.json` and add:
```json
{
"userns-remap": "username"
}
```
2. Configure the subordinate uid/guid:
```bash
# in /etc/subuid

Yassine Doghri
committed
username:1000:1
username:100000:65536
```
```bash
# in /etc/subgid

Yassine Doghri
committed
username:1000:1
username:100000:65536
```
3. Restart docker:
```bash
sudo systemctl restart docker
```
4. That's it! Now, the root user in the container will be mapped to the user on
your local machine, no more permission issues! 🎉

Yassine Doghri
committed
You can check
[this great article](https://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/)
to know more about how it works.