Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix make podman work on fedora, apple silicone and windows OS #74

Merged
merged 23 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8f4ff10
fix podman compose script with podman machine running with applehv du…
tjololo Jan 18, 2024
dfcdff2
update all volume definitions so they match
tjololo Jan 18, 2024
ef85e0c
remove bind.selinux as it does not seem to have any affect
tjololo Jan 18, 2024
d1b79c7
Add updated readme for podman and add a hack for resolving the bind i…
tjololo Jan 24, 2024
4bb478e
update readme
tjololo Jan 24, 2024
41bf85d
adde one line to readme.md
tjololo Jan 24, 2024
3c139b5
test new notation for information and warnings
tjololo Jan 24, 2024
36dc653
test more with info sections
tjololo Jan 24, 2024
fc6359b
try to fix indend
tjololo Jan 24, 2024
14dfc9c
Restructure the readme
tjololo Jan 24, 2024
84c2653
update readme
tjololo Jan 24, 2024
4c77ed0
some small changes to the README.md
tjololo Jan 24, 2024
d6be11a
use host.docker.internal as it seems to work on both windows and mac
tjololo Jan 25, 2024
305d356
change nginx internal domain to host.containers.internal
tjololo Jan 26, 2024
e78b9e9
Differentiate on host and container domains for podman
tjololo Jan 26, 2024
545f90d
bind problems also seems to be present on fedora. Renaming hack metho…
tjololo Jan 26, 2024
92dfe5b
update readme with known issue about bind mounts
tjololo Jan 26, 2024
e32363b
fix bug in makefile
tjololo Jan 29, 2024
f16a8c1
Make local frontend port configurable
tjololo Jan 31, 2024
d8fa105
Podman defaults localtest to 8000
tjololo Feb 1, 2024
cb23b2d
Update readme with guide to add hyper-v firewall rule if needed
tjololo Feb 5, 2024
c76ddc6
big Z instead of small z
tjololo Feb 5, 2024
02e0cc0
Update known issue in readme
tjololo Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

## What port should the loadbalancer use?
## sometimes PCs have another service running on port 80, so you might need to
## change this. Default in podman-compose.yml is 8080 as ports below 1024 are privileged ports on most unix systems.
## change this.
## Default in podman-compose.yml is 8000 as ports below 1024 are privileged ports on most unix systems.

#ALTINN3LOCAL_PORT=80

Expand Down
18 changes: 17 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,20 @@ podman-start-localtest:

.PHONY: podman-stop-localtest
podman-stop-localtest:
podman compose --file podman-compose.yml down
podman compose --file podman-compose.yml down

.PHONY: podman-compose-start-localtest
podman-compose-start-localtest:
podman-compose --file podman-compose.yml up -d --build

.PHONY: podman-compose-stop-localtest
podman-compose-stop-localtest:
podman-compose --file podman-compose.yml down


.PHONY: podman-selinux-bind-hack
podman-selinux-bind-hack:
@echo "Running best effort commands to make bind mounts work on Apple Silicon and Linux with podman. Dirty hack until actual issue is located and fixed."
podman container run -v ./testdata/:/testdata/:z --rm -it --entrypoint cat nginx:alpine-perl /testdata/authorization/claims/1337.json > /dev/null
podman container run -v ./loadbalancer/templates/:/testdata/:z --rm -it --entrypoint cat nginx:alpine-perl /testdata/nginx.conf.conf > /dev/null
podman container run -v ./loadbalancer/www/:/testdata/:z --rm -it --entrypoint cat nginx:alpine-perl /testdata/502App.html > /dev/null
164 changes: 97 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ These are some of the required steps, tips, and tricks when it comes to running

- [Prerequisites](#prerequisites)
- [Setup](#setup)
- [Clone the repository](#clone-the-repository)
- [Option A: Start the containers using podman](#option-a-start-the-containers-using-podman)
- [Option B: Start the containers using Docker](#option-b-start-the-containers-using-docker)
- [Start your app](#start-your-app)
- [Changing configuration](#changing-configuration)
- [Multiple apps at the same time (running LocalTest locally)](#multiple-apps-at-the-same-time-running-localtest-locally)
- [Changing test data](#changing-test-data)
- [Known issues](#known-issues)

### Prerequisites

Expand All @@ -14,89 +21,94 @@ These are some of the required steps, tips, and tricks when it comes to running
- Also
install [recommended extensions](https://code.visualstudio.com/docs/editor/extension-gallery#_workspace-recommended-extensions) (
f.ex. [C#](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp))
4. [Docker Desktop](https://www.docker.com/products/docker-desktop) (Linux users can also use native Docker)

4. [Podman Desktop](https://podman-desktop.io)/[Podman](https://podman.io) (Linux users can also use native Docker) or [Docker Desktop](https://www.docker.com/products/docker-desktop) (Windows and Mac) This might require you to purchase a license.
On mac with apple silicone (M1, M2, M3):
5. [vfkit](https://github.com/crc-org/vfkit?tab=readme-ov-file#installation)
### Setup

#### Using docker

1. Clone the `app-localtest` repository to a local folder and move into the folder.

```shell
git clone https://github.com/Altinn/app-localtest
cd app-localtest
```

2. Build and run the containers in the background.

```shell
docker compose up -d --build
```
#### Clone the repository

:information_source: If you are using linux or mac you can use the Makefile to build and run the containers.

```shell
make docker-start-localtest
```

This mode supports running one app at a time. If you need to run multiple apps at once, stop the localtest container with `docker stop localtest` and follow the instructions below to run LocalTest locally outside Docker.
```shell
git clone https://github.com/Altinn/app-localtest
cd app-localtest
```

3. Start your app
_This step requires that you have already [created an app](https://docs.altinn.studio/app/getting-started/create-app/), added a [data model](https://docs.altinn.studio/app/development/data/data-model/data-models-tool/), and [cloned the app](https://docs.altinn.studio/app/getting-started/local-dev/) to your local environment._

Move into the `App` folder of your application.
#### Option A: Start the containers using podman

Example: If your application is named `my-awesome-app` and is located in the folder `C:\my_applications`, run the following command:

```shell
cd C:\my_applications\my-awasome-app\App
```

Run the application:

```shell
dotnet run
```

#### Using podman

1. Clone the `app-localtest` repository to a local folder and move into the folder.

```shell
git clone https://github.com/Altinn/app-localtest
cd app-localtest
```
This mode supports running one app at a time. If you need to run multiple apps at once, stop the localtest container with `podman stop localtest` and follow the instructions below to run LocalTest locally outside Docker/Podman.

2. Build and run the containers in the background.
> [!IMPORTANT]
> If you are using an mac with either a M1, M2 or M3 chip you may need to use `applehv` instead of `qemu` as the podman machine driver.
> This can be done by setting the environment variable `CONTAINERS_MACHINE_PROVIDER` to `applehv` before running the command below.
> To add this to your zsh profile run the following command: `echo "export CONTAINERS_MACHINE_PROVIDER=applehv" >> ~/.zprofile`
> If you are using Podman Desktop you also need to add these lines in `~/.config/containers/containers.conf` (check if the `[machine]` section already exists):
>
> ```
> [machine]
> provider = "applehv"
> ```

```shell
podman compose --file podman-compose.yml up -d --build
```
Start the containers with the following command:

:information_source: If you are using linux or mac you can use the Makefile to build and run the containers.
```shell
podman compose --file podman-compose.yml up -d --build
```

```shell
make podman-start-localtest
```
> [!NOTE]
> If you are using linux or mac you can use the Makefile to build and run the containers.
>
> ```shell
> make podman-start-localtest
> ```

> [!IMPORTANT]
> Are you running podman version < 4.7.0 you need to use the following command instead:
>
> ```shell
> podman-compose --file podman-compose.yml up -d --build
> ```
>
> or the make command:
>
> ```shell
> make podman-compose-start-localtest
> ```

Localtest should now be runningn on port 8000 and can be accessed on <http://local.altinn.cloud:8000>.

#### Option B: Start the containers using Docker

This mode supports running one app at a time. If you need to run multiple apps at once, stop the localtest container with `docker stop localtest` and follow the instructions below to run LocalTest locally outside Docker.

```shell
docker compose up -d --build
```

> [!NOTE]
> If you are using linux or mac you can use the Makefile to build and run the containers.
>
> ```shell
> make docker-start-localtest
> ```

This mode supports running one app at a time. If you need to run multiple apps at once, stop the localtest container with `podman stop localtest` and follow the instructions below to run LocalTest locally outside Docker.
Localtest should now be runningn on port 80 and can be accessed on <http://local.altinn.cloud:80>.

3. Start your app
_This step requires that you have already [created an app](https://docs.altinn.studio/app/getting-started/create-app/), added a [data model](https://docs.altinn.studio/app/development/data/data-model/data-models-tool/), and [cloned the app](https://docs.altinn.studio/app/getting-started/local-dev/) to your local environment._
#### Start your app
_This step requires that you have already [created an app](https://docs.altinn.studio/app/getting-started/create-app/), added a [data model](https://docs.altinn.studio/app/development/data/data-model/data-models-tool/), and [cloned the app](https://docs.altinn.studio/app/getting-started/local-dev/) to your local environment._

Move into the `App` folder of your application.
Move into the `App` folder of your application.

Example: If your application is named `my-awesome-app` and is located in the folder `C:\my_applications`, run the following command:
Example: If your application is named `my-awesome-app` and is located in the folder `C:\my_applications`, run the following command:

```shell
cd C:\my_applications\my-awasome-app\App
```
```shell
cd C:\my_applications\my-awasome-app\App
```

Run the application:
Run the application:

```shell
dotnet run
```
```shell
dotnet run
```

The app and local platform services are now running locally. The app can be accessed on <http://local.altinn.cloud>.

Expand Down Expand Up @@ -203,3 +215,21 @@ This would be required if your app requires a role which none of the test users

4. Save and close the file
5. Restart LocalTest

### Known issues

#### Bind mounts folders gives permission denied. Nginx returns default page

On some nix systems you might experience problems with the bind mounts used by the containers. If you get the default nginx page when trying to access local.altinn.cloud this might be the case.

To verify this you can run the following command:

```shell
podman container exec -it localtest-loadbalancer cat /etc/nginx/templates/nginx.conf.conf
```

if you get a permission denied message this verifies that the bind mount is not working. A best effort fix for this is to run the following command:

```shell
make podman-selinux-bind-hack
```
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ services:
- NGINX_HOST=localhost
- NGINX_PORT=80
- TEST_DOMAIN=${TEST_DOMAIN:-local.altinn.cloud}
- HOST_DOMAIN=host.docker.internal
- INTERNAL_DOMAIN=host.docker.internal
- ALTINN3LOCAL_PORT=${ALTINN3LOCAL_PORT:-80}
- NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx/
Expand Down
2 changes: 1 addition & 1 deletion loadbalancer/templates/nginx.conf.conf
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ http {
}

upstream app {
server ${INTERNAL_DOMAIN}:5005;
server ${HOST_DOMAIN}:5005;
}
# Redirect localhost and the old altinn3local.no to the configured test domain
server {
Expand Down
33 changes: 24 additions & 9 deletions podman-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,34 @@ networks:
external: false

services:
local.altinn.cloud:
localtest_loadbalancer:
container_name: localtest-loadbalancer
image: nginx:alpine-perl
restart: always
networks:
- altinntestlocal_network
altinntestlocal_network:
aliases:
- ${TEST_DOMAIN:-local.altinn.cloud}
ports:
- "${ALTINN3LOCAL_PORT:-8080}:80"
- "${ALTINN3LOCAL_PORT:-8000}:80"
environment:
- NGINX_HOST=localhost
- NGINX_PORT=80
- TEST_DOMAIN=${TEST_DOMAIN:-local.altinn.cloud}
- HOST_DOMAIN=host.docker.internal
- INTERNAL_DOMAIN=host.containers.internal
- ALTINN3LOCAL_PORT=${ALTINN3LOCAL_PORT:-80}
- ALTINN3LOCAL_PORT=${ALTINN3LOCAL_PORT:-8000}
- NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx/
- NGINX_ENVSUBST_TEMPLATE_SUFFIX=.conf
volumes:
- ./loadbalancer/templates:/etc/nginx/templates/:ro
- ./loadbalancer/www:/www/:ro
- type: bind
source: ./loadbalancer/templates/
target: /etc/nginx/templates/
read_only: true
- type: bind
source: ./loadbalancer/www/
target: /www/
read_only: true


altinn_platform_pdf:
Expand Down Expand Up @@ -57,11 +66,17 @@ services:
environment:
- DOTNET_ENVIRONMENT=Podman
- ASPNETCORE_URLS=http://*:5101/
- GeneralSettings__BaseUrl=http://${TEST_DOMAIN:-local.altinn.cloud}:${ALTINN3LOCAL_PORT:-80}
- GeneralSettings__BaseUrl=http://${TEST_DOMAIN:-local.altinn.cloud}:${ALTINN3LOCAL_PORT:-8000}
- GeneralSettings__HostName=${TEST_DOMAIN:-local.altinn.cloud}
volumes:
- ./testdata:/testdata
- ${ALTINN3LOCALSTORAGE_PATH:-AltinnPlatformLocal}:/AltinnPlatformLocal
- type: volume
source: AltinnPlatformLocal
target: /AltinnPlatformLocal/
read_only: false
- type: bind
source: ./testdata/
target: /testdata/
read_only: true

volumes:
AltinnPlatformLocal:
4 changes: 4 additions & 0 deletions src/Configuration/LocalPlatformSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public string LocalTestingStaticTestDataPath
}
}

public string LocalFrontendHostname { get; set; }

public string LocalFrontendProtocol { get; set; } = "http";

/// <summary>
/// Url for the local app when LocalAppMode == http
/// <summary>
Expand Down
25 changes: 13 additions & 12 deletions src/Controllers/FrontendVersionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
using System.Text.Json;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

using LocalTest.Configuration;
using LocalTest.Models;
using LocalTest.Services.LocalApp.Interface;

using LocalTest.Services.TestData;
using LocalTest.Services.LocalFrontend.Interface;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc.Rendering;

Expand All @@ -23,7 +18,7 @@ public class FrontendVersionController : Controller
public static readonly string FRONTEND_URL_COOKIE_NAME = "frontendVersion";

[HttpGet]
public async Task<ActionResult> Index([FromServices] HttpClient client)
public async Task<ActionResult> Index([FromServices] HttpClient client, [FromServices] ILocalFrontendService localFrontendService)
{
var versionFromCookie = HttpContext.Request.Cookies[FRONTEND_URL_COOKIE_NAME];

Expand All @@ -36,14 +31,20 @@ public async Task<ActionResult> Index([FromServices] HttpClient client)
{
Text = "Keep as is",
Value = "",
},
new ()
{
Text = "localhost:8080 (local dev)",
Value = "http://localhost:8080/"
}
}
};
var groupLocalVersions = new SelectListGroup() { Name = "Frontend served from local dev server" };
var localFrontendPorts = await localFrontendService.GetLocalFrontendDevPorts();
foreach (var localPort in localFrontendPorts)
{
frontendVersion.Versions.Add(new SelectListItem()
{
Text = $"Local dev-server on port {localPort.Port} ({localPort.Branch} branch)",
Value = $"http://localhost:{localPort.Port}/",
Group = groupLocalVersions
});
}
var cdnVersionsString = await client.GetStringAsync("https://altinncdn.no/toolkits/altinn-app-frontend/index.json");
var groupCdnVersions = new SelectListGroup() { Name = "Specific version from cdn" };
var versions = JsonSerializer.Deserialize<List<string>>(cdnVersionsString)!;
Expand Down
7 changes: 7 additions & 0 deletions src/Models/LocalFrontendInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace LocalTest.Models;

public struct LocalFrontendInfo
{
public string Port { get; init; }
public string Branch { get; init; }
}
Loading
Loading