Code Monkey home page Code Monkey logo

docker-phoenix-example's Introduction

An example Phoenix + Docker app

CI

You could use this example app as a base for your new project or as a guide to Dockerize your existing Phoenix app.

The example app is minimal but it wires up a number of things you might use in a real world Phoenix app, but at the same time it's not loaded up with a million personal opinions.

For the Docker bits, everything included is an accumulation of Docker best practices based on building and deploying dozens of assorted Dockerized web apps since late 2014.

This app is using Phoenix 1.7.12 and Elixir 1.16.2. The screenshot doesn't get updated every time I bump the versions:

Screenshot

Table of contents

Tech stack

If you don't like some of these choices that's no problem, you can swap them out for something else on your own.

Back-end

Front-end

But what about JavaScript?!

Picking a JS library is a very app specific decision because it depends on which library you like and it also depends on if your app is going to be mostly HEEx templates with sprinkles of JS or an API back-end.

This isn't an exhaustive list but here's a few reasonable choices depending on how you're building your app:

Picking a JS library is a very app specific decision because it depends on which library you like and it also depends on if your app is going to be mostly Jinja templates with sprinkles of JS or an API back-end.

Personally I'm going to be using LiveView with StimulusJS in most newer projects.

Notable opinions and packages

Phoenix is a healthy mix of being both opinionated and unopinionated but I find in most apps I'm adding the same things over and over. Here's a few note worthy additions and changes.

  • Mix and releases:
    • When MIX_ENV is set to dev then the server will be run with mix
    • When MIX_ENV is set to prod a release will be built and used to run your server
    • All of this is automated through a multi-stage Dockerfile and build ARGs
  • Static analysis and testing:
    • credo helps create more consistent code
    • excoveralls for getting detailed test coverge reports
  • Controllers:
    • Add page controller to render a home page
    • Add up controller with 2 health check related actions
  • Config:
    • Extract a bunch of configuration settings into environment variables
    • The .env file stores all environment variables
    • Put all config settings with environment variables in config/runtime.exs (works with releases)
  • Phoenix defaults that are changed:
    • Cookies are encrypted
    • A lib/hello/release.ex module has been added to run migrations with releases
    • .formatter.exs has been configured to use 80 character line lengths
    • An empty .iex.exs file has been created so you can customize your IEx sessions however you see fit
    • CSS, JS and image links are referenced with url(~p"...") to support optionally using a CDN
  • Front-end assets:
    • Custom 502.html and maintenance.html pages
    • Generate favicons using modern best practices

Besides the Elixir / Phoenix app itself:

  • Docker support has been added which would be any files having *docker* in its name
  • GitHub Actions have been set up

Running this app

You'll need to have Docker installed. It's available on Windows, macOS and most distros of Linux. If you're new to Docker and want to learn it in detail check out the additional resources links near the bottom of this README.

You'll also need to enable Docker Compose v2 support if you're using Docker Desktop. On native Linux without Docker Desktop you can install it as a plugin to Docker. It's been generally available for a while now and is stable. This project uses specific Docker Compose v2 features that only work with Docker Compose v2 2.20.2+.

If you're using Windows, it will be expected that you're following along inside of WSL or WSL 2. That's because we're going to be running shell commands. You can always modify these commands for PowerShell if you want.

Clone this repo anywhere you want and move into the directory:

git clone https://github.com/nickjj/docker-phoenix-example hellophoenix
cd hellophoenix

# Optionally checkout a specific tag, such as: git checkout 0.8.0

Copy an example .env file because the real one is git ignored:

cp .env.example .env

Build everything:

The first time you run this it's going to take 5-10 minutes depending on your internet connection speed and computer's hardware specs. That's because it's going to download a few Docker images and build the Elixir + Yarn dependencies.

docker compose up --build

Now that everything is built and running we can treat it like any other Phoenix app.

Did you receive a depends_on "Additional property required is not allowed" error? Please update to at least Docker Compose v2.20.2+ or Docker Desktop 4.22.0+.

Did you receive an error about a port being in use? Chances are it's because something on your machine is already running on port 8000. Check out the docs in the .env file for the DOCKER_WEB_PORT_FORWARD variable to fix this.

Did you receive a permission denied error? Chances are you're running native Linux and your uid:gid aren't 1000:1000 (you can verify this by running id). Check out the docs in the .env file to customize the UID and GID variables to fix this.

Check it out in a browser:

Visit http://localhost:8000 in your favorite browser.

Linting the code base:

# You should get a report back saying there's no issues.
./run lint

We'll go over that ./run script in a bit!

Formatting the code base:

# You can check to see if any code is not formatted correctly.
./run format:check

# You can also auto-fix any malformed code (both commands call mix format).
./run format

Running the test suite:

# You should see all passing tests. Warnings are typically ok.
./run test

# You can also get test coverage which uses coveralls.
./run test:coverage
./run test:coverage:details

Stopping everything:

# Stop the containers and remove a few Docker related resources associated to this project.
docker compose down

You can start things up again with docker compose up and unlike the first time it should only take seconds.

Files of interest

I recommend checking out most files and searching the code base for TODO:, but please review the .env and run files before diving into the rest of the code and customizing it. Also, you should hold off on changing anything until we cover how to customize this example app's name with an automated script (coming up next in the docs).

.env

This file is ignored from version control so it will never be commit. There's a number of environment variables defined here that control certain options and behavior of the application. Everything is documented there.

Feel free to add new variables as needed. This is where you should put all of your secrets as well as configuration that might change depending on your environment (specific dev boxes, CI, production, etc.).

run

You can run ./run to get a list of commands and each command has documentation in the run file itself.

It's a shell script that has a number of functions defined to help you interact with this project. It's basically a Makefile except with less limitations. For example as a shell script it allows us to pass any arguments to another program.

This comes in handy to run various Docker commands because sometimes these commands can be a bit long to type. Feel free to add as many convenience functions as you want. This file's purpose is to make your experience better!

If you get tired of typing ./run you can always create a shell alias with alias run=./run in your ~/.bash_aliases or equivalent file. Then you'll be able to run run instead of ./run.

Running a script to automate renaming the project

The app is named hello right now but chances are your app will be a different name. Since the app is already created we'll need to do a find / replace on a few variants of the string "hello" and update a few Docker related resources.

And by we I mean I created a zero dependency shell script that does all of the heavy lifting for you. All you have to do is run the script below.

Run the rename-project script included in this repo:

# The script takes 2 arguments.
#
# The first one is the lower case version of your app's name, such as myapp or
# my_app depending on your preference.
#
# The second one is used for your app's module name. For example if you used
# myapp or my_app for the first argument you would want to use MyApp here.
bin/rename-project myapp MyApp

The bin/rename-project script is going to:

  • Remove any Docker resources for your current project
  • Perform a number of find / replace actions
  • Optionally initialize a new git repo for you

Afterwards you can delete this script because its only purpose is to assist in helping you change this project's name without depending on any complicated project generator tools or 3rd party dependencies.

If you're not comfy running the script or it doesn't work for whatever reasons you can check it out and perform the actions manually. It's mostly running a find / replace across files and then renaming a few directories and files.

Start and setup the project:

This won't take as long as before because Docker can re-use most things.

docker compose up --build

Sanity check to make sure everything is formatted and the tests still pass:

It's always a good idea to make sure things are in a working state before adding custom changes.

# You can run this from the same terminal as before.
./run lint
./run format
./run test

If everything passes now you can optionally git add -A && git commit -m "Initial commit" and start customizing your app. Alternatively you can wait until you develop more of your app before committing anything. It's up to you!

Tying up a few loose ends:

You'll probably want to create a fresh CHANGELOG.md file for your project. I like following the style guide at https://keepachangelog.com/ but feel free to use whichever style you prefer.

Since this project is MIT licensed you should keep my name and email address in the LICENSE file to adhere to that license's agreement, but you can also add your name and email on a new line.

If you happen to base your app off this example app or write about any of the code in this project it would be rad if you could credit this repo by linking to it. If you want to reference me directly please link to my site at https://nickjanetakis.com. You don't have to do this, but it would be very much appreciated!

Updating dependencies

Let's say you've customized your app and it's time to make a change to your mix.exs or package.json file.

Without Docker you'd normally run mix deps.get or yarn install. With Docker it's basically the same thing and since these commands are in our Dockerfile we can get away with doing a docker compose build but don't run that just yet.

In development:

You can run ./run mix:outdated or ./run yarn:outdated to get a list of outdated dependencies based on what you currently have installed. Once you've figured out what you want to update, go make those updates in your mix.exs and / or assets/package.json file.

Then to update your dependencies you can run ./run mix:install or ./run yarn:install. That'll make sure any lock files get copied from Docker's image (thanks to volumes) into your code repo and now you can commit those files to version control like usual.

You can check out the run file to see what these commands do in more detail.

In CI:

You'll want to run docker compose build since it will use any existing lock files if they exist. You can also check out the complete CI test pipeline in the run file under the ci:test function.

In production:

This is usually a non-issue since you'll be pulling down pre-built images from a Docker registry but if you decide to build your Docker images directly on your server you could run docker compose build as part of your deploy pipeline.

See a way to improve something?

If you see anything that could be improved please open an issue or start a PR. Any help is much appreciated!

Additional resources

Now that you have your app ready to go, it's time to build something cool! If you want to learn more about Docker, Phoenix and deploying a Phoenix app here's a couple of free and paid resources. There's Google too!

Learn more about Docker and Phoenix

Official documentation

Courses

Deploy to production

I'm creating an in-depth course related to deploying Dockerized web apps. If you want to get notified when it launches with a discount and potentially get free videos while the course is being developed then sign up here to get notified.

About the author

I'm a self taught developer and have been freelancing for the last ~20 years. You can read about everything I've learned along the way on my site at https://nickjanetakis.com.

There's hundreds of blog posts / videos and a couple of video courses on web development and deployment topics. I also have a podcast where I talk with folks about running web apps in production.

docker-phoenix-example's People

Contributors

j-m-hoffmann avatar lauritzsh avatar nickjj avatar pjo336 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-phoenix-example's Issues

Assets break after being stopped

This is a great template for learning how Phoenix and Docker plays together but I have trouble getting a consistent build running.

  • If I completely prune everything in Docker docker system prune -a --volumes, do a fresh git clone and build with docker-compose up --build then everything looks fine.
  • I then stop it with Ctrl-C.
  • I run docker-compose up and when I visit the page, I see the assets are not being generated, even though I can see Webpack runs in the logs. Same problem with running docker-compose up --build.
  • I have tried docker compose up (no -) too but same problem.
  • Same problem running docker-compose down and then docker-compose up.

What I see is [debug] ** (Phoenix.Router.NoRouteError) no route found for GET /css/app.css (HelloWeb.Router) and for the other resources too.

I am on macOS 11.2.3 and Docker 3.3.3 (64133). Any idea what is causing this?

❯ docker-compose up
Docker Compose is now in the Docker CLI, try `docker compose up`

Starting hellophoenix_webpack_1  ... done
Starting hellophoenix_postgres_1 ... done
Starting hellophoenix_web_1      ... done
Attaching to hellophoenix_webpack_1, hellophoenix_postgres_1, hellophoenix_web_1
postgres_1  |
postgres_1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres_1  |
yarn run v1.22.5
warning package.json: No license field
$ /node_modules/webpack/bin/webpack.js --mode=development --progress --watch
37% building 1/2 entries 9/9 dependencies 5/6 modules
webpack_1   | warn - You have enabled the JIT engine which is currently in preview.
webpack_1   | warn - Preview features are not covered by semver, may introduce breaking changes, and can change at any time.
postgres_1  | 2021-06-07 10:20:15.730 UTC [1] LOG:  starting PostgreSQL 13.3 (Debian 13.3-1.pgdg100+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
postgres_1  | 2021-06-07 10:20:15.730 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres_1  | 2021-06-07 10:20:15.730 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres_1  | 2021-06-07 10:20:15.732 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1  | 2021-06-07 10:20:15.736 UTC [28] LOG:  database system was shut down at 2021-06-07 10:17:14 UTC
postgres_1  | 2021-06-07 10:20:15.739 UTC [1] LOG:  database system is ready to accept connections
assets by status 49.2 KiB [compared for emit]
webpack_1   |   assets by path *.png 29.8 KiB 4 assets
webpack_1   |   assets by path *.html 1.87 KiB
webpack_1   |     asset 502.html 1020 bytes [compared for emit] [from: static/502.html] [copied]
webpack_1   |     asset maintenance.html 892 bytes [compared for emit] [from: static/maintenance.html] [copied]
webpack_1   |   asset favicon.ico 14.7 KiB [compared for emit] [from: static/favicon.ico] [copied]
webpack_1   |   asset safari-pinned-tab.svg 1.9 KiB [compared for emit] [from: static/safari-pinned-tab.svg] [copied]
webpack_1   |   asset manifest.json 489 bytes [compared for emit] [from: static/manifest.json] [copied]
webpack_1   |   asset browserconfig.xml 246 bytes [compared for emit] [from: static/browserconfig.xml] [copied]
webpack_1   |   asset robots.txt 185 bytes [compared for emit] [from: static/robots.txt] [copied]
webpack_1   | assets by status 224 KiB [emitted]
webpack_1   |   asset js/app.js 173 KiB [emitted] (name: main)
webpack_1   |   asset images/phoenix.png 37.8 KiB [emitted] [from: static/images/phoenix.png] [copied]
webpack_1   |   asset css/app.css 13.4 KiB [emitted] (name: main)
webpack_1   | Entrypoint main 186 KiB = css/app.css 13.4 KiB js/app.js 173 KiB
webpack_1   | runtime modules 937 bytes 4 modules
webpack_1   | cacheable modules 159 KiB
webpack_1   |   modules by path ../../node_modules/ 158 KiB
webpack_1   |     ../../node_modules/phoenix_html/priv/static/phoenix_html.js 2.21 KiB [built] [code generated]
webpack_1   |     ../../node_modules/phoenix/priv/static/phoenix.js 38.9 KiB [built] [code generated]
webpack_1   |     ../../node_modules/topbar/topbar.min.js 4 KiB [built] [code generated]
webpack_1   |     ../../node_modules/phoenix_live_view/priv/static/phoenix_live_view.js 113 KiB [built] [code generated]
webpack_1   |   modules by path ./app/ 1020 bytes
webpack_1   |     ./app/app.css 50 bytes [built] [code generated]
webpack_1   |     ./app/app.js 966 bytes [built] [code generated]
webpack_1   | css ../../node_modules/css-loader/dist/cjs.js!../../node_modules/postcss-loader/dist/cjs.js!./app/app.css 13.4 KiB [code generated]
webpack_1   | webpack 5.36.1 compiled successfully in 1613 ms
assets by status 273 KiB [cached] 14 assets
webpack_1   | Entrypoint main 186 KiB = css/app.css 13.4 KiB js/app.js 173 KiB
webpack_1   | cached modules 159 KiB (javascript) 13.4 KiB (css/mini-extract) 937 bytes (runtime) [cached] 10 modules
webpack_1   | ./app/app.css 50 bytes [built]
webpack_1   | webpack 5.36.1 compiled successfully in 137 ms
web_1       | Erlang/OTP 24 [erts-12.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
web_1       |
web_1       | [info] Running HelloWeb.Endpoint with cowboy 2.9.0 at :::8000 (http)
web_1       | [info] Access HelloWeb.Endpoint at http://localhost:8000
web_1       | Interactive Elixir (1.12.1) - press Ctrl+C to exit (type h() ENTER for help)
web_1       | iex(1)> [info] GET /
web_1       | [debug] Processing with HelloWeb.PageController.home/2
web_1       |   Parameters: %{}
web_1       |   Pipelines: [:browser]
web_1       | [info] Sent 200 in 19ms
web_1       | [info] GET /css/app.css
web_1       | [info] GET /js/app.js
web_1       | [debug] ** (Phoenix.Router.NoRouteError) no route found for GET /css/app.css (HelloWeb.Router)
web_1       |     (hello 0.1.0) lib/phoenix/router.ex:402: HelloWeb.Router.call/2
web_1       |     (hello 0.1.0) lib/hello_web/endpoint.ex:1: HelloWeb.Endpoint.plug_builder_call/2
web_1       |     (hello 0.1.0) lib/plug/debugger.ex:136: HelloWeb.Endpoint."call (overridable 3)"/2
web_1       |     (hello 0.1.0) lib/hello_web/endpoint.ex:1: HelloWeb.Endpoint.call/2
web_1       |     (phoenix 1.5.9) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
web_1       |     (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
web_1       |
web_1       | [debug] ** (Phoenix.Router.NoRouteError) no route found for GET /js/app.js (HelloWeb.Router)
web_1       |     (hello 0.1.0) lib/phoenix/router.ex:402: HelloWeb.Router.call/2
web_1       |     (hello 0.1.0) lib/hello_web/endpoint.ex:1: HelloWeb.Endpoint.plug_builder_call/2
web_1       |     (hello 0.1.0) lib/plug/debugger.ex:136: HelloWeb.Endpoint."call (overridable 3)"/2
web_1       |     (hello 0.1.0) lib/hello_web/endpoint.ex:1: HelloWeb.Endpoint.call/2
web_1       |     (phoenix 1.5.9) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
web_1       |     (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
web_1       |
web_1       | [info] GET /images/phoenix.png
web_1       | [debug] ** (Phoenix.Router.NoRouteError) no route found for GET /images/phoenix.png (HelloWeb.Router)
web_1       |     (hello 0.1.0) lib/phoenix/router.ex:402: HelloWeb.Router.call/2
web_1       |     (hello 0.1.0) lib/hello_web/endpoint.ex:1: HelloWeb.Endpoint.plug_builder_call/2
web_1       |     (hello 0.1.0) lib/plug/debugger.ex:136: HelloWeb.Endpoint."call (overridable 3)"/2
web_1       |     (hello 0.1.0) lib/hello_web/endpoint.ex:1: HelloWeb.Endpoint.call/2
web_1       |     (phoenix 1.5.9) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
web_1       |     (cowboy 2.9.0) /mix/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
web_1       |     (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
web_1       |
^CGracefully stopping... (press Ctrl+C again to force)
Stopping hellophoenix_web_1      ... done
Stopping hellophoenix_webpack_1  ... done
Stopping hellophoenix_postgres_1 ... done

Phoenix app without postgres

Hi,

Thank you for creating this awesome boilerplate. I would like to ask if I can use it without postgres. My reason of excluding postgres is I the data I'm storing are all ephemeral.

The app I'm building contains frontend (react) and backend (phoenix).
Do I only need to modify the docker-compose.yml file?

x-app: &default-app
  build:
    context: "."
    target: "${MIX_ENV:-prod}"
    args:
      - "MIX_ENV=${MIX_ENV:-prod}"
      - "NODE_ENV=${NODE_ENV:-production}"
  env_file:
    - ".env"
  restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
  stop_grace_period: "3s"
  tty: true
  volumes:
    - "${DOCKER_WEB_VOLUME:-./priv/static:/app/priv/static}"

services:
  web:
    <<: *default-app
    deploy:
      resources:
        limits:
          cpus: "${DOCKER_WEB_CPUS:-0}"
          memory: "${DOCKER_WEB_MEMORY:-0}"
    healthcheck:
      test: "${DOCKER_WEB_HEALTHCHECK_TEST:-curl localhost:8000/up}"
      interval: "60s"
      timeout: "3s"
      start_period: "5s"
      retries: 3
    ports:
      - "${DOCKER_WEB_PORT_FORWARD:-127.0.0.1:8000}:8000"

Play nice with VSCode

Thanks for a great resource!

Do you have any tips on getting this setup to play nice with VSCode and the elixir-lsp?

an exception was raised:
    ** (Mix.Error) Can't continue due to errors on dependencies
        (mix 1.11.3) lib/mix.ex:436: Mix.raise/1
        (mix 1.11.3) lib/mix/tasks/deps.loadpaths.ex:28: Mix.Tasks.Deps.Loadpaths.run/1
        (mix 1.11.3) lib/mix/task.ex:394: Mix.Task.run_task/3
        (mix 1.11.3) lib/mix/tasks/loadpaths.ex:37: Mix.Tasks.Loadpaths.run/1
        (mix 1.11.3) lib/mix/task.ex:394: Mix.Task.run_task/3
        (mix 1.11.3) lib/mix/tasks/compile.ex:113: Mix.Tasks.Compile.run/1
        (mix 1.11.3) lib/mix/task.ex:394: Mix.Task.run_task/3
        (language_server 0.7.0) lib/language_server/build.ex:199: ElixirLS.LanguageServer.Build.compile/0ElixirLS

I am assuming that the elixir-lsp in VSCode is looking at the build_path and deps_path in mix.exs and not finding anything.

Thanks in advance.

Webpack failing in initial docker-compose

Issue

The initial docker-compose up --build is failing to run webpack. The error log from Docker Desktop for hellophoenix_webpack_1 is below.

yarn run v1.22.5

error Couldn't find a package.json file in "/app/assets"

info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Steps to reproduce

Do the first 3 steps of "Running this app".

  1. Clone repo
  2. Duplicate the .env and docker-compose.override.yml files (and remove .example affix)
  3. Run docker-compose up --build

System details

M1, macOS v11.4
Docker Desktop 3.5.2 (66501)
Node v14.17.0

Having trouble creating deployment pipeline in EKS using your Dockerfile

I am trying to create Deployment pipeline in EKS that will deploy your application setup in Kubernetes. but i am stuck at running the container from Docker i am getting the following error "cp : cannot create directory '/app/priv/static': no such file or directory "
image (1)
also when i try using docker compose build command and then run the image to make containers i am getting error "mkdir : cannot create directory '../priv/static/css' : permission denied " and "mkdir : cannot create directory '../priv/static/js' : permission denied "
image (2)

build pipeline in TeamCity fails

I came across your well crafted solution for docker-phoenix and I'm trying to get it work in TeamCity to achieve a documented build pipeline,
Connected a TeamCity-Project to a repo in gogs (git like selfhosted repo)
and set up a TeamCity Build Step: Command Line with command docker-compose up --build
[docker compose up --build (without the minus) didn't work]

Due to my yet limited experience using Docker and Phoenix I'm asking you if you could possibly point me into the right direction why this build fails.

I did the following steps according to the README:

git clone https://github.com/nickjj/docker-phoenix-example hellophoenix
cd hellophoenix
cp .env.example .env

[committed the .env to the testrepo and changed .gitignore and .dockerignore to not ignore .env]
docker-compose up --build # in teamcity shell command

The build fails with the following log:

Step 1/1: Command Line
23:16:40   Starting: /opt/buildagent/temp/agentTmp/custom_script3179222894012803463
23:16:40   in directory: /opt/buildagent/work/34b3e6d02e4125c3
23:16:41   Building web
23:16:41   #2 [internal] load build definition from Dockerfile
23:16:41   #2 transferring dockerfile: 2.99kB done
23:16:41   #2 DONE 0.1s
23:16:41   
23:16:41   #1 [internal] load .dockerignore
23:16:41   #1 transferring context: 151B done
23:16:41   #1 DONE 0.1s
23:16:41   
23:16:41   #4 [internal] load metadata for docker.io/library/elixir:1.15.4-slim
23:16:44   #4 DONE 2.5s
23:16:44   
23:16:44   #3 [internal] load metadata for docker.io/library/node:18.15.0-bullseye-slim
23:16:44   #3 DONE 2.5s
23:16:44   
23:16:44   #13 [dev  1/11] FROM docker.io/library/elixir:1.15.4-slim@sha256:430b719241b01d3326ab9ff24b9799c6bcc22e93206ae54e626403f17227d33b
23:16:44   #13 DONE 0.0s
23:16:44   
23:16:44   #14 [assets 1/7] FROM docker.io/library/node:18.15.0-bullseye-slim@sha256:639e94182196dccc83a45224a10d2a3cb4139c0e3d05194b64d6587ce2919e8c
23:16:44   #14 DONE 0.0s
23:16:44   
23:16:44   #12 [internal] load build context
23:16:44   #12 transferring context: 373.48kB 0.0s done
23:16:44   #12 DONE 0.1s
23:16:44   
23:16:44   #6 [assets 2/7] WORKDIR /app/assets
23:16:44   #6 CACHED
23:16:44   
23:16:44   #20 [dev  4/11] RUN mix local.hex --force && mix local.rebar --force
23:16:44   #20 CACHED
23:16:44   
23:16:44   #5 [assets 3/7] RUN apt-get update   && apt-get install -y --no-install-recommends build-essential   && rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man   && apt-get clean   && groupmod -g "1000" node && usermod -u "1000" -g "1000" node   && mkdir -p /node_modules && chown node:node -R /node_modules /app
23:16:44   #5 CACHED
23:16:44   
23:16:44   #16 [assets 4/7] COPY --chown=node:node assets/package.json assets/*yarn* ./
23:16:44   #16 CACHED
23:16:44   
23:16:44   #11 [assets 7/7] RUN if [ "development" != "development" ]; then   ../run yarn:build:js && ../run yarn:build:css; else mkdir -p /app/priv/static; fi
23:16:44   #11 CACHED
23:16:44   
23:16:44   #18 [dev  3/11] RUN apt-get update   && apt-get install -y --no-install-recommends build-essential curl inotify-tools   && rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man   && apt-get clean   && groupadd -g "1000" elixir   && useradd --create-home --no-log-init -u "1000" -g "1000" elixir   && mkdir -p /mix && chown elixir:elixir -R /mix /app
23:16:44   #18 CACHED
23:16:44   
23:16:44   #7 [dev  6/11] RUN if [ "dev" = "dev" ]; then   mix deps.get; else mix deps.get --only "dev"; fi
23:16:44   #7 CACHED
23:16:44   
23:16:44   #10 [assets 5/7] RUN yarn install && yarn cache clean
23:16:44   #10 CACHED
23:16:44   
23:16:44   #8 [dev  7/11] COPY --chown=elixir:elixir config/config.exs config/dev.exs config/
23:16:44   #8 CACHED
23:16:44   
23:16:44   #15 [dev  9/11] COPY --chown=elixir:elixir --from=assets /app/priv/static /public
23:16:44   #15 CACHED
23:16:44   
23:16:44   #9 [dev 10/11] COPY --chown=elixir:elixir . .
23:16:44   #9 CACHED
23:16:44   
23:16:44   #17 [assets 6/7] COPY --chown=node:node . ..
23:16:44   #17 CACHED
23:16:44   
23:16:44   #21 [dev  2/11] WORKDIR /app
23:16:44   #21 CACHED
23:16:44   
23:16:44   #19 [dev  5/11] COPY --chown=elixir:elixir mix.* ./
23:16:44   #19 CACHED
23:16:44   
23:16:44   #22 [dev  8/11] RUN mix deps.compile
23:16:44   #22 CACHED
23:16:44   
23:16:44   #23 [dev 11/11] RUN if [ "dev" != "dev" ]; then   ln -s /public /app/priv/static     && mix phx.digest && mix release && rm -rf /app/priv/static; fi
23:16:44   #23 CACHED
23:16:44   
23:16:44   #24 exporting to image
23:16:44   #24 exporting layers done
23:16:44   #24 writing image sha256:be40c12202c0f327dd77937e94add4995104c209222c6677afbe2dd6ce30f5d0 0.0s done
23:16:44   #24 naming to docker.io/library/hellophoenix_web 0.0s done
23:16:44   #24 DONE 0.0s
23:16:44   Successfully built be40c12202c0f327dd77937e94add4995104c209222c6677afbe2dd6ce30f5d0
23:16:44   Building js
23:16:44   #2 [internal] load build definition from Dockerfile
23:16:44   #2 transferring dockerfile: 2.99kB done
23:16:44   #2 DONE 0.1s
23:16:44   
23:16:44   #1 [internal] load .dockerignore
23:16:44   #1 transferring context: 151B done
23:16:44   #1 DONE 0.1s
23:16:44   
23:16:44   #3 [internal] load metadata for docker.io/library/node:18.15.0-bullseye-slim
23:16:45   #3 DONE 0.2s
23:16:45   
23:16:45   #11 [assets 1/7] FROM docker.io/library/node:18.15.0-bullseye-slim@sha256:639e94182196dccc83a45224a10d2a3cb4139c0e3d05194b64d6587ce2919e8c
23:16:45   #11 DONE 0.0s
23:16:45   
23:16:45   #8 [internal] load build context
23:16:45   #8 transferring context: 4.54kB 0.0s done
23:16:45   #8 DONE 0.0s
23:16:45   
23:16:45   #9 [assets 3/7] RUN apt-get update   && apt-get install -y --no-install-recommends build-essential   && rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man   && apt-get clean   && groupmod -g "1000" node && usermod -u "1000" -g "1000" node   && mkdir -p /node_modules && chown node:node -R /node_modules /app
23:16:45   #9 CACHED
23:16:45   
23:16:45   #6 [assets 5/7] RUN yarn install && yarn cache clean
23:16:45   #6 CACHED
23:16:45   
23:16:45   #10 [assets 2/7] WORKDIR /app/assets
23:16:45   #10 CACHED
23:16:45   
23:16:45   #5 [assets 6/7] COPY --chown=node:node . ..
23:16:45   #5 CACHED
23:16:45   
23:16:45   #7 [assets 4/7] COPY --chown=node:node assets/package.json assets/*yarn* ./
23:16:45   #7 CACHED
23:16:45   
23:16:45   #4 [assets 7/7] RUN if [ "development" != "development" ]; then   ../run yarn:build:js && ../run yarn:build:css; else mkdir -p /app/priv/static; fi
23:16:45   #4 CACHED
23:16:45   
23:16:45   #12 exporting to image
23:16:45   #12 exporting layers done
23:16:45   #12 writing image sha256:7d72edda23eda94e9e4cdcba3be001a0c2107e9836562c8246aacb75da4b4d7f 0.0s done
23:16:45   #12 naming to docker.io/library/hellophoenix_js 0.0s done
23:16:45   #12 DONE 0.0s
23:16:45   Successfully built 7d72edda23eda94e9e4cdcba3be001a0c2107e9836562c8246aacb75da4b4d7f
23:16:45   Building css
23:16:45   #1 [internal] load .dockerignore
23:16:45   #1 transferring context: 151B done
23:16:45   #1 DONE 0.0s
23:16:45   
23:16:45   #2 [internal] load build definition from Dockerfile
23:16:45   #2 transferring dockerfile: 2.99kB done
23:16:45   #2 DONE 0.0s
23:16:45   
23:16:45   #3 [internal] load metadata for docker.io/library/node:18.15.0-bullseye-slim
23:16:45   #3 DONE 0.2s
23:16:45   
23:16:45   #6 [assets 1/7] FROM docker.io/library/node:18.15.0-bullseye-slim@sha256:639e94182196dccc83a45224a10d2a3cb4139c0e3d05194b64d6587ce2919e8c
23:16:45   #6 DONE 0.0s
23:16:45   
23:16:45   #11 [internal] load build context
23:16:45   #11 transferring context: 4.54kB 0.0s done
23:16:45   #11 DONE 0.0s
23:16:45   
23:16:45   #5 [assets 2/7] WORKDIR /app/assets
23:16:45   #5 CACHED
23:16:45   
23:16:45   #10 [assets 4/7] COPY --chown=node:node assets/package.json assets/*yarn* ./
23:16:45   #10 CACHED
23:16:45   
23:16:45   #4 [assets 3/7] RUN apt-get update   && apt-get install -y --no-install-recommends build-essential   && rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man   && apt-get clean   && groupmod -g "1000" node && usermod -u "1000" -g "1000" node   && mkdir -p /node_modules && chown node:node -R /node_modules /app
23:16:45   #4 CACHED
23:16:45   
23:16:45   #9 [assets 5/7] RUN yarn install && yarn cache clean
23:16:45   #9 CACHED
23:16:45   
23:16:45   #8 [assets 6/7] COPY --chown=node:node . ..
23:16:45   #8 CACHED
23:16:45   
23:16:45   #7 [assets 7/7] RUN if [ "development" != "development" ]; then   ../run yarn:build:js && ../run yarn:build:css; else mkdir -p /app/priv/static; fi
23:16:45   #7 CACHED
23:16:45   
23:16:45   #12 exporting to image
23:16:45   #12 exporting layers done
23:16:45   #12 writing image sha256:7d72edda23eda94e9e4cdcba3be001a0c2107e9836562c8246aacb75da4b4d7f 0.0s done
23:16:45   #12 naming to docker.io/library/hellophoenix_css 0.0s done
23:16:45   #12 DONE 0.0s
23:16:45   Successfully built 7d72edda23eda94e9e4cdcba3be001a0c2107e9836562c8246aacb75da4b4d7f
23:16:45   Creating hellophoenix_postgres_1 ...
23:16:45   Creating hellophoenix_css_1      ...
23:16:45   Creating hellophoenix_js_1       ...
23:16:48   Creating hellophoenix_js_1       ... done
23:16:48   Creating hellophoenix_postgres_1 ... done
23:16:48   Creating hellophoenix_web_1      ...
23:16:49   Creating hellophoenix_css_1      ... done
23:16:50   Creating hellophoenix_web_1      ... error
23:16:50   
23:16:50   ERROR: for hellophoenix_web_1  Cannot start service web: failed to create task for container: 
failed to create shim task: OCI runtime create failed: 
runc create failed: unable to start container process: 
exec: "/app/bin/docker-entrypoint-web": stat /app/bin/docker-entrypoint-web: 
no such file or directory: unknown
23:16:50   
23:16:50   ERROR: for web  Cannot start service web: failed to create task for container: 
                                  failed to create shim task: OCI runtime create failed: 
                                   runc create failed: unable to start container process: 
                                  exec: "/app/bin/docker-entrypoint-web": stat /app/bin/docker-entrypoint-web: 
                                 no such file or directory: unknown
23:16:50   Encountered errors while bringing up the project.
23:16:51   Process exited with code 1
23:16:51   Process exited with code 1 (Step: Command Line)
23:16:51   Step Command Line failed

cp: cannot create directory '/app/priv/static/'

I use azure devops to deploy an image to azure app service, when looked into `default container log' of azure app service, I got the following error:

2022-11-11T08:58:59.578466425Z cp: cannot create directory '/app/priv/static/': No such file or directory

  • compose file

    # cloud service. Everything "just works", even optional depends_on!
    # export COMPOSE_PROFILES=postgres,web
    # export COMPOSE_PROFILES=postgres,assets,web
    export COMPOSE_PROFILES=web
    
  • I changed the environment as

    export MIX_ENV=prod
    export NODE_ENV=production
    
  • comment out

    # export DOCKER_WEB_VOLUME=./priv/static:/app/priv/static
    # export DOCKER_WEB_VOLUME=.:/app
    
  • changed the docker web port forward

    export DOCKER_WEB_PORT_FORWARD=127.0.0.1:8000
    # export DOCKER_WEB_PORT_FORWARD=8000
    

Prod releases do not work

Hi,

First off thanks for the awesome template. I am running into an issue with releasing to prod.

From a fresh clone and copying over the .env, and .override files,

change MIX_ENV and NODE_ENV in .env to prod and production respectively, then run docker compose up --build

I see this error:

web_1       | /app/bin/docker-entrypoint-web: line 9: /app/bin/hello: No such file or directory

Currently spinning my wheels trying to figure this out.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.