Closed burfo closed 7 years ago
I can help with this - just for local dev purposes, right? Setting up a VM environment to build this - hope to get a chunk of work done on it tomorrow. Feel free to assign this issue to me if possible.
Not just for local dev purposes. They plan to use Docker to deploy the live site as well.
Of course you can use
npm install
ng build
To build the app. Then either ng serve
to run the built-in angular web server or take the /dist/
folder (created by ng build) and use with another web server. (Not sure if one option is better than the other.)
I'm not sure what the staff want to do, but depending on what their webservers are like the dev version can just be used with a reverse proxy to serve up the live site too. I'm going to build a container and we can adjust accordingly. We can always maintain a prod image if necessary.
@burfo serving static files is going to be a lot faster, and should make the container a lot small (just nginx no node runtime)
It would be great if we could setup the asset delivery for nginx instead of node runtime. Node / npm was a nightmare to deploy to a docker image and ng serve isn't staying up. I can try just adding nginx but not sure if ng serve does anything angular / node specific that needs to be configured.
@gp2015 #16
I added an nginx pull request, with a few other additions, that i probably should have made their own pull requests.
@gp2015 so all ng serve does is setup a watcher on your file system via webpack to compile your TS into js along with all your assets (images/templates/styles). It has a bunch of debug information (ie source maps) and very limited optimization of the output code (so you get slower loads).
ng build compiles your assets into optimized bundles of code and throws it in the dist folder which can be statically served (only needs a web browser to run).
Fixed by #16
I was actually looking at making this a docker image for build and deployment but this gets the job done for dev.
What's missing for build/deploy?
Dockerfile
FROM nginx
COPY ./nginx/conf.d /etc/nginx/conf.d
COPY ./herald/dist /usr/share/nginx/html
EXPOSE 80
package.json
"docker:build:nginx": "docker build -t uthgard-nginx $(pwd)/.."
I meant as an image:
FROM repo/uthgard-herald
You solution is elegant and probably better for this kind of project that doesn't need CI. Nice work!
Well you wouldn't use this as a base image, so FROM wouldn't really be useful within a Dockerfile, but you could definitely tag it to uthgard/herald and push it to docker hub.
ie
https://hub.docker.com/r/jearle/uthgard-nginx/
now you can just run:
docker run -p 8787:80 -d jearle/uthgard-nginx
No need to push any images to the docker hub; I'm fine building the images myself on the server from git (I'd actually prefer that).
I'd prefer reducing the entire build & run process to a simple Makefile similar to this:
INSTANCE=uth-go-mainpage
IMAGE=uth-mainpage
.PHONY: build
build:
docker build -t $(IMAGE) .
.PHONY: runlocal
runlocal: build stop
docker run -it --name $(INSTANCE) $(IMAGE)
.PHONY: run
run: build stop
docker run --restart on-failure -d --name $(INSTANCE) $(IMAGE)
.PHONY: stop
stop:
docker stop $(INSTANCE) || /bin/true
docker rm $(INSTANCE) || /bin/true
Dockerfile:
FROM golang:1.6-alpine
COPY . /go
RUN go install -v main
CMD main
I.e. create a Dockerfile that just copies the current directory content into the docker image, and spins up some lightweight http server to serve the frontend
What does a hand rolled static go server have over nginx?
I'm not saying to use a go-server (that was just an example Makefile + Dockerimage), but I'm saying to create a makefile that can be build and run docker images from the git repo directly (without the need to go through Dockerhub)
You could switch over from GitHub to GitLab.
GitLab has built-in Container Registry for Continuous Integration (CI), so you don't need dockerhub anymore.
If you cannot setup a GitLab server own your own, I can offer you to use mine (https://git.simon-mueller.de)...
Given that we have a single-instance webserver, I'd just like to avoid having any kind of image registry all together
@thekroko Yeah, I agree... I wrote something akin to that using npm run if you checkout the package json.
If we wanted to be really uncoupled we should also add a node container that builds the project, leaving the only dependency on the target server docker.
So, here's what we can do right now...
Get the code and build it:
git clone https://github.com/thekroko/uthgard-herald
cd uthgard-herald/herald
npm install
npm run build
Fire up a Docker container (based on the nginx image) that serves the freshly built dist
directory:
npm run docker:run:nginx
Build a new Docker image from it:
npm run docker:build:nginx
@thekroko is this sufficient or what should we change?
Would be great if the npm commands are run inside the docker container. I want to avoid installing anything on the server directly besides docker.
I'd probably use this as a base: https://hub.docker.com/_/node/
Is there a specific reason you want your own image to do the building?
Should be easier to just use the Node image itself. If the command to build it gets a bit lengthy, just put it in a build.sh
script in the repo or something.
Took a quick shot at it and cooked up the following, it breaks on the ng build
, but I'm also using the wrong version of angular-cli, aught to fix that later.
docker run -it --rm --name uthgard-herald-build -v $(pwd)/herald:/usr/src/app -w /usr/src/app node:7.4 sh -c 'npm install && npm install -g angular-cli && ng build'
I'd prefer to have the npm install in the image itself so it doesn't have to be done on every server restart, but please base the image upon one of the node alpine images.
You should be using the "RUN" command in the dockerbuild for installing all dependencies. Dockerbuild should look something along those lines:
FROM node:alpine RUN apk update && apk upgrade RUN apk add npm
WORKDIR /uthgard ADD . /uthgard ENTRYPOINT [ "node", "server.js" ]
Look here for a rough overview: https://www.digitalocean.com/community/tutorials/docker-explained-using-dockerfiles-to-automate-building-of-images
@thekroko you should group your run scripts together ie:
RUN apk update && apk upgrade && apk add npm
Every RUN creates a new image snapshot, increasing the disk usage of your docker images. Unless you have a reason to create the intermediary update/upgrade snapshot.
I forgot to do a quick write-up after hacking around during a lunch break some time ago where I, despite my utter lack of knowledge of Angular, got it to build inside Docker. I had to bump dependencies to fix some problems, but that's since been done on master here as well. Besides that, I was also unable to fetch a certain dependency, but having python/make/g++ in the container allows it to build it itself instead.
After a successful build, I spun up a container that runs ng serve
, exposing :4200. This results in a happy message that the development server is up and running, but when I actually tried to access it, it came up blank. It didn't complain about anything in the logs, not that I could find, at least. (I may be out of my element here. :sweat_smile:)
How do you actually want to run this?
FROM node:7.4-alpine
# Copy in the herald
COPY ./herald /usr/src/app
# Can't pull in some dependency, npm resorts to building it itself, but needs Py/Make/g++
# https://github.com/AngularClass/angular2-webpack-starter/issues/626
RUN apk update && apk upgrade && apk add python make g++
# Build the herald
WORKDIR /usr/src/app
RUN npm install -q && npm build
# Run the herald
CMD npm start
I thought this was already working? I can take a look later if it isn't.
i believe the CMD should be npm build
, the container shouldn't be used to serve the web app, rather just to build the static assets and served from a fast server (nginx).
That's how I saw it originally, but I had a talk with @thekroko on the IRC and I figured he wanted an image that both builds and serves the website, something about sequential execution of containers being difficult. It's entirely possible that I misunderstood him, though, as I was focus pulling on my necro at the same time.
Well ideally you'd have a build pipeline that would look something like:
git push
(kicks off the following commands on a CI server)
docker build -t uthgard-herald .
docker run -v $(pwd)/dist:/angular/app/dist uthgard-herald
cd ./nginx
docker build -t uthgard-herald-nginx .
(the Dockerfile would COPY
from ../dist or you could supply an env var to build)
Now you would have an nginx container with the static built assets, which can be shared and deployed wherever.
I implemented this somewhat today (e4b90d8b19e53bc462b90aa7212ee159fc41c982). The Docker image now builds the "app" on image build time. This bloats up the image a bit (thats a downside compared to having a simple docker "container" containing all the assets and running it off a standard webserver) but these days that shouldn't really matter.
I'm happy to invest a bit more time to fix potential issues/implement stuff if needed.
Deployable now, looks good. Looks like AngularJS is running in debug instead of production mode though in the game.
Yeah, it's in dev mode rather than prd mode due to how the build script is configured. We'd need to change it to do ng build -prod
(instead of ng build
), or create a 2nd script if we want build to stay in dev mode.
I kinda believe that when you build the docker image (to deploy it somewhere) you always want a production build. If you agree just merge https://github.com/thekroko/uthgard-herald/pull/25 :-)
Make sure everything can be deployed via docker ("docker run .." should produce a local webserver listening on some random port that displays that page).