Once the image is available we can write an install script. You can see below a sample install script for gitlab.
```sh cat > docker-compose.yml << 'EOF' gitlab-container: image: 'gitlab/gitlab-ce:latest' container_name: "APP_IDENTIFIER" restart: unless-stopped hostname: 'APP_HOSTNAME' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://APP_HOSTNAME:HOST_PORT' gitlab_rails['gitlab_shell_ssh_port'] = 2224 ports: - 'HOST_PORT:HOST_PORT' - '2224:22' volumes: - './srv/gitlab/config:/etc/gitlab' - './srv/gitlab/logs:/var/log/gitlab' - './srv/gitlab/data:/var/opt/gitlab' EOF docker-compose up -d```
This script creates a docker-compose.yml file and then runs `docker-compose up -d` command which essentially creates and runs the container.
===Understanding the script===
Container script for each app will have these parameters for sure:
```
container-name: "APP_IDENTIFIER"
restart : unless-stopped
ports:
- 'HOST_PORT:xyz' # Not required for apps which are not webapp
container-name: "APP_IDENTIFIER" restart : unless-stopped ports: - 'HOST_PORT:xyz' # Not required for apps which are not webapp # xyz = any port inside the container # HOST_PORT is port on the host machine. Two different containers cannot have same value for # HOST_PORT but can have the same value for xyz (Just to clear up the confusion about # HOST_PORT)```
Most of the configuration related to the container will be written in the docker-compose.yml file but some data we have to extract during run time like the HOST_PORT using which will reverse proxy to the container. HOST_PORT is 35000+app_id and has to be derived during app installation. Similarly APP_IDENTIFIER and APP_HOSTNAME are derived during runtime. The code below is used to put that data into install script during runtime.
```rb #app/models/app.rb Line 322 to 326 install_script = installer.install_script install_script = install_script.gsub(/HOST_PORT/, (BASE_PORT+self.id).to_s) install_script = install_script.gsub(/WEBAPP_PATH/, webapp_path) install_script = install_script.gsub(/APP_IDENTIFIER/, identifier) install_script = install_script.gsub(/APP_HOSTNAME/, app_host)```
Sample uninstall script
```sh docker-compose stop docker-compose rm -f # Not removing the image. Just stopping the container. ```
For most containers the above uninstallation script will work fine. This stops the running container and removes it. Please note that this doesn't delete any of the volumes attached (persistent storage. Please refer to docker documentatio for more details regarding volumes) with the container so if you add a volume during installation (as we have done in the gitlab example above) then we have to remove them here during uninstallation. For example if we were to remove gitlab completely along with all files that were added by gitlab container then the uninstall script would look something like this:
```sh docker-compose stop docker-compose rm -f rm -rf srv # Removing the srv folder which holds the persistent files for gitlab container```
This behaviour might not be intended for all applications. Right now I haven't removed static files for any apps that I have added.
For reverse proxy I have added a new app-container.conf file which can be seen below. The `APP_PORT` is changed during runtime.
```sh <VirtualHost *:80> ServerName HDA_APP_NAME ServerAlias HDA_APP_NAME.HDA_DOMAIN APP_ALIASES APP_CUSTOM_OPTIONS ProxyPreserveHost On ProxyPass / http://localhost:APP_PORT/ ProxyPassReverse / http://localhost:APP_PORT/ ErrorLog APP_ROOT_DIR/logs/error_log CustomLog APP_ROOT_DIR/logs/access_log combined env=!dontlog </VirtualHost>
ProxyPass / http://localhost:APP_PORT/
ProxyPassReverse / http://localhost:APP_PORT/
ErrorLog APP_ROOT_DIR/logs/error_log
CustomLog APP_ROOT_DIR/logs/access_log combined env=!dontlog
</VirtualHost>
```
APP_PORT part is derived from the app id. After installation the app will have some id in the database base. The APP_PORT will be 35000+app_id
See the usage as mentioned by the maintainer:
```sh docker create --name=hydra \ -v <path to data>:/config \ -v <nzb download>:/downloads \ -e PGID=<gid> -e PUID=<uid> \ -e TZ=<timezone> \ -p 5075:5075 linuxserver/hydra```
Convert the above to a docker-compose file. Ignore the `-e PGID=<gid> -e PUID=<uid>`, even though it's relevant, it is out of the scope of this discussion.
``` hydra-container: image: 'docker.io/linuxserver/hydra' container_name: "hydra" restart: unless-stopped ports: - '5075:5075' volumes: - './config:/config' - './downloads:/downloads' - '/etc/localtime:/etc/localtime:ro' # Understanding the volume mounts: # ./config:/config -> As seen in the docker create commnad the -v command mentions the volumes. # Path to data that we are providing is a relative path. Every installed app has a path in which the # install script runs. So "config" and "downloads" folder will be created there in that path. # /etc/localtime:/etc/localtime:ro -> This is to make sure that the container uses the same time as used # by the host system. To avoid this mount we can also use # environment: # - TZ=<timezone> # in the docker compose file
# Understanding the volume mounts:
# ./config:/config -> As seen in the docker create commnad the -v command mentions the volumes.
# Path to data that we are providing is a relative path. Every installed app has a path in which the
# install script runs. So "config" and "downloads" folder will be created there in that path.
# /etc/localtime:/etc/localtime:ro -> This is to make sure that the container uses the same time as used
# by the host system. To avoid this mount we can also use
# environment:
# - TZ=<timezone>
# in the docker compose file
```
NOTE: Please note that adding apps might require knowledge about docker and docker-compose and discussing those is out of the scope of this documentation though the links mentioned below might be useful.
For adding to amahi.org some modifications have to be done. The final changes can be seen below. Notice the `APP_IDENTIFIER` and `HOST_PORT` (For more info on this refer to "Understandin the script" section)
``` hydra-container: image: 'docker.io/linuxserver/hydra' container_name: "APP_IDENTIFIER" restart: unless-stopped ports: - 'HOST_PORT:5075' volumes: - './config:/config' - './downloads:/downloads' - '/etc/localtime:/etc/localtime:ro'```
The final install and uninstall scripts to be added on amahi.org will be
Install Script
```sh cat > docker-compose.yml << 'EOF' hydra-container: image: 'docker.io/linuxserver/hydra' container_name: "APP_IDENTIFIER" restart: unless-stopped ports: - 'HOST_PORT:5075' volumes: - './config:/config' - './downloads:/downloads' - '/etc/localtime:/etc/localtime:ro' EOF docker-compose up -d```
Uninstall Script
```sh docker-compose stop docker-comose rm -f rm -rf config # Use this if you want all files to be removed after uninstall rm -rf downloads # Use this if you want all files to be removed after uninstall```
## NOTE