philomena-dev / philomena

Next-generation imageboard
GNU Affero General Public License v3.0
84 stars 29 forks source link

"Could not fetch environment variable "PORT" because it is not set." #224

Closed KamillaPup closed 2 months ago

KamillaPup commented 2 months ago

I've had to move to a new server and switched to prod mode but the first step was to build a virgin philomena from the latest version then move data over.

Sadly, I keep getting this error when doing docker-compose up

app_1            | 19:41:41.167 [info] Loading 141 CA(s) from :otp store
app_1            | ** (System.EnvError) could not fetch environment variable "PORT" because it is not set
app_1            |     (elixir 1.16.1) lib/system.ex:721: System.fetch_env!/1
app_1            |     /srv/philomena/config/runtime.exs:133: (file)
app_1            |     (stdlib 5.2) erl_eval.erl:750: :erl_eval.do_apply/7
app_1            |     (stdlib 5.2) erl_eval.erl:1026: :erl_eval.expr_list/7
app_1            |     (stdlib 5.2) erl_eval.erl:292: :erl_eval.expr/6
app_1            |     (stdlib 5.2) erl_eval.erl:282: :erl_eval.expr/6
app_1            |     (stdlib 5.2) erl_eval.erl:283: :erl_eval.expr/6
app_1            | 
app_1            | 19:41:41.184 [info] Loading 141 CA(s) from :otp store
app_1            | ** (System.EnvError) could not fetch environment variable "PORT" because it is not set
app_1            |     (elixir 1.16.1) lib/system.ex:721: System.fetch_env!/1
app_1            |     /srv/philomena/config/runtime.exs:133: (file)
app_1            |     (stdlib 5.2) erl_eval.erl:750: :erl_eval.do_apply/7
app_1            |     (stdlib 5.2) erl_eval.erl:1026: :erl_eval.expr_list/7
app_1            |     (stdlib 5.2) erl_eval.erl:292: :erl_eval.expr/6
app_1            |     (stdlib 5.2) erl_eval.erl:282: :erl_eval.expr/6
app_1            |     (stdlib 5.2) erl_eval.erl:283: :erl_eval.expr/6

I'm not sure how it's not set? I'm including my docker-compose.yml with salts and private info redacted.

version: '3'
volumes:
  postgres_data: {}
  elastic_data: {}

services:
  app:
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile
    environment:
      - MIX_ENV=prod
      - PGPASSWORD=postgres
      - ANONYMOUS_NAME_SALT=*redacted*
      - HCAPTCHA_SECRET_KEY=*redacted*
      - HCAPTCHA_SITE_KEY=*redacted*
      - PASSWORD_PEPPER=*redacted*
      - TUMBLR_API_KEY=*redacted*
      - OTP_SECRET_KEY=*redacted*
      - ADVERT_FILE_ROOT=adverts
      - AVATAR_FILE_ROOT=avatars
      - BADGE_FILE_ROOT=badges
      - IMAGE_FILE_ROOT=images
      - TAG_FILE_ROOT=tags
      - AVATAR_URL_ROOT=/avatars
      - ADVERT_URL_ROOT=/spns
      - IMAGE_URL_ROOT=/img
      - BADGE_URL_ROOT=/badge-img
      - TAG_URL_ROOT=/tag-img
      - ELASTICSEARCH_URL=http://elasticsearch:9200
      - REDIS_HOST=redis
      - DATABASE_URL=ecto://postgres:postgres@postgres/philomena_dev
      - CDN_HOST=localhost
      - MAILER_ADDRESS=*redacted*
      - START_ENDPOINT=true
      - SITE_DOMAINS=*redacted*
      - S3_SCHEME=http
      - S3_HOST=files
      - S3_PORT=80
      - S3_BUCKET=philomena
      - AWS_ACCESS_KEY_ID=local-identity
      - AWS_SECRET_ACCESS_KEY=local-credential
      - SMTP_DOMAIN=*redacted*
      - SMTP_USERNAME=*redacted*
      - SMTP_PASSWORD=*redacted*
      - SMTP_PORT=587
      - SMTP_RELAY=*redacted*
    working_dir: /srv/philomena
    tty: true
    volumes:
      - .:/srv/philomena
    depends_on:
      - postgres
      - elasticsearch
      - redis

  postgres:
    image: postgres:16.2-alpine
    environment:
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    logging:
      driver: "none"

  elasticsearch:
    image: elasticsearch:7.9.3
    volumes:
      - elastic_data:/usr/share/elasticsearch/data
    logging:
      driver: "none"
    environment:
      - discovery.type=single-node
    ulimits:
      nofile:
        soft: 65536
        hard: 65536

  redis:
    image: redis:7.2.4-alpine
    logging:
      driver: "none"

  files:
    image: andrewgaul/s3proxy:sha-ec12ae0
    environment:
      - JCLOUDS_FILESYSTEM_BASEDIR=/srv/philomena/priv/s3
    volumes:
      - .:/srv/philomena

  web:
    build:
      context: .
      dockerfile: ./docker/web/Dockerfile
      args:
        - APP_DIR=/srv/philomena
        - S3_SCHEME=http
        - S3_HOST=files
        - S3_PORT=80
        - S3_BUCKET=philomena
    volumes:
      - .:/srv/philomena
    environment:
      - AWS_ACCESS_KEY_ID=local-identity
      - AWS_SECRET_ACCESS_KEY=local-credential
    logging:
      driver: "none"
    depends_on:
      - app
    ports:
      - '8080:80'

Later on, I need to migrate the existing thumbs and database to this install and not sure how to do that. Ideally, I'd like to host all posts on Wasabi... also no clue lol.

liamwhite commented 2 months ago

You didn't set the PORT= environment variable in your compose config. This environment is only used in prod mode. Dev mode uses this: https://github.com/philomena-dev/philomena/blob/master/config/dev.exs#L13

KamillaPup commented 2 months ago

Thanks! So if web runs on 8080 what should I run the app on? I currently have a reverse docker proxy forwarding 8080 to 80/443.

Also can I hire you? I'm not confident in my ability to move content over lol.

KamillaPup commented 2 months ago

I set it to port 4000 like the link says and also tried 80 and 443 and they all cause the following error:

ERROR: for d110a045c166_philomena_app_1  'ContainerConfig'

ERROR: for app  'ContainerConfig'
Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 33, in <module>
    sys.exit(load_entry_point('docker-compose==1.29.2', 'console_scripts', 'docker-compose')())
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 81, in main
    command_func()
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 203, in perform_command
    handler(command, command_options)
  File "/usr/lib/python3/dist-packages/compose/metrics/decorator.py", line 18, in wrapper
    result = fn(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 1186, in up
    to_attach = up(False)
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 1166, in up
    return self.project.up(
  File "/usr/lib/python3/dist-packages/compose/project.py", line 697, in up
    results, errors = parallel.parallel_execute(
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 108, in parallel_execute
    raise error_to_reraise
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 206, in producer
    result = func(obj)
  File "/usr/lib/python3/dist-packages/compose/project.py", line 679, in do
    return service.execute_convergence_plan(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 579, in execute_convergence_plan
    return self._execute_convergence_recreate(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 499, in _execute_convergence_recreate
    containers, errors = parallel_execute(
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 108, in parallel_execute
    raise error_to_reraise
  File "/usr/lib/python3/dist-packages/compose/parallel.py", line 206, in producer
    result = func(obj)
  File "/usr/lib/python3/dist-packages/compose/service.py", line 494, in recreate
    return self.recreate_container(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 612, in recreate_container
    new_container = self.create_container(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 330, in create_container
    container_options = self._get_container_create_options(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 921, in _get_container_create_options
    container_options, override_options = self._build_container_volume_options(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 960, in _build_container_volume_options
    binds, affinity = merge_volume_bindings(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 1548, in merge_volume_bindings
    old_volumes, old_mounts = get_container_data_volumes(
  File "/usr/lib/python3/dist-packages/compose/service.py", line 1579, in get_container_data_volumes
    container.image_config['ContainerConfig'].get('Volumes') or {}
KeyError: 'ContainerConfig'
liamwhite commented 2 months ago

Ideally you probably want to expose the web container on ports 80 and 443 and have it doing TLS termination (which is out of the scope of this project), and have nginx forward requests on the internal network to the app running on whatever other port you like by setting the PORT envvar and modifying the port nginx uses to find the app.

Moving files to object storage can be done with this mix task

Since you are using a new version of docker, you should use docker compose instead of docker-compose. I've updated the documentation to reflect this. This should fix the issue with KeyError: 'ContainerConfig'.

KamillaPup commented 2 months ago

Okay that got it mostly but I'm still missing env variables... How many more are there and what is a secret key base?

** (System.EnvError) could not fetch environment variable "SECRET_KEY_BASE" because it is not set
app-1            |     (elixir 1.16.1) lib/system.ex:721: System.fetch_env!/1
app-1            |     /srv/philomena/config/runtime.exs:135: (file)
app-1            |     (stdlib 5.2) erl_eval.erl:750: :erl_eval.do_apply/7
app-1            |     (stdlib 5.2) erl_eval.erl:1026: :erl_eval.expr_list/7
app-1            |     (stdlib 5.2) erl_eval.erl:292: :erl_eval.expr/6
app-1            |     (stdlib 5.2) erl_eval.erl:282: :erl_eval.expr/6
app-1            |     (stdlib 5.2) erl_eval.erl:283: :erl_eval.expr/6
app-1 exited with code 1
liamwhite commented 2 months ago

https://github.com/philomena-dev/philomena/blob/078957941ba2f2304531033f52bb16c13706b2f6/config/runtime.exs#L132-L136

secret_key_base is used to encrypt and sign cookies for the application endpoint.

server is used to determine whether to start the server (generally you will want to set this to true, it is separated from the application to allow for running cron jobs without starting it)

KamillaPup commented 2 months ago

Would secret_key_base be a 64 character salt string or just the hostname or something similar?

liamwhite commented 2 months ago

You can generate a new one with mix phx.gen.secret.