1
0
mirror of https://github.com/phusion/baseimage-docker.git synced 2026-03-26 04:18:46 +00:00

Compare commits

..

179 Commits

Author SHA1 Message Date
Hongli Lai (Phusion)
1812fbf093 Note 0.9.16 release date 2015-01-20 11:40:15 +01:00
Hongli Lai (Phusion)
65e212f235 When uploading new release, run 'docker tag' with '-f' 2015-01-20 11:39:50 +01:00
Hongli Lai (Phusion)
bc40f72c84 Update documentation 2015-01-20 11:14:53 +01:00
Hongli Lai (Phusion)
4a41a00697 Merge branch 'reduce-dockerfile-steps' of git://github.com/kanzure/baseimage-docker into kanzure-reduce-dockerfile-steps 2015-01-20 11:04:49 +01:00
Hongli Lai (Phusion)
d85b76dfd9 Update URLs in the README, add translation note 2015-01-20 10:52:48 +01:00
Hongli Lai (Phusion)
a0e2a13b0a Merge branch 'master' into next 2015-01-20 10:50:13 +01:00
Hongli Lai
c1c5e70dd5 Merge pull request #156 from zhaopengme/master
Add Chinese translation of the README
2015-01-20 10:49:23 +01:00
Hongli Lai (Phusion)
6e55e3d515 Redirect syslog to 'docker logs' and fix cron
Closes GH-123. Closes GH-115.
2015-01-19 18:07:15 +01:00
Hongli Lai (Phusion)
0b2de757f5 Fixed some locale issues
Closes GH-178. Thanks to David J. M. Karlsen.
2015-01-19 17:32:05 +01:00
Hongli Lai (Phusion)
9b08ea9cd4 Logrotate now reloads syslog-ng properly
Closes GH-167.
2015-01-19 16:55:09 +01:00
Hongli Lai (Phusion)
2640bc7b03 Make 'docker exec' the default and disable SSH by default
Closes GH-168.
2015-01-19 16:40:17 +01:00
Hongli Lai (Phusion)
a0a48d8fd3 Merge branch 'remove_etc_hosts_workaround' into next 2015-01-19 16:01:53 +01:00
Hongli Lai (Phusion)
d9023071e4 Bump version to 0.9.16 2015-01-19 16:00:13 +01:00
Hongli Lai (Phusion)
8f2877c806 Do not set APT's force-unsafe-io option because the latest ubuntu image already does that 2015-01-17 14:32:41 +01:00
Hongli Lai (Phusion)
19c2df66b3 Remove workaround for Docker bug #2267 now that Docker has fixed this
Closes GH-155.
2015-01-16 16:50:39 +01:00
Hongli Lai (Phusion)
ea56d35011 Update README 2015-01-16 14:29:19 +01:00
Hongli Lai (Phusion)
e77d34aedf Clarify our stand point on running multiple processes and fat containers 2015-01-16 14:27:24 +01:00
Bryan Bishop
81af926a78 remove Dockerfile step for mkdir /build
The ADD command will create /build automatically, so the RUN mkdir step
can be safely removed. Also, this has the benefit of reducing the number
of steps in the Dockerfile which is helpful for not as quickly hitting
the 127 layer limit.
2014-11-24 10:56:23 -06:00
mikey.zhaopeng
c4385735af add the Chinese translation 2014-10-24 08:53:28 +08:00
Hongli Lai (Phusion)
e54a443cca Fix setuid bit on /usr/bin/sudo, bump version to 0.9.15.
Closes GH-148.
2014-10-03 12:37:00 +02:00
Hongli Lai (Phusion)
4db83076bd Bump version to 0.9.14 2014-10-01 11:00:21 +02:00
Hongli Lai (Phusion)
fc74a85e5d Update Changelog 2014-10-01 11:00:04 +02:00
Hongli Lai
04173bb162 Merge pull request #142 from andreamtp/patch-1
Update README.md
2014-09-20 14:47:39 +02:00
andreamtp
715a6eebde Update README.md
updated link to the Changelog of the master branch instead of nsenter
2014-09-20 14:42:09 +02:00
Hongli Lai (Phusion)
2d2c13b519 Note 0.9.13 release date 2014-08-22 18:10:34 +02:00
Hongli Lai (Phusion)
2135d2192e Update Changelog 2014-08-22 18:03:35 +02:00
Hongli Lai
ae652517e8 Merge pull request #129 from kingdonb/master
syslog-ng.ctl left around after commit
2014-08-22 16:49:00 +02:00
Kingdon Barrett
212e080b58 syslog-ng.ctl left around after commit
For phusion/baseimage#128
2014-08-07 15:15:07 -04:00
Hongli Lai
97e256cc61 Merge pull request #124 from arkadijs/master
Correct typo
2014-08-04 15:06:34 +02:00
Arkadi Shishlov
f0514872ea Correct typo 2014-08-04 14:51:28 +03:00
Hongli Lai (Phusion)
0de8640bac Change the docker_env group ID from 1000 to 8377. 2014-07-25 14:49:06 +02:00
Hongli Lai (Phusion)
5e5794c528 Bump version to 0.9.13 2014-07-25 14:38:01 +02:00
Hongli Lai (Phusion)
9be2ee2916 Fix my_init not properly exiting with a non-zero exit status when Ctrl-C is pressed. 2014-07-25 14:37:03 +02:00
Hongli Lai (Phusion)
a0d4877272 When releasing, throw an error if the release date isn't noted in Changelog.md 2014-07-17 10:16:23 +02:00
Hongli Lai (Phusion)
a06da035d0 Note 0.9.12 release date 2014-07-17 10:14:01 +02:00
Hongli Lai (Phusion)
d55fa363bf Update changelog 2014-07-16 21:07:59 +02:00
Hongli Lai (Phusion)
eb189e7864 Officially support nsenter 2014-07-16 21:07:49 +02:00
Hongli Lai (Phusion)
7fd667bc1f Update Changelog 2014-07-13 23:59:40 +02:00
Hongli Lai
5106ffd4b1 Merge pull request #105 from bubenkoff/patch-1
Allow X11 forwarding and remove invalid xauth location
2014-07-13 23:58:19 +02:00
Hongli Lai (Phusion)
3526928ad9 Update README 2014-07-13 23:09:52 +02:00
Hongli Lai (Phusion)
9cf192ca02 Fix mistake in changelog 2014-07-13 23:06:05 +02:00
Hongli Lai (Phusion)
25e8b1c535 Make docker-bash work on a regular sh shell instead of bash.
Closes GH-103.
2014-07-13 12:50:16 +02:00
Hongli Lai (Phusion)
2fa47a225b Update Readme 2014-07-13 01:31:14 +02:00
Hongli Lai (Phusion)
b9d75d899d Fix documentation order 2014-07-13 01:12:04 +02:00
Hongli Lai (Phusion)
1f38e2226e Added a workaround for Docker's inability to modify /etc/hosts in the container.
See Docker bug 2267: https://github.com/dotcloud/docker/issues/2267
2014-07-13 00:49:05 +02:00
Hongli Lai (Phusion)
291b9aae02 Bump version to 0.9.12 2014-07-13 00:49:05 +02:00
Hongli Lai (Phusion)
75902437c9 Move scripts into bin directory 2014-07-13 00:49:04 +02:00
Hongli Lai
73d900dece Merge pull request #106 from mephi42/master
my_init: use stderr for all logs

Useful when you want to run tar within the container and pipe the archive to host.
2014-07-03 11:36:04 +02:00
mephi42
669435158f my_init: use stderr for all logs
Useful when you want to run tar within the container
and pipe the archive to host.
2014-07-02 19:12:42 -04:00
Anatoly Bubenkov
a32cbb7808 remove explicit xauth location
Change allows to connect by ssh using X11 forwarding from linux host, otherwise you get
debug1: Remote: No xauth program; cannot forward with spoofing.
2014-07-02 16:04:37 +02:00
Hongli Lai
070245feb8 Merge pull request #97 from dgoujard/master
Update doc with more informations in ssh section
2014-06-24 17:07:46 +02:00
Hongli Lai (Phusion)
f58282d4d3 Note release date 2014-06-24 16:40:22 +02:00
Hongli Lai (Phusion)
e6258b37b5 Give credit to Brant Fitzsimmons 2014-06-24 16:39:56 +02:00
Hongli Lai
71ce2a6d9d Merge pull request #98 from bfitzsimmons/patch-1
Fixed typo.
2014-06-23 19:09:11 +02:00
Brant Fitzsimmons
08d5b93095 Fixed typo. 2014-06-23 12:56:26 -04:00
Damien Goujard
7d2bdfe67e Update doc with more informations in ssh section 2014-06-22 09:39:59 +02:00
Hongli Lai
d0e63da07b Merge pull request #86 from imanel/patch-2
Don't write HOME env variable
2014-06-20 13:45:36 +02:00
Bernard Potocki
2beb0e253e Change break to continue 2014-06-20 12:38:17 +02:00
Hongli Lai (Phusion)
0302713554 Update documentation 2014-06-20 11:33:10 +02:00
Hongli Lai
7ac6795aa5 Merge pull request #84 from imanel/patch-1
Preserve ENV variables for SSH client
2014-06-20 11:28:27 +02:00
Hongli Lai
feab2fce75 Merge pull request #94 from pda/stderr-not-proctitle
my_init: runsvdir no longer redirects stderr to proctitle.
2014-06-20 11:26:39 +02:00
Paul Annesley
3019bbf09b my_init: runsvdir no longer redirects stderr to proctitle.
As described at http://smarden.org/runit/runsvdir.8.html passing a log
option to runsvdir causes stderr to be redirected to the proctitle.

That prevents stderr from reaching docker logs, which is a big problem.
2014-06-18 09:38:52 -07:00
Bernard Potocki
18a7fe26ec Add USER, GROUP, UID, GID and SHELL to restricted env variables 2014-06-18 17:29:02 +02:00
Bernard Potocki
b9d788611a Update readme 2014-06-18 17:13:44 +02:00
Bernard Potocki
1357e9399e Add docker_env group and make container_environment scripts group-readable 2014-06-18 17:10:35 +02:00
Hongli Lai (Phusion)
ba1e1ffbf5 Fix an anchor in the README 2014-06-17 17:41:20 +02:00
Hongli Lai (Phusion)
0b468fb61b Introduce the docker-bash tool.
This is a shortcut tool for logging into a container using SSH. Usage: `docker-bash <CONTAINER_ID>`.
2014-06-17 17:40:34 +02:00
Hongli Lai
9db4f43b74 Merge pull request #93 from qerub/ipaddress
Use Go template instead of grep to extract container IP address
2014-06-17 14:40:05 +02:00
Hongli Lai (Phusion)
5806f51ea3 Fixed various process waiting issues in my_init.
Closes GH-27. Closes GH-82. Closes GH-83.
Thanks to André Luiz dos Santos and Paul Annesley.
2014-06-17 14:35:05 +02:00
Hongli Lai (Phusion)
c431f2d151 Update Changelog 2014-06-17 13:27:03 +02:00
Hongli Lai
76100b639a Merge pull request #88 from jeckhart/fix-syslogng-runit-run
Missing target of chown in syslog-ng runit run file
2014-06-17 13:15:20 +02:00
Hongli Lai
ecf6e6b226 Merge pull request #90 from yebyen/patch-1
needed for insecure key usage
2014-06-17 13:03:48 +02:00
Hongli Lai (Phusion)
92c2ea22ed Install add-apt-repository.
Closes GH-74.
2014-06-17 12:46:14 +02:00
Hongli Lai (Phusion)
436be20ff0 Bump version to 0.9.11 2014-06-17 12:45:24 +02:00
Christoffer Sawicki
f445cafe03 Use Go template instead of grep to extract container IP address 2014-06-16 14:20:46 +02:00
Hongli Lai
93572a5698 Update CONTRIBUTING.md
Fix link
2014-06-16 12:41:42 +02:00
Hongli Lai
f5efca365c Create CONTRIBUTING.md 2014-06-16 12:41:13 +02:00
yebyen
949bd1d89f needed for insecure key usage
`chmod 600` is for the benefit of ssh client, which will otherwise spew:

```
chmod 600 image/insecure_key.pub
SSHing into 172.17.0.2
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0664 for 'image/insecure_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: image/insecure_key
```

As you can see though, the wrong file is `chmod`'ed -- it's the private key that SSH will insist should be protected with a more restrictive mode.

After this, `CMD ["/sbin/my_init", "--enable-insecure-key"]` works as expected.
2014-06-09 12:32:52 -04:00
John Eckhart
2b339a3344 Missing target of chown 2014-06-04 02:10:00 -04:00
Bernard Potocki
b665b78454 Make container_envoriments.sh and .json readable by other users
Prevents bug when loading env variables on non-root user login.
2014-06-02 15:06:02 +02:00
Bernard Potocki
5b403fe06c Don't write HOME env variable
Loading HOME variable breaks multi-user container (i.e. logging as postgres user) if you try to load variables via `/etc/container_environment.sh`.
2014-06-02 15:03:49 +02:00
Bernard Potocki
1a6c43b8d7 Preserve ENV variables for SSH client
Currently when you ssh to host you will not see ENV variables set. This was mentioned earlier in #54 and solution is tested.

Additional rationale: currently you can't see docker link ENV variables inside ssh, so you need to load this file every time you connect to container. I would say that expected behavior is to preserve them in services that are provided at default (cron/ssh)
2014-06-02 00:11:24 +02:00
Hongli Lai
0325abf74e Changelog.md now explicitly mentions that the latest version is not yet released 2014-05-16 14:17:15 +02:00
Hongli Lai (Phusion)
22c3d60d94 Install ca-certificates package by default.
This is because we include `apt-transport-https`, but Ubuntu 14.04 no longer
installs `ca-certificates` by default anymore. Closes GH-73.
2014-05-12 23:07:17 +02:00
Hongli Lai (Phusion)
b56693beb3 Fix syslog-ng.
The system() source in the default syslog-ng config file does
not work in Docker because it tries to access /proc/kmsg,
which is not allowed due to Docker's privileges. We replace
it by a source that only reads from /dev/log.
2014-05-12 17:29:45 +02:00
Hongli Lai (Phusion)
612b1504af The syslog-ng script should restore /dev/xconsole permissions because that's what the official init script does 2014-05-12 16:43:55 +02:00
Hongli Lai (Phusion)
7bde5d9993 Document release date of 0.9.10 2014-05-12 16:15:59 +02:00
Hongli Lai (Phusion)
af11b5e7b4 Early in the my_init initialization process, do not overwrite already-defined environment variables by the ones in /etc/container_environment.
Closes GH-52.
2014-05-12 16:14:47 +02:00
Hongli Lai (Phusion)
29d315891f Use Ubuntu 14.04 as Vagrant box 2014-05-12 16:14:44 +02:00
Hongli Lai (Phusion)
5e0b1b6267 Update URLs to Vagrant boxes 2014-05-12 13:56:40 +02:00
Hongli Lai (Phusion)
e0d3f5d1a4 Bump version to 0.9.10 2014-05-12 10:32:34 +02:00
Hongli Lai (Phusion)
03adf9b696 Document the new environment variable newline handling in my_init 2014-05-12 10:32:18 +02:00
Hongli Lai (Phusion)
51748c3b1d Update the README to say that we're on Ubuntu 14.04 now. 2014-05-12 10:24:52 +02:00
Hongli Lai (Phusion)
895b145207 Update Changelog 2014-05-12 10:24:02 +02:00
mpeterson
d3d4b6124a modified setuser to use Python3 (default on 14.04) 2014-05-12 10:21:54 +02:00
mpeterson
5cfdd42d4b Modify defaults for syslog_ng to function properly
On 14.04 (trusty) there is nos no need to list all the modules since that was fixed.
No only that, listing them causes an error and it doesn't start.
2014-05-12 10:21:54 +02:00
Kingdon Barrett
6acfd8794d Remove /dev/log if it's a file a file.
Fixes https://github.com/phusion/baseimage-docker/pull/25
2014-05-12 10:21:36 +02:00
Santiago M. Mola
90ff4682df Migrate to Python 3
Ubuntu Trusty ships Python 3 by default, but not Python 2. Older versions already ship Python 3, so this change should be safe.
2014-05-10 12:28:23 +00:00
Paul Jimenez
17f000b744 Upgrade from Precise to Trusty
Conflicts:
	image/sources.list
2014-05-10 12:26:34 +00:00
mpeterson
90262a0460 Better way to enable universe and multiverse
Instead of copying over a hardcoded file we just uncomment the correct lines via two simple sed commands.

Conflicts:
	image/sources.list
2014-05-10 12:24:41 +00:00
Hongli Lai
9f369b5ed7 Merge pull request #51 from nanobeep/patch-1
Use '--rm' instead of '-rm', which was deprecated in Docker 0.9
2014-04-21 16:43:35 +02:00
Matt Jaynes
2ba32b6172 Use '--rm' instead of '-rm', which was deprecated in Docker 0.9 2014-04-08 15:36:36 -06:00
Hongli Lai
c740ff2f4d Merge pull request #49 from harto/trim-env-newlines
Trim trailing newlines from file-based envs
2014-04-02 16:47:09 +02:00
Stuart Campbell
5e2ee3838d Trim trailing newlines from file-based envs
Many editors add a trailing newline to files. This can result in
slightly unexpected values for environment variables read from
/etc/container_environment.
2014-04-03 00:13:09 +11:00
Hongli Lai (Phusion)
8f9eefa1f6 Correctly pass child process' exit status to sys.exit(). Closes GH-45 2014-03-28 10:23:25 +01:00
Hongli Lai (Phusion)
5ae32384d5 Document 0.9.9 release date 2014-03-25 17:18:16 +01:00
Hongli Lai (Phusion)
f55fde8d99 Fix a bug in the build process 2014-03-25 17:06:53 +01:00
Hongli Lai (Phusion)
0632b4865b Set the INITRD env variable and make 'ischroot' always return true.
This prevents initramfs and initscripts updates from breaking.
2014-03-25 16:44:33 +01:00
Hongli Lai (Phusion)
7914d8ac55 Enable more Ubuntu APT repositories. 2014-03-25 16:44:29 +01:00
Hongli Lai (Phusion)
73709ed0a0 During 'docker build', temporarily disable dpkg fsync to make it faster 2014-03-25 16:22:04 +01:00
Hongli Lai (Phusion)
dfaac83527 Run 'docker build' with '--rm' instead of '-rm', the latter which has been deprecated in Docker 0.9. 2014-03-25 15:49:46 +01:00
Hongli Lai (Phusion)
e11f2b8cfd Bump version to 0.9.9 2014-03-25 15:49:16 +01:00
Hongli Lai (Phusion)
fa3098206d Update Changelog 2014-03-25 15:48:05 +01:00
Hongli Lai (Phusion)
ad347d91c8 Merge branch 'amirgur1-master' 2014-03-25 15:37:18 +01:00
Hongli Lai (Phusion)
55727c2f30 Cleanup Amir Gur's patch 2014-03-25 15:36:15 +01:00
Hongli Lai (Phusion)
c8e79991b7 Merge branch 'master' of https://github.com/amirgur1/baseimage-docker into amirgur1-master 2014-03-25 15:30:00 +01:00
Hongli Lai
a03b58d94d Merge pull request #42 from rhacker/patch-1
Fix typo in Makefile
2014-03-19 10:49:41 +01:00
Dung Quang
ed89f20836 Update Makefile 2014-03-19 09:14:34 +07:00
Hongli Lai (Phusion)
fd8a1273ad Update Changelog 2014-03-17 12:59:03 +01:00
Hongli Lai
4094d20cec Merge pull request #38 from slawo-ch/patch-1
properly specify location of sftp-server binary
2014-03-17 12:57:51 +01:00
Slawomir Chodnicki
585932c74c properly specify location of sftp-server binary
Currently there is a symlink at /usr/lib/sftp-server to /usr/lib/openssh/sftp-server in the image. That seems to give trouble with packages like the rssh restricted shell, which will not follow a symlink to the sftp server binary for security reasons. So currently it is not possible to use this image as a basis for scp/sftp only access over ssh.
2014-03-15 18:08:28 +01:00
Hongli Lai
3366687e86 Merge pull request #35 from Laurent-Sarrazin/patch-1
Fix a typo
2014-03-14 11:54:15 +01:00
Laurent Sarrazin
b749352f1e Fix a typo 2014-03-12 23:27:50 +01:00
Hongli Lai
25d9972c0b Merge pull request #34 from felixhummel/typo
rw is enough for the insecure_key
2014-03-11 15:12:13 +01:00
Felix Hummel
5b1b6e8364 rw is enough for the insecure_key 2014-03-11 13:15:59 +01:00
Hongli Lai
0dab5aa4c8 Merge pull request #30 from ruphin/master
typo fix
2014-03-06 12:52:15 +01:00
Amir Gur
2ef5fa1659 * More Parametrization, example.
* All synced_folders are included.
 * Vagrantfile of baseimage and passenger are nearly identical now.  (I got to that when wanting to try passenger.  But already had a vagrant box started from baseimage, there was no need to dup the effort, just reuse the existing single box for all.  Then in end of day, may not need multiple Vagrantfiles.  Passenger is a simple structure/process for managing dockers, but only needing to use baseimage once and have one VM up)
2014-03-06 02:28:27 -08:00
Goffert van Gool
17cb4cebca typo fix 2014-03-06 02:54:37 +01:00
Amir Gur
ac7f9b0785 - Parametrized passenger-docker location 2014-03-04 14:33:57 -08:00
Amir Gur
d06b177508 - Parametrize
- Print docker version
- Add a d alias to docker
- Cleanup
2014-03-03 18:39:28 -08:00
Hongli Lai (Phusion)
775ded05dc Fix permissions on test scripts 2014-02-26 11:56:19 +01:00
Hongli Lai (Phusion)
cc9847580d Document release date 2014-02-26 11:56:10 +01:00
Hongli Lai (Phusion)
46334c7363 Bump version to 0.9.8 2014-02-26 11:44:19 +01:00
Hongli Lai (Phusion)
1684aa1448 Fix my_init not properly forcing Runit to shut down if Runit appears to refuse to respond to SIGTERM. 2014-02-25 22:49:34 +01:00
Hongli Lai (Phusion)
367cddb201 Fix a regression in my_init which causes it to delete environment variables passed from Docker. 2014-02-25 22:08:37 +01:00
Hongli Lai (Phusion)
27782aca39 Note release date in Changelog.md 2014-02-25 15:21:57 +01:00
Hongli Lai (Phusion)
4e60438c66 Fixed some warnings in 00_regen_ssh_host_keys.sh. 2014-02-25 15:18:28 +01:00
Hongli Lai (Phusion)
ec719ad255 Small documentation updates regarding environment variables 2014-02-25 13:37:55 +01:00
Hongli Lai (Phusion)
23651ad5ff Cleanup Changelog 2014-02-25 12:48:21 +01:00
Hongli Lai (Phusion)
300adc0bf2 Store environment variables in a file, and allow init scripts to change environment variables.
Closes GH-23.
2014-02-25 12:47:02 +01:00
Hongli Lai (Phusion)
c0e872b3e3 Credit Dr Nic and Tomer Cohen. 2014-02-25 11:21:42 +01:00
Hongli Lai (Phusion)
87698aa223 Added the logrotate service. Fixes GH-22. 2014-02-25 11:18:25 +01:00
Hongli Lai (Phusion)
68e4f5e8bf Removed some default Ubuntu cron jobs which are not useful in Docker containers. 2014-02-25 11:16:09 +01:00
Hongli Lai (Phusion)
8cf30f326e Change the documented way to start a shell: run bash through my_init 2014-02-25 11:09:56 +01:00
Hongli Lai (Phusion)
9af37c0d58 Fixed syslog-ng not being able to start because of a missing afsql module.
Closes pull request 7.
2014-02-25 11:07:54 +01:00
Hongli Lai (Phusion)
095c1e715c Add a Changelog entry that documents why all EXPOSEd ports are now removed. 2014-02-25 10:52:11 +01:00
Hongli Lai (Phusion)
aa46e10163 Remove all EXPOSEd ports. Fixes GH-15. 2014-02-25 10:49:08 +01:00
Hongli Lai (Phusion)
5e9f60b0ea Update documentation regarding the insecure key. 2014-02-25 10:45:55 +01:00
Hongli Lai (Phusion)
139bc7b81e Merge branch 'feature/16' of https://github.com/thomasleveil/baseimage-docker into thomasleveil-feature/16 2014-02-25 10:30:30 +01:00
Hongli Lai
3d5a46482f Merge pull request #20 from thomasleveil/fix/failed-shutdown-msg
Fix failed shutdown message not displaying process name and PID
2014-02-24 13:23:04 +01:00
Hongli Lai
6d1a12673b Merge pull request #21 from thomasleveil/fix/unbuffered-stdout
Fix log not showing messages sent to stdout by my_init
2014-02-24 13:21:43 +01:00
Thomas LÉVEIL
55efefa51b fix log not showing messages sent to stdout by my_init 2014-02-22 17:16:55 +01:00
Thomas LÉVEIL
1443856c34 fix failed shutdown message not displaying process name and PID 2014-02-22 16:36:41 +01:00
Thomas LÉVEIL
bf35ff2bf1 allow to install the insecure key with the new --enable-insecure-key option
fix #16
2014-02-22 16:30:08 +01:00
Thomas LÉVEIL
7bd55402b0 do not remove already installed private keys when installing the secure key 2014-02-22 14:26:48 +01:00
Hongli Lai
1c560d073d Merge pull request #17 from thomasleveil/master
Add the insecure private key in the PuTTY format
2014-02-21 01:21:26 +01:00
Thomas LÉVEIL
3eec5201da Update README.md
to add the download link to the insecure private key in the PuTTY format
2014-02-21 01:10:21 +01:00
Thomas LÉVEIL
02c42206ec Create insecure_key.ppk
as a convenience for PuTTY/WinSCP users
2014-02-21 01:07:52 +01:00
Hongli Lai (Phusion)
3125ec683b Add instructions regarding disabling SSH. 2014-02-20 13:43:03 +01:00
Hongli Lai (Phusion)
829d753a88 Fix typos in the insecure key documentation 2014-02-19 17:15:48 +01:00
Hongli Lai
91a6b2d7a2 Merge pull request #13 from tomer/patch-1
Fix link [reap them] in README.md
2014-02-19 17:13:38 +01:00
Hongli Lai
636444612f Merge pull request #12 from drnic/patch-1
Fix typo in changelog: not -> now
2014-02-19 17:11:17 +01:00
Tomer Cohen
a131b126f5 Fix link [reap them] in README.md 2014-02-19 12:10:17 +02:00
Dr Nic Williams
cb700ed590 not -> now
I'm just guessing... its "now much faster" rather than "not much faster" :)
2014-02-18 16:14:11 -08:00
Hongli Lai (Phusion)
0caf8692fb Update Changelog 2014-02-17 12:01:09 +01:00
Hongli Lai (Phusion)
d8968d136a Improve setuser: set auxilliary groups and more environment variables 2014-02-15 12:42:31 +01:00
Hongli Lai (Phusion)
b6dac86e04 Improve the init system: support skipping startup files and running a custom main command 2014-02-15 12:11:48 +01:00
Hongli Lai (Phusion)
d884118827 Add a 'make ssh' task for easily SSHing into the container 2014-02-13 15:37:35 +01:00
Hongli Lai (Phusion)
c22f8804ad Correctly reap child processes that are adopted during invocation of init scripts. 2014-02-13 15:37:32 +01:00
Hongli Lai (Phusion)
67c6b089e3 Bump version to 0.9.6 2014-02-13 15:37:32 +01:00
Hongli Lai (Phusion)
7e35fe7f32 Update Changelog 2014-02-06 14:00:18 +01:00
Hongli Lai (Phusion)
37cd856425 Disable the insecure SSH key by default 2014-02-06 13:40:27 +01:00
Hongli Lai (Phusion)
a5f521b1b1 Change the name inside the insecure key 2014-02-06 13:06:40 +01:00
Hongli Lai (Phusion)
e833b26944 Bump version to 0.9.5 2014-02-06 13:06:23 +01:00
Hongli Lai (Phusion)
4ab0625de0 Update README 2014-02-06 12:36:06 +01:00
Hongli Lai (Phusion)
a8db7a386f Update Changelog 2014-02-06 12:32:39 +01:00
Hongli Lai (Phusion)
f0fbe3ffc8 Use setuser instead of chpst in the memcached example for consistency. Closes GH-8 2014-02-06 12:31:07 +01:00
Hongli Lai
4a6ee64b63 Merge pull request #6 from yukonlabs/master
Bypass runsvdir-start in order to preserve env
2014-02-06 12:30:51 +01:00
Matt Olson
892dcc7ca4 Bypass runsvdir-start in order to preserve env
runsvdir-start clears the environment, which wipes out any
environment variables passed in when the container starts.
This patch bypasses runsvdir-start and calls runsvdir directly,
preserving the current environment.
2014-02-05 11:52:48 -08:00
31 changed files with 1790 additions and 211 deletions

7
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,7 @@
Hey, thanks for wanting to contribute to baseimage-docker. :)
If you have a question, please use the [discussion forum](https://groups.google.com/d/forum/passenger-docker). The Github issue tracker is only for **bug reports and feature requests**.
If you want to develop baseimage-docker, use the Vagrantfile in the repository. It will setup an Ubuntu VM with Docker installed in it. Use the Makefile to build the Docker image.
All development happens on the `next` branch. The `master` branch is supposed to point to the latest stable release, because users read documentation from the `master` branch.

View File

@@ -1,3 +1,105 @@
## 0.9.16 (release date: 2015-01-20)
* `docker exec` is now the default and recommended mechanism for running commands in the container. SSH is now disabled by default, but is still supported for those cases where "docker exec" is not appropriate. Closes GH-168.
* All syslog output is now forwarded to `docker logs`. Closes GH-123.
* The workaround for Docker bug 2267 (the inability to modify /etc/hosts) has been removed, because it has been fixed upstream. Closes GH-155.
* Logrotate now reloads syslog-ng properly. Closes GH-167.
* Fixed some locale issues. Closes GH-178. Thanks to David J. M. Karlsen.
* Fixed problems with cron. Closes GH-115.
* Contribution by Bryan Bishop.
## 0.9.15 (release date: 2014-10-03)
* Fixed the setuid bit on /usr/bin/sudo. This problem was caused by Docker bug #6828.
## 0.9.14 (release date: 2014-10-01)
* Installed all the latest Ubuntu security updates. This patches Shellshock, among other things.
* Some documentation updates by andreamtp.
## 0.9.13 (release date: 2014-08-22)
* Fixed `my_init` not properly exiting with a non-zero exit status when Ctrl-C is pressed.
* The GID of the `docker_env` group has been changed from 1000 to 8377, in order to avoid GID conflicts with any groups that you might want to introduce inside the container.
* The syslog-ng socket is now deleted before starting the syslog-ng daemon, to avoid the daemon from failing to start due to garbage on the filesystem. Thanks to Kingdon Barrett. Closes GH-129.
* Typo fixes by Arkadi Shishlov.
## 0.9.12 (release date: 2014-07-24)
* We now officially support `nsenter` as an alternative way to login to the container. With official support, we mean that we've provided extensive documentation on how to use `nsenter`, as well as related convenience tools. However, because `nsenter` has various issues, and for backward compatibility reasons, we still support SSH. Please refer to the README for details about `nsenter`, and what the pros and cons are compared to SSH.
* The `docker-bash` tool has been modified to use `nsenter` instead of SSH.
* What was previously the `docker-bash` tool, has now been renamed to `docker-ssh`. It now also works on a regular sh shell too, instead of bash specifically.
* Added a workaround for Docker's inability to modify /etc/hosts in the container ([Docker bug 2267](https://github.com/dotcloud/docker/issues/2267)). Please refer to the README for details.
* Fixed an issue with SSH X11 forwarding. Thanks to Anatoly Bubenkov. Closes GH-105.
* The init system now prints its own log messages to stderr. Thanks to mephi42. Closes GH-106.
## 0.9.11 (release date: 2014-06-24)
* Introduced the `docker-bash` tool. This is a shortcut tool for logging into a container using SSH. Usage: `docker-bash <CONTAINER ID>`. See the README for details.
* Fixed various process waiting issues in `my_init`. Closes GH-27, GH-82 and GH-83. Thanks to André Luiz dos Santos and Paul Annesley.
* The `ca-certificates` package is now installed by default. This is because we include `apt-transport-https`, but Ubuntu 14.04 no longer installs `ca-certificates` by default anymore. Closes GH-73.
* Output print by Runit services are now redirected to the Docker logs instead of to proctitle. Thanks to Paul Annesley.
* Container environment variables are now made available to SSH root shells. If you login with SSH through a non-root account, then container environment variables are only made available if that user is a member of the `docker_env` group. Thanks to Bernard Potocki.
* `add-apt-repository` is now installed by default. Closes GH-74.
* Various minor fixes and contributions thanks to yebyen, John Eckhart, Christoffer Sawicki and Brant Fitzsimmons.
## 0.9.10 (release date: 2014-05-12)
* Upgraded to Ubuntu 14.04 (Trusty). We will no longer release images based on 12.04.
Thanks to contributions by mpeterson, Paul Jimenez, Santiago M. Mola and Kingdon Barrett.
* Fixed a problem with my_init not correctly passing child processes' exit status. Fixes GH-45.
* When reading environment variables from /etc/container_environment, the trailing newline (if any) is ignored. This makes commands like this work, without unintentially adding a newline to the environment variable value:
echo my_value > /etc/container_environment/FOO
If you intended on adding a newline to the value, ensure you have *two* trailing newlines:
echo -e "my_value\n" > /etc/container_environment/FOO
* It was not possible to use `docker run -e` to override environment variables defined in /etc/container_environment. This has been fixed (GH-52). Thanks to Stuart Campbell for reporting this bug.
## 0.9.9 (release date: 2014-03-25)
* Fixed a problem with rssh. (Slawomir Chodnicki)
* The `INITRD` environment variable is now set in the container by default. This prevents updates to the `initramfs` from running grub or lilo.
* The `ischroot` tool in Ubuntu has been modified to always return true. This prevents updates to the `initscripts` package from breaking /dev/shm.
* Various minor bug fixes, improvements and typo corrections. (Felix Hummel, Laurent Sarrazin, Dung Quang, Amir Gur)
## 0.9.8 (release date: 2014-02-26)
* Fixed a regression in `my_init` which causes it to delete environment variables passed from Docker.
* Fixed `my_init` not properly forcing Runit to shut down if Runit appears to refuse to respond to SIGTERM.
## 0.9.7 (release date: 2014-02-25)
* Improved and fixed bugs in `my_init` (Thomas LÉVEIL):
* It is now possible to enable the insecure key by passing `--enable-insecure-key` to `my_init`. This allows users to easily enable the insecure key for convenience reasons, without having the insecure key enabled permanently in the image.
* `my_init` now exports environment variables to the directory `/etc/container_environment` and to the files `/etc/container_environment.sh`, `/etc/container_environment.json`. This allows all applications to query what the original environment variables were. It is also possible to change the environment variables in `my_init` by modifying `/etc/container_environment`. More information can be found in the README, section "Environment variables".
* Fixed a bug that causes it not to print messages to stdout when there is no pseudo terminal. This is because Python buffers stdout by default.
* Fixed an incorrectly printed message.
* The insecure key is now also available in PuTTY format. (Thomas LÉVEIL)
* Fixed `enable_insecure_key` removing already installed SSH keys. (Thomas LÉVEIL)
* The baseimage-docker image no longer EXPOSEs any ports by default. The EXPOSE entries were originally there to enable some default guest-to-host port forwarding entries, but in recent Docker versions they changed the meaning of EXPOSE, and now EXPOSE is used for linking containers. As such, we no longer have a reason to EXPOSE any ports by default. Fixes GH-15.
* Fixed syslog-ng not being able to start because of a missing afsql module. Fixes the issue described in [pull request 7](https://github.com/phusion/baseimage-docker/pull/7).
* Removed some default Ubuntu cron jobs which are not useful in Docker containers.
* Added the logrotate service. Fixes GH-22.
* Fixed some warnings in `/etc/my_init.d/00_regen_ssh_host_keys.sh`.
* Fixed some typos in the documentation. (Dr Nic Williams, Tomer Cohen)
## 0.9.6 (release date: 2014-02-17)
* Fixed a bug in `my_init`: child processes that have been adopted during execution of init scripts are now properly reaped.
* Much improved `my_init`:
* It is now possible to run and watch a custom command, possibly in addition to running runit. See "Running a one-shot command in the container" in the README.
* It is now possible to skip running startup files such as /etc/rc.local.
* Shutdown is now much faster. It previously took a few seconds, but it is now almost instantaneous.
* It ensures that all processes in the container are properly shut down with SIGTERM, even those that are not direct child processes of `my_init`.
* `setuser` now also sets auxilliary groups, as well as more environment variables such as `USER` and `UID`.
## 0.9.5 (release date: 2014-02-06)
* Environment variables are now no longer reset by runit. This is achieved by running `runsvdir` directly instead of through Debian's `runsvdir-start`.
* The insecure SSH key is now disabled by default. You have to explicitly opt-in to use it.
## 0.9.4 (release date: 2014-02-03)
* Fixed syslog-ng startup problem.

View File

@@ -1,20 +1,29 @@
NAME = phusion/baseimage
VERSION = 0.9.4
VERSION = 0.9.16
.PHONY: all build test tag_latest release
.PHONY: all build test tag_latest release ssh
all: build
build:
docker build -t $(NAME):$(VERSION) -rm image
docker build -t $(NAME):$(VERSION) --rm image
test:
env NAME=$(NAME) VERSION=$(VERSION) ./test/runner.sh
tag_latest:
docker tag $(NAME):$(VERSION) $(NAME):latest
docker tag -f $(NAME):$(VERSION) $(NAME):latest
release: test tag_latest
@if ! docker images phusion/baseimage | awk '{ print $$2 }' | grep -q -F $(VERSION); then echo "$(NAME) version $(VERSION) is not yet built. Please run 'make build'"; false; fi
@if ! docker images $(NAME) | awk '{ print $$2 }' | grep -q -F $(VERSION); then echo "$(NAME) version $(VERSION) is not yet built. Please run 'make build'"; false; fi
@if ! head -n 1 Changelog.md | grep -q 'release date'; then echo 'Please note the release date in Changelog.md.' && false; fi
docker push $(NAME)
@echo "*** Don't forget to create a tag. git tag rel-$(VERSION) && git push origin rel-$(VERSION)"
ssh:
chmod 600 image/insecure_key
@ID=$$(docker ps | grep -F "$(NAME):$(VERSION)" | awk '{ print $$1 }') && \
if test "$$ID" = ""; then echo "Container is not running."; exit 1; fi && \
IP=$$(docker inspect $$ID | grep IPAddr | sed 's/.*: "//; s/".*//') && \
echo "SSHing into $$IP" && \
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i image/insecure_key root@$$IP

374
README.md
View File

@@ -1,12 +1,18 @@
# A minimal Ubuntu base image modified for Docker-friendliness
Baseimage-docker is a special [Docker](http://www.docker.io) image that is configured for correct use within Docker containers. It is Ubuntu, plus modifications for Docker-friendliness. You can use it as a base for your own Docker images.
Baseimage-docker is a special [Docker](https://www.docker.com) image that is configured for correct use within Docker containers. It is Ubuntu, plus:
Baseimage-docker is available for pulling from [the Docker registry](https://index.docker.io/u/phusion/baseimage/)!
* Modifications for Docker-friendliness.
* Administration tools that are especially useful in the context of Docker.
* Mechanisms for easily running multiple processes, [without violating the Docker philosophy](#docker_single_process).
You can use it as a base for your own Docker images.
Baseimage-docker is available for pulling from [the Docker registry](https://registry.hub.docker.com/u/phusion/baseimage/)!
### What are the problems with the stock Ubuntu base image?
Ubuntu is not designed to be run inside docker. Its init system, Upstart, assumes that it's running on either real hardware or virtualized hardware, but not inside a Docker container. But inside a container you don't want a full system anyway, you want a minimal system. But configuring that minimal system for use within a container has many strange corner cases that are hard to get right if you are not intimately familiar with the Unix system model. This can cause a lot of strange problems.
Ubuntu is not designed to be run inside Docker. Its init system, Upstart, assumes that it's running on either real hardware or virtualized hardware, but not inside a Docker container. But inside a container you don't want a full system anyway, you want a minimal system. But configuring that minimal system for use within a container has many strange corner cases that are hard to get right if you are not intimately familiar with the Unix system model. This can cause a lot of strange problems.
Baseimage-docker gets everything right. The "Contents" section describes all the things that it modifies.
@@ -35,12 +41,29 @@ You can configure the stock `ubuntu` image yourself from your Dockerfile, so why
* [What's inside the image?](#whats_inside)
* [Overview](#whats_inside_overview)
* [Wait, I thought Docker is about running a single process in a container?](#docker_single_process)
* [Does Baseimage-docker advocate "fat containers" or "treating containers as VMs"?](#fat_containers)
* [Inspecting baseimage-docker](#inspecting)
* [Using baseimage-docker as base image](#using)
* [Getting started](#getting_started)
* [Adding additional daemons](#adding_additional_daemons)
* [Running scripts during container startup](#running_startup_scripts)
* [Login to the container](#login)
* [Environment variables](#environment_variables)
* [Centrally defining your own environment variables](#envvar_central_definition)
* [Environment variable dumps](#envvar_dumps)
* [Modifying environment variables](#modifying_envvars)
* [Security](#envvar_security)
* [Container administration](#container_administration)
* [Running a one-shot command in a new container](#oneshot)
* [Running a command in an existing, running container](#run_inside_existing_container)
* [Login to the container via `docker exec`](#login_docker_exec)
* [Usage](#docker_exec)
* [Login to the container via SSH](#login_ssh)
* [Enabling SSH](#enabling_ssh)
* [About SSH keys](#ssh_keys)
* [Using the insecure key for one container only](#using_the_insecure_key_for_one_container_only)
* [Enabling the insecure key permanently](#enabling_the_insecure_key_permanently)
* [Using your own key](#using_your_own_key)
* [The `docker-ssh` tool](#docker_ssh)
* [Building the image yourself](#building)
* [Conclusion](#conclusion)
@@ -56,11 +79,12 @@ You can configure the stock `ubuntu` image yourself from your Dockerfile, so why
| Component | Why is it included? / Remarks |
| ---------------- | ------------------- |
| Ubuntu 12.04 LTS | The base system. |
| A **correct** init process | According to the Unix process model, [the init process](https://en.wikipedia.org/wiki/Init) -- PID 1 -- inherits all [orphaned child processes](https://en.wikipedia.org/wiki/Orphan_process) and must [reap them](https://en.wikipedia.org/wiki/Wait_(system_call). Most Docker containers do not have an init process that does this correctly, and as a result their containers become filled with [zombie processes](https://en.wikipedia.org/wiki/Zombie_process) over time. <br><br>Furthermore, `docker stop` sends SIGTERM to the init process, which is then supposed to stop all services. Unfortunately most init systems don't do this correctly within Docker since they're built for hardware shutdowns instead. This causes processes to be hard killed with SIGKILL, which doesn't give them a chance to correctly deinitialize things. This can cause file corruption. <br><br>Baseimage-docker comes with an init process `/sbin/my_init` that performs both of these tasks correctly. |
| Ubuntu 14.04 LTS | The base system. |
| A **correct** init process | According to the Unix process model, [the init process](https://en.wikipedia.org/wiki/Init) -- PID 1 -- inherits all [orphaned child processes](https://en.wikipedia.org/wiki/Orphan_process) and must [reap them](https://en.wikipedia.org/wiki/Wait_(system_call)). Most Docker containers do not have an init process that does this correctly, and as a result their containers become filled with [zombie processes](https://en.wikipedia.org/wiki/Zombie_process) over time. <br><br>Furthermore, `docker stop` sends SIGTERM to the init process, which is then supposed to stop all services. Unfortunately most init systems don't do this correctly within Docker since they're built for hardware shutdowns instead. This causes processes to be hard killed with SIGKILL, which doesn't give them a chance to correctly deinitialize things. This can cause file corruption. <br><br>Baseimage-docker comes with an init process `/sbin/my_init` that performs both of these tasks correctly. |
| Fixes APT incompatibilities with Docker | See https://github.com/dotcloud/docker/issues/1024. |
| syslog-ng | A syslog daemon is necessary so that many services - including the kernel itself - can correctly log to /var/log/syslog. If no syslog daemon is running, a lot of important messages are silently swallowed. <br><br>Only listens locally. |
| ssh server | Allows you to easily login to your container to inspect or administer things. <br><br>Password and challenge-response authentication are disabled by default. Only key authentication is allowed.<br>By default, it allows a predefined key, in order to make debugging easy. You should replace this ASAP. See instructions. |
| syslog-ng | A syslog daemon is necessary so that many services - including the kernel itself - can correctly log to /var/log/syslog. If no syslog daemon is running, a lot of important messages are silently swallowed. <br><br>Only listens locally. All syslog messages are forwarded to "docker logs". |
| logrotate | Rotates and compresses logs on a regular basis. |
| SSH server | Allows you to easily login to your container to [inspect or administer](#login_ssh) things. <br><br>_SSH is **disabled by default** and is only one of the methods provided by baseimage-docker for this purpose. The other method is through [docker exec](#login_docker_exec). SSH is also provided as an alternative because `docker exec` comes with several caveats._<br><br>Password and challenge-response authentication are disabled by default. Only key authentication is allowed. |
| cron | The cron daemon must be running for cron jobs to work. |
| [runit](http://smarden.org/runit/) | Replaces Ubuntu's Upstart. Used for service supervision and management. Much easier to use than SysV init and supports restarting daemons when they crash. Much easier to use and more lightweight than Upstart. |
| `setuser` | A tool for running a command as another user. Easier to use than `su`, has a smaller attack vector than `sudo`, and unlike `chpst` this tool sets `$HOME` correctly. Available as `/sbin/setuser`. |
@@ -70,16 +94,31 @@ Baseimage-docker is very lightweight: it only consumes 6 MB of memory.
<a name="docker_single_process"></a>
### Wait, I thought Docker is about running a single process in a container?
Absolutely not true. Docker runs fine with multiple processes in a container. In fact, there is no technical reason why you should limit yourself to one process - it only makes things harder for you and breaks all kinds of essential system functionality, e.g. syslog.
The Docker developers advocate the philosophy of running a single *logical service* per container. A logical service can consist of multiple OS processes.
Baseimage-docker *encourages* multiple processes through the use of runit.
Baseimage-docker only advocates running multiple OS processes inside a single container. We believe this makes sense because at the very least it would solve [the PID 1 problem](#whats_inside_overview) and the "syslog blackhole" problem. By running multiple processes, we solve very real Unix OS-level problems, with minimal overhead and without turning the container into multiple logical services.
Splitting your logical service into multiple OS processes also makes sense from a security standpoint. By running processes as different users, you can limit the impact of vulnerabilities. Baseimage-docker provides tools to encourage running processes as different users, e.g. the `setuser` tool.
Do we advocate running multiple *logical services* in a single container? Not necessarily, but we do not prohibit it either. While the Docker developers are very opinionated and have very rigid philosophies about how containers *should* be built, Baseimage-docker is completely unopinionated. We believe in freedom: sometimes it makes sense to run multiple services in a single container, and sometimes it doesn't. It is up to you to decide what makes sense, not the Docker developers.
<a name="fat_containers"></a>
### Does Baseimage-docker advocate "fat containers" or "treating containers as VMs"?
There are people who are under the impression that Baseimage-docker advocates treating containers as VMs, because of the fact that Baseimage-docker advocates the use of multiple processes. Therefore they are also under the impression that Baseimage-docker does not follow the Docker philosophy. Neither of these impressions are true.
The Docker developers advocate running multiple *logical services* inside a single container. But we are not disputing that. Baseimage-docker advocates running multiple *OS processes* inside a single container, and a single logical service can consist of multiple OS processes.
It follows from this that Baseimage-docker also does not deny the Docker philosophy. In fact, many of the modifications we introduce are explicitly in line with the Docker philosophy. For example, using environment variables to pass parameters to containers is very much the "Docker way", and provide [a mechanism to easily work with environment variables](#environment_variables) in the presence of multiple processes that may run as different users.
<a name="inspecting"></a>
## Inspecting baseimage-docker
To look around in the image, run:
docker run -rm -t -i phusion/baseimage bash -l
docker run --rm -t -i phusion/baseimage:<VERSION> /sbin/my_init -- bash -l
where `<VERSION>` is [one of the baseimage-docker version numbers](https://github.com/phusion/baseimage-docker/blob/master/Changelog.md).
You don't have to download anything manually. The above command will automatically pull the baseimage-docker image from the Docker registry.
@@ -91,8 +130,6 @@ You don't have to download anything manually. The above command will automatical
The image is called `phusion/baseimage`, and is available on the Docker registry.
By default, it allows SSH access for the key in `image/insecure_key`. This makes it easy for you to login to the container, but you should replace this key as soon as possible.
# Use phusion/baseimage as base image. To make your builds reproducible, make
# sure you lock down to a specific version, not to `latest`!
# See https://github.com/phusion/baseimage-docker/blob/master/Changelog.md for
@@ -102,14 +139,6 @@ By default, it allows SSH access for the key in `image/insecure_key`. This makes
# Set correct environment variables.
ENV HOME /root
# Remove authentication rights for insecure_key.
RUN rm -f /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]
@@ -121,17 +150,17 @@ By default, it allows SSH access for the key in `image/insecure_key`. This makes
<a name="adding_additional_daemons"></a>
### Adding additional daemons
You can add additional daemons to the image by creating runit entries. You only have to write a small shell script which runs your daemon, and runit will keep it up and running for you, restarting it when it crashes, etc.
You can add additional daemons (e.g. your own app) to the image by creating runit entries. You only have to write a small shell script which runs your daemon, and runit will keep it up and running for you, restarting it when it crashes, etc.
The shell script must be called `run`, must be executable, and is to be placed in the directory `/etc/service/<NAME>`.
Here's an example showing you how to a memached server runit entry can be made.
Here's an example showing you how a memcached server runit entry can be made.
### In memcached.sh (make sure this file is chmod +x):
#!/bin/sh
# `chpst` is part of running. `chpst -u memcache` runs the given command
# as the user `memcache`. If you omit this, the command will be run as root.
exec chpst -u memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
# `/sbin/setuser memcache` runs the given command as the user `memcache`.
# If you omit that part, the command will be run as root.
exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
### In Dockerfile:
RUN mkdir /etc/service/memcached
@@ -144,7 +173,7 @@ Note that the shell script must run the daemon **without letting it daemonize/fo
The baseimage-docker init system, `/sbin/my_init`, runs the following scripts during startup, in the following order:
* All executable scripts in `/etc/my_init.d`, if this directory exists. The scripts are run during in lexicographic order.
* All executable scripts in `/etc/my_init.d`, if this directory exists. The scripts are run in lexicographic order.
* The script `/etc/rc.local`, if this file exists.
All scripts must exit correctly, e.g. with exit code 0. If any script exits with a non-zero exit code, the booting will fail.
@@ -159,14 +188,220 @@ The following example shows how you can add a startup script. This script simply
RUN mkdir -p /etc/my_init.d
ADD logtime.sh /etc/my_init.d/logtime.sh
<a name="login"></a>
### Login to the container
<a name="environment_variables"></a>
### Environment variables
You can use SSH to login to any container that is based on baseimage-docker.
If you use `/sbin/my_init` as the main container command, then any environment variables set with `docker run --env` or with the `ENV` command in the Dockerfile, will be picked up by `my_init`. These variables will also be passed to all child processes, including `/etc/my_init.d` startup scripts, Runit and Runit-managed services. There are however a few caveats you should be aware of:
Start a container based on baseimage-docker (or a container based on an image based on baseimage-docker):
* Environment variables on Unix are inherited on a per-process basis. This means that it is generally not possible for a child process to change the environment variables of other processes.
* Because of the aforementioned point, there is no good central place for defining environment variables for all applications and services. Debian has the `/etc/environment` file but it only works in some situations.
* Some services change environment variables for child processes. Nginx is one such example: it removes all environment variables unless you explicitly instruct it to retain them through the `env` configuration option. If you host any applications on Nginx (e.g. using the [passenger-docker](https://github.com/phusion/passenger-docker) image, or using Phusion Passenger in your own image) then they will not see the environment variables that were originally passed by Docker.
docker run phusion/baseimage
`my_init` provides a solution for all these caveats.
<a name="envvar_central_definition"></a>
#### Centrally defining your own environment variables
During startup, before running any [startup scripts](#running_startup_scripts), `my_init` imports environment variables from the directory `/etc/container_environment`. This directory contains files who are named after the environment variable names. The file contents contain the environment variable values. This directory is therefore a good place to centrally define your own environment variables, which will be inherited by all startup scripts and Runit services.
For example, here's how you can define an environment variable from your Dockerfile:
RUN echo Apachai Hopachai > /etc/container_environment/MY_NAME
You can verify that it works, as follows:
$ docker run -t -i <YOUR_NAME_IMAGE> /sbin/my_init -- bash -l
...
*** Running bash -l...
# echo $MY_NAME
Apachai Hopachai
**Handling newlines**
If you've looked carefully, you'll notice that the 'echo' command actually prints a newline. Why does $MY_NAME not contain a newline then? It's because `my_init` strips the trailing newline, if any. If you intended on the value having a newline, you should add *another* newline, like this:
RUN echo -e "Apachai Hopachai\n" > /etc/container_environment/MY_NAME
<a name="envvar_dumps"></a>
#### Environment variable dumps
While the previously mentioned mechanism is good for centrally defining environment variables, it by itself does not prevent services (e.g. Nginx) from changing and resetting environment variables from child processes. However, the `my_init` mechanism does make it easy for you to query what the original environment variables are.
During startup, right after importing environment variables from `/etc/container_environment`, `my_init` will dump all its environment variables (that is, all variables imported from `container_environment`, as well as all variables it picked up from `docker run --env`) to the following locations, in the following formats:
* `/etc/container_environment`
* `/etc/container_environment.sh` - a dump of the environment variables in Bash format. You can source the file directly from a Bash shell script.
* `/etc/container_environment.json` - a dump of the environment variables in JSON format.
The multiple formats makes it easy for you to query the original environment variables no matter which language your scripts/apps are written in.
Here is an example shell session showing you how the dumps look like:
$ docker run -t -i \
--env FOO=bar --env HELLO='my beautiful world' \
phusion/baseimage:<VERSION> /sbin/my_init -- \
bash -l
...
*** Running bash -l...
# ls /etc/container_environment
FOO HELLO HOME HOSTNAME PATH TERM container
# cat /etc/container_environment/HELLO; echo
my beautiful world
# cat /etc/container_environment.json; echo
{"TERM": "xterm", "container": "lxc", "HOSTNAME": "f45449f06950", "HOME": "/root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "FOO": "bar", "HELLO": "my beautiful world"}
# source /etc/container_environment.sh
# echo $HELLO
my beautiful world
<a name="modifying_envvars"></a>
#### Modifying environment variables
It is even possible to modify the environment variables in `my_init` (and therefore the environment variables in all child processes that are spawned after that point in time), by altering the files in `/etc/container_environment`. After each time `my_init` runs a [startup script](#running_startup_scripts), it resets its own environment variables to the state in `/etc/container_environment`, and re-dumps the new environment variables to `container_environment.sh` and `container_environment.json`.
But note that:
* modifying `container_environment.sh` and `container_environment.json` has no effect.
* Runit services cannot modify the environment like that. `my_init` only activates changes in `/etc/container_environment` when running startup scripts.
<a name="envvar_security"></a>
#### Security
Because environment variables can potentially contain sensitive information, `/etc/container_environment` and its Bash and JSON dumps are by default owned by root, and accessible only by the `docker_env` group (so that any user added this group will have these variables automatically loaded).
If you are sure that your environment variables don't contain sensitive data, then you can also relax the permissions on that directory and those files by making them world-readable:
RUN chmod 755 /etc/container_environment
RUN chmod 644 /etc/container_environment.sh /etc/container_environment.json
<a name="container_administration"></a>
## Container administration
One of the ideas behind Docker is that containers should be stateless, easily restartable, and behave like a black box. However, you may occasionally encounter situations where you want to login to a container, or to run a command inside a container, for development, inspection and debugging purposes. This section describes how you can administer the container for those purposes.
<a name="oneshot"></a>
### Running a one-shot command in a new container
_**Note:** This section describes how to run a command insider a -new- container. To run a command inside an existing running container, see [Running a command in an existing, running container](#run_inside_existing_container)._
Normally, when you want to create a new container in order to run a single command inside it, and immediately exit after the command exits, you invoke Docker like this:
docker run YOUR_IMAGE COMMAND ARGUMENTS...
However the downside of this approach is that the init system is not started. That is, while invoking `COMMAND`, important daemons such as cron and syslog are not running. Also, orphaned child processes are not properly reaped, because `COMMAND` is PID 1.
Baseimage-docker provides a facility to run a single one-shot command, while solving all of the aforementioned problems. Run a single command in the following manner:
docker run YOUR_IMAGE /sbin/my_init -- COMMAND ARGUMENTS ...
This will perform the following:
* Runs all system startup files, such as /etc/my_init.d/* and /etc/rc.local.
* Starts all runit services.
* Runs the specified command.
* When the specified command exits, stops all runit services.
For example:
$ docker run phusion/baseimage:<VERSION> /sbin/my_init -- ls
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 80
*** Running ls...
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
*** ls exited with exit code 0.
*** Shutting down runit daemon (PID 80)...
*** Killing all processes...
You may find that the default invocation is too noisy. Or perhaps you don't want to run the startup files. You can customize all this by passing arguments to `my_init`. Invoke `docker run YOUR_IMAGE /sbin/my_init --help` for more information.
The following example runs `ls` without running the startup files and with less messages, while running all runit services:
$ docker run phusion/baseimage:<VERSION> /sbin/my_init --skip-startup-files --quiet -- ls
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
<a name="run_inside_existing_container"></a>
### Running a command in an existing, running container
There are two ways to run a command inside an existing, running container.
* Through the `docker exec` tool. This is builtin Docker tool, available since Docker 1.4. Internally, it uses Linux kernel system calls in order to execute a command within the context of a container. Learn more in [Login to the container, or running a command inside it, via `docker exec`](#login_docker_exec).
* Through SSH. This approach requires running an SSH daemon inside the container, and requires you to setup SSH keys. Learn more in [Login to the container, or running a command inside it, via SSH](#login_ssh).
Both way have their own pros and cons, which you can learn in their respective subsections.
<a name="login_docker_exec"></a>
### Login to the container, or running a command inside it, via `docker exec`
You can use the `docker exec` tool on the Docker host OS to login to any container that is based on baseimage-docker. You can also use it to run a command inside a running container. `docker exec` works by using Linux kernel system calls.
Here's how it compares to [using SSH to login to the container or to run a command inside it](#login_ssh):
* Pros
* Does not require running an SSH daemon inside the container.
* Does not require setting up SSH keys.
* Works on any container, even containers not based on baseimage-docker.
* Cons
* If the `docker exec` process on the host is terminated by a signal (e.g. with the `kill` command or even with Ctrl-C), then the command that is executed by `docker exec` is *not* killed and cleaned up. You will either have to do that manually, or you have to run `docker exec` with `-t -i`.
* Requires privileges on the Docker host to be able to access the Docker daemon. Note that anybody who can access the Docker daemon effectively has root access.
* Not possible to allow users to login to the container without also letting them login to the Docker host.
<a name="docker_exec_usage"></a>
#### Usage
Start a container:
docker run YOUR_IMAGE
Find out the ID of the container that you just ran:
docker ps
Now that you have the ID, you can use `docker exec` to run arbitrary commands in the container. For example, to run `echo hello world`:
docker exec YOUR-CONTAINER-ID echo hello world
To open a bash session inside the container, you must pass `-t -i` so that a terminal is available:
docker exec -t -i YOUR-CONTAINER-ID bash -l
<a name="login_ssh"></a>
### Login to the container, or running a command inside it, via SSH
You can use SSH to login to any container that is based on baseimage-docker. You can also use it to run a command inside a running container.
Here's how it compares to [using `docker exec` to login to the container or to run a command inside it](#login_docker_exec):
* Pros
* Does not require root privileges on the Docker host.
* Allows you to let users login to the container, without letting them login to the Docker host. However, this is not enabled by default because baseimage-docker does not expose the SSH server to the public Internet by default.
* Cons
* Requires setting up SSH keys. However, baseimage-docker makes this easy for many cases through a pregenerated, insecure key. Read on to learn more.
<a name="enabling_ssh"></a>
#### Enabling SSH
Baseimage-docker disables the SSH server by default. Add the following to your Dockerfile to enable it:
RUN rm -f /etc/service/sshd/down
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
<a name="ssh_keys"></a>
#### About SSH keys
First, you must ensure that you have the right SSH keys installed inside the container. By default, no keys are installed, so nobody can login. For convenience reasons, we provide [a pregenerated, insecure key](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key) [(PuTTY format)](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key.ppk) that you can easily enable. However, please be aware that using this key is for convenience only. It does not provide any security because this key (both the public and the private side) is publicly available. **In production environments, you should use your own keys**.
<a name="using_the_insecure_key_for_one_container_only"></a>
#### Using the insecure key for one container only
You can temporarily enable the insecure key for one container only. This means that the insecure key is installed at container boot. If you `docker stop` and `docker start` the container, the insecure key will still be there, but if you use `docker run` to start a new container then that container will not contain the insecure key.
Start a container with `--enable-insecure-key`:
docker run YOUR_IMAGE /sbin/my_init --enable-insecure-key
Find out the ID of the container that you just ran:
@@ -174,12 +409,82 @@ Find out the ID of the container that you just ran:
Once you have the ID, look for its IP address with:
docker inspect <ID> | grep IPAddress
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
Now SSH into the container. In this example we're using [the default insecure key](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key), but if you're followed the instructions well then you've already replaced that with your own key. You did replace the key, didn't you?
Now that you have the IP address, you can use SSH to login to the container, or to execute a command inside it:
# Download the insecure private key
curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/insecure_key
chmod 600 insecure_key
# Login to the container
ssh -i insecure_key root@<IP address>
# Running a command inside the container
ssh -i insecure_key root@<IP address> echo hello world
<a name="enabling_the_insecure_key_permanently"></a>
#### Enabling the insecure key permanently
It is also possible to enable the insecure key in the image permanently. This is not generally recommended, but is suitable for e.g. temporary development or demo environments where security does not matter.
Edit your Dockerfile to install the insecure key permanently:
RUN /usr/sbin/enable_insecure_key
Instructions for logging in the container is the same as in section [Using the insecure key for one container only](#using_the_insecure_key_for_one_container_only).
<a name="using_your_own_key"></a>
#### Using your own key
Edit your Dockerfile to install an SSH public key:
## Install an SSH of your choice.
ADD your_key.pub /tmp/your_key.pub
RUN cat /tmp/your_key.pub >> /root/.ssh/authorized_keys && rm -f /tmp/your_key.pub
Then rebuild your image. Once you have that, start a container based on that image:
docker run your-image-name
Find out the ID of the container that you just ran:
docker ps
Once you have the ID, look for its IP address with:
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
Now that you have the IP address, you can use SSH to login to the container, or to execute a command inside it:
# Login to the container
ssh -i /path-to/your_key root@<IP address>
# Running a command inside the container
ssh -i /path-to/your_key root@<IP address> echo hello world
<a name="docker_ssh"></a>
#### The `docker-ssh` tool
Looking up the IP of a container and running an SSH command quickly becomes tedious. Luckily, we provide the `docker-ssh` tool which automates this process. This tool is to be run on the *Docker host*, not inside a Docker container.
First, install the tool on the Docker host:
curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \
tar xzf master.tar.gz && \
sudo ./baseimage-docker-master/install-tools.sh
Then run the tool as follows to login to a container using SSH:
docker-ssh YOUR-CONTAINER-ID
You can lookup `YOUR-CONTAINER-ID` by running `docker ps`.
By default, `docker-ssh` will open a Bash session. You can also tell it to run a command, and then exit:
docker-ssh YOUR-CONTAINER-ID echo hello world
<a name="building"></a>
## Building the image yourself
@@ -204,6 +509,7 @@ If you want to call the resulting image something else, pass the NAME variable,
make build NAME=joe/baseimage
<a name="conclusion"></a>
## Conclusion

570
README_ZH_cn_.md Normal file
View File

@@ -0,0 +1,570 @@
# 小巧玲珑的ubuntu镜像
**This translation was last updated October 24, 2014.**
Baseimage-docker是一个特殊的 [Docker](https://www.docker.com) 镜像可以很优雅的将它用于docker镜像。相对于 Ubuntu, 有这些新增:
* 修改之后可以很友好的使用docker
* 修复了一些docker的bug [some Docker bugs](#workaroud_modifying_etc_hosts).
* 很有用的管理员工具
你可以用它作为你自己的基础docker镜像。
Baseimage-docker 可以从[the Docker registry](https://registry.hub.docker.com/u/phusion/baseimage/)获取到!
### 原生的ubuntu基础镜像有什么问题呢
原生ubuntu不是设计为运行docker的。它是假设运行到真实硬件或者虚拟硬件上的但不是docker容器。你运行docker容器不需要一个完整的系统你需要一个小巧的系统。如果你不熟悉unix系统那么配制出来的精简系统会有很奇怪的问题。这样就可以导致很多奇奇怪怪的问题。
Baseimage-docker 将错误都修正了。在"内容"部分,可以看到哪些内容修改过了.
<a name="why_use"></a>
### 为什么使用 baseimage-docker?
你可以用原生`ubuntu`镜像作为你的Dockerfile,那为什么又麻烦的使用baseimage-docker呢?
* 配置一个友好的基础镜像不是一个简单的任务.正如之前提到的,会很有的坑在里面.当你处理那些坑之后,你又重复造了一个baseimage-docker.使用baseimage-docker会拯救你的努力.
* 它减少了一个写正确Dockerfile文件的时间.你不用担心基础系统,你可以专注你的业务和你的项目.
* 它减少了运行`docker build`的时间,让你更快的迭代Dockerfile.
* 它减少了多次下载的时间.Docker只需要下载一次基础镜像:在第一次部署的时候.在之后的部署中,只需要对你最近的基础镜像进行修改.
-----------------------------------------
**相关资源**
[Website](http://phusion.github.io/baseimage-docker/) |
[Github](https://github.com/phusion/baseimage-docker) |
[Docker registry](https://index.docker.io/u/phusion/baseimage/) |
[Discussion forum](https://groups.google.com/d/forum/passenger-docker) |
[Twitter](https://twitter.com/phusion_nl) |
[Blog](http://blog.phusion.nl/)
**Table of contents**
**目录**
* [镜像里面包含什么?](#whats_inside)
* [概述](#whats_inside_overview)
* [等等,我认为docker在一个容器中只能允许一个进程?](#docker_single_process)
* [细细看看baseimage-docker](#inspecting)
* [用baseimage-docker作为基础镜像](#using)
* [开始](#getting_started)
* [增加后台进行](#adding_additional_daemons)
* [在启动容器过程中允许脚本](#running_startup_scripts)
* [环境变量](#environment_variables)
* [集中定义你自己的环境变量](#envvar_central_definition)
* [保存环境变量](#envvar_dumps)
* [修改环境变量](#modifying_envvars)
* [安全性](#envvar_security)
* [解决docker没有办法修改/etc/hosts的问题](#workaroud_modifying_etc_hosts)
* [禁用ssh](#disabling_ssh)
* [容器管理](#container_administration)
* [在一个新容器中运行单条命令](#oneshot)
* [在正在运行的的容器中运行命令](#run_inside_existing_container)
* [通过nsenter登录容器](#login_nsenter)
* [用法](#nsenter_usage)
* [`docker-bash`工具](#docker_bash)
* [使用ssh登录容器](#login_ssh)
* [在容器中使用不安全的key](#using_the_insecure_key_for_one_container_only)
* [支持长久不变的不安全的key](#enabling_the_insecure_key_permanently)
* [使用你自己的key](#using_your_own_key)
* [`docker-ssh`工具](#docker_ssh)
* [构建你自己的镜像](#building)
* [总结](#conclusion)
-----------------------------------------
<a name="whats_inside"></a>
## 镜像里面包含什么?
<a name="whats_inside_overview"></a>
### 概述
*想看一个完整的基础镜像?这里有一个包含Ruby,Python Node.js and Meteor的.可以看看[passenger-docker](https://github.com/phusion/passenger-docker).*
| 模块 | 包含什么 / 备注 |
| ---------------- | ------------------- |
| Ubuntu 14.04 LTS | 基础系统. |
| 一个**正确**的初始化进程 | 根据Unix进程模型,[初始化进程](https://en.wikipedia.org/wiki/Init) -- PID 1 -- 继承了所有[孤立的子进行],并且必须[监控他们](https://en.wikipedia.org/wiki/Wait_(system_call)).大多数Docker容器没有一个正确的初始化进程,结果是他们的容器就出现了大量的[僵尸进程](https://en.wikipedia.org/wiki/Zombie_process).<br><br>此外,`docker stop`发送终止信号给初始化进程,然后停止所有的服务进程.不幸的是,由于他们主机关闭了容器,大多初始系统没有正确运行.<br><br>Baseimage-docker包含了一个初始进程`/sbin/my_init`,来正确的执行这些任务. |
| 修复了APT 与docker不兼容的问题 | See https://github.com/dotcloud/docker/issues/1024. |
| 修复某些Docker bugs | [Learn more.](#workaroud_modifying_etc_hosts) |
| syslog-ng | 必须要有一个监控很多服务的系统日志进程,包括内核本身,以便可以正确的输出日志到/var/log/syslog.如果没有后台日志进程,那么很多重要的信息就会丢失了.<br><br>只监听本地服务. |
| logrotate | logrotate 程序是一个日志文件管理工具,可以定期转存和压缩日志. |
| SSH server | 允许你可以很容易的登录到你的容器中进行[管理](#login_ssh).<br><br>_baseimage-docker提供了一个SSH的方法.还有其他方法,比如通过[nsenter](#login_nsenter).SSH提供了一个方法,因为nsenter还有很多的问题._<br><br>通过密码和challenge-response的方式,默认是禁用的.只有通过key认证的方式是允许的.<br><br>如果你想禁用SSH访问的方式,禁用也是很容易的.可以阅读下面的说明. |
| cron | 定时任务进程保证定时任务的运行. |
| [runit](http://smarden.org/runit/) | 替代Ubuntu的Upstart. 用于监控服务和管理.比SysV init更容易使用,同时支持当有服务挂掉之后,重启这些服务.比Upstart更易使用,也更加的轻量级. |
| `setuser` |使用另一个用户运行命令的工具,比`su`更容易使用,减少使用`sudo`的安全性,不像使用`chpst`,需要正确的设置`$HOME`.`/sbin/setuser`这样使用就可以了. |
Baseimage-docker is very lightweight: it only consumes 6 MB of memory.
Baseimage-docker是非常轻量级的:仅仅小号6MB内存.
<a name="docker_single_process"></a>
### 等等,我认为Docker在一个容器中就运行一个进程吗?
绝对不是这样的. 在一个docker容器中,运行多个进程也是很好的. 事实上,没有什么技术原因限制你只运行一个进程,运行很多的进程,只会把容器中系统的基本功能搞的更乱,比如syslog.
Baseimage-docker *鼓励* 通过runit来运行多进程.
<a name="inspecting"></a>
## 检测一下baseimage-docker
要检测镜像,执行下面的命令:
docker run --rm -t -i phusion/baseimage:<VERSION> /sbin/my_init -- bash -l
`<VERSION>` 是[baseimage-docker的版本号](https://github.com/phusion/baseimage-docker/blob/master/Changelog.md).
你不用手动去下载任何文件.上面的命令会自动从docker仓库下载baseimage-docker镜像.
<a name="using"></a>
## 使用baseimage-docker作为基础镜像
<a name="getting_started"></a>
### 入门指南
The image is called `phusion/baseimage`, and is available on the Docker registry.
镜像名字叫`phusion/baseimage`,在Docker仓库上也是可用的.
下面的这个是一个Dockerfile的模板.
# 使用phusion/baseimage作为基础镜像,去构建你自己的镜像,需要下载一个明确的版本,千万不要使用`latest`.
# 查看https://github.com/phusion/baseimage-docker/blob/master/Changelog.md,可用看到版本的列表.
FROM phusion/baseimage:<VERSION>
# 设置正确的环境变量.
ENV HOME /root
# 生成SSH keys,baseimage-docker不包含任何的key,所以需要你自己生成.你也可以注释掉这句命令,系统在启动过程中,会生成一个.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
# 初始化baseimage-docker系统
CMD ["/sbin/my_init"]
# 这里可以放置你自己需要构建的命令
# 当完成后,清除APT.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
<a name="adding_additional_daemons"></a>
### 增加后台进程
你可以通过runit工具向你的镜像中添加后台进程(例如:你自己的某些应用).你需要编写一个运行你需要的后台进程的脚步就可以了,runit工具会保证它的正常运行,如果进程死掉,runit也会重启它的.
脚本的名称必须是`run`,必须是可以运行的,它需要放到`/etc/service/<NAME>`.
这里有一个例子,向你展示如果运行memcached服务的.
### memcached.sh(确定文件的权限是chmod +x):
#!/bin/sh
# `/sbin/setuser memcache` 指定一个`memcache`用户来运行命令.如果你忽略了这部分,就会使用root用户执行.
exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
### 在Dockerfile中:
RUN mkdir /etc/service/memcached
ADD memcached.sh /etc/service/memcached/run
注意脚本必须运行在后台的,**不能让他们进程进行daemonize/fork**.通常,后台进程会提供一个标志位或者配置文件.
<a name="running_startup_scripts"></a>
### 在容器启动的时候,运行脚本.
baseimage-docker的初始化脚本 `/sbin/my_init`,在启动的时候进程运行,按照下面的顺序:
* 如果`/etc/my_init.d`存在,则按照字母顺序执行脚本.
* 如果`/etc/rc.local`存在,则执行里面的脚本.
所有的脚本都是正确退出的,例如:退出的code是0.如果有任何脚本以非0的code退出,启动就会失败.
下面的例子向你展示了怎么添加一个启动脚本.这个脚本很简单的记录的一个系统启动时间,将启动时间记录到/tmp/boottime.txt.
### 在 logtime.sh (文件权限chmod +x):
#!/bin/sh
date > /tmp/boottime.txt
### 在 Dockerfile中:
RUN mkdir -p /etc/my_init.d
ADD logtime.sh /etc/my_init.d/logtime.sh
<a name="environment_variables"></a>
### 环境变量
如果你使用`/sbin/my_init`作为主容器命令,那么通过`docker run --env`或者在Dockerfile文件中设置的`ENV`环境变量,都会被`my_init`读取.
* 在Unix系统中,环境变量都会被子进程给继承.这就意味着,子进程不可能修改环境变量或者修改其他进程的环境变量.
* 由于上面提到的一点,这里没有一个可以为所有应用和服务集中定义环境的地方.Debian提供了一个`/etc/environment` 文件,解决一些问题.
* 某些服务更改环境变量是为了给子进程使用.Nginx有这样的一个例子:它移除了所有的环境变量,除非你通过`env`进行了配置,明确了某些是保留的.如果你部署了任何应用在Nginx镜像(例如:使用[passenger-docker](https://github.com/phusion/passenger-docker)镜像或者使用Phusion Passenger作为你的镜像.),那么你通过Docker,你不会看到任何环境变量.
`my_init`提供了一个办法来解决这些问题.
<a name="envvar_central_definition"></a>
#### 集中定义你的环境变量
在启动的时候,在执行[startup scripts](#running_startup_scripts),`my_init`会从`/etc/container_environment`导入环境变量.这个文件夹下面,包含的文件,文件被命名为环境变量的名字.文件内容就是环境变量的值.这个文件夹是因此是一个集中定义你的环境变量的好地方,它会继承到所有启动项目和Runit管理的服务中.
给个例子,在你的dockerfile如何定义一个环境变量:
RUN echo Apachai Hopachai > /etc/container_environment/MY_NAME
你可以按照下面这样验证:
$ docker run -t -i <YOUR_NAME_IMAGE> /sbin/my_init -- bash -l
...
*** Running bash -l...
# echo $MY_NAME
Apachai Hopachai
**换行处理**
如果你观察仔细一点,你会注意到'echo'命令,实际上在它是在新行打印出来的.为什么$MY_NAME没有包含在一行呢? 因为`my_init`在尾部有个换行字符.如果你打算让你的值包含一个新行,你需要增*另外*一个新字符,像这样:
RUN echo -e "Apachai Hopachai\n" > /etc/container_environment/MY_NAME
<a name="envvar_dumps"></a>
#### 环境变量存储
上面提到集中定义环境变量,它不会从子服务进程改变父服务进程或者重置环境变量.而且,`my_init`也会很容易的让你查询到原始的环境变量是什么.
在启动的时候,`/etc/container_environment`, `my_init`中的变量会存储起来,并且导入到环境变量中,例如一下的格式:
* `/etc/container_environment`
* `/etc/container_environment.sh`- 一个bash存储的环境变量格式.你可以从这个命令中得到base格式的文件.
* `/etc/container_environment.json` - 一个json格式存储的环境变量格式.
多种格式可以让你不管采用什么语言/apps都可以很容易使用环境变量.
这里有个例子,展示怎么使用:
$ docker run -t -i \
--env FOO=bar --env HELLO='my beautiful world' \
phusion/baseimage:<VERSION> /sbin/my_init -- \
bash -l
...
*** Running bash -l...
# ls /etc/container_environment
FOO HELLO HOME HOSTNAME PATH TERM container
# cat /etc/container_environment/HELLO; echo
my beautiful world
# cat /etc/container_environment.json; echo
{"TERM": "xterm", "container": "lxc", "HOSTNAME": "f45449f06950", "HOME": "/root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "FOO": "bar", "HELLO": "my beautiful world"}
# source /etc/container_environment.sh
# echo $HELLO
my beautiful world
<a name="modifying_envvars"></a>
#### 修改环境变量
通过修改`/etc/container_environment`这个文件,很有可能修改了`my_init`中的环境变量.之后,每次`my_init`启动[启动脚本](#running_startup_scripts),就会重置掉我们自己`/etc/container_environment`中的环境变量,也就会导致`container_environment.sh``container_environment.json`重新存储.
但是记住这些:
* 修改`container_environment.sh``container_environment.json`是没有效果的.
* Runit 的服务是不能像这样修改环境变量的.`my_init`运行的时候,只对`/etc/container_environment`中的修改是生效的.
<a name="envvar_security"></a>
#### 安全
因为环境变量可能包含敏感信息, `/etc/container_environment`和它的bash文件和JSON文件,默认都是root,都是可以被`docker_env`群组可以访问的(所以任何用户只要添加到群组中,都可以自动的获取这些信息).
如果你确定你的环境变量中没有什么敏感信息,那么你可以放松管理权限,将文件夹和文件分配下面的权限:
RUN chmod 755 /etc/container_environment
RUN chmod 644 /etc/container_environment.sh /etc/container_environment.json
<a name="workaroud_modifying_etc_hosts"></a>
### 解决Docker没有办法解决的/etc/hosts的问题
当前是没有办法在docker容器中修改`/etc/hosts`,这个是因为[Docker bug 2267](https://github.com/dotcloud/docker/issues/2267).Baseimage-docker包含了解决这个问题的办法,你必须明白是怎么修改的.
修改的办法包含在系统库中的` libnss_files.so.2`文件,这个文件使用`/etc/workaround-docker-2267/hosts`来代替系统使用`/etc/hosts`.如果需要修改`/etc/hosts`,你只要修改`/etc/workaround-docker-2267/hosts`就可以了.
增加这个修改到你的Dockerfile.下面的命令修改了文件`libnss_files.so.2`.
RUN /usr/bin/workaround-docker-2267
(其实你不用在Dockerfile文件中运行这个命令,你可以在容器中运行一个shell就可以了.)
验证一下它是否生效了,[在你的容器中打开一个shell](#inspecting),修改`/etc/workaround-docker-2267/hosts`,检查一下是否生效了:
bash# echo 127.0.0.1 my-test-domain.com >> /etc/workaround-docker-2267/hosts
bash# ping my-test-domain.com
...should ping 127.0.0.1...
**注意apt-get升级:** 如果Ubuntu升级,就有可能将`libnss_files.so.2`覆盖掉,那么修改就会失效.你必须重新运行`/usr/bin/workaround-docker-2267`.为了安全一点,你应该在运行`apt-get upgrade`之后,运行一下这个命令.
<a name="disabling_ssh"></a>
### 禁用SSH
Baseimage-docker默认是支持SSH的,所以可以[使用SSH](#login_ssh)来[管理你的容器](#container_administration).万一你不想支持SSH,你可以只要禁用它:
RUN rm -rf /etc/service/sshd /etc/my_init.d/00_regen_ssh_host_keys.sh
<a name="container_administration"></a>
## 容器管理
一个优秀的docker想法,就是docker是一个无状态的,容易启动的容器,就想一个黑盒子.然而,你可能遇到某种情况,需要登录到容器,或者运行命令在容器中.或者为了开发,需要查看或者debug的目的.这章就给你讲解怎么管理容器.
<a name="oneshot"></a>
### 在一个新容器中运行一个一闪而过的命令
_**备注:** 这章讲解怎么在一个-新-容器中运行命令.要在一个存在的容器中运行命令,请查看[在一个存在的容器中,运行一个命令](#run_inside_existing_container)._
正常情况下,当你创建了一个新容器,为了在容器中运行一个单独的命令,而且在运行之后会立即退出的,你会这样调用docker命令:
docker run YOUR_IMAGE COMMAND ARGUMENTS...
然而下面的方法初始化系统的进行是不会启动.它是这样的,当调用`COMMAND`的时候,重要的后台进程,例如定时任务和系统日志都是不运行的.同样,子进程也是不会出现的,因为`COMMAND`的pid是1.
Baseimage-docker提供了一个灵活的方式运行只要一闪而过的命令,同时也解决了上述所说的问题.以一下的方式运行一条命令:
docker run YOUR_IMAGE /sbin/my_init -- COMMAND ARGUMENTS ...
他们会按照下面的流程执行:
* 运行所有的启动文件,例如 /etc/my_init.d/* and /etc/rc.local.
* 运行所有的runit服务
* 运行指定的命令
* 运行指定的命令结束之后,结束所有runit服务.
例如:
$ docker run phusion/baseimage:<VERSION> /sbin/my_init -- ls
*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
No SSH host key available. Generating one...
Creating SSH2 RSA key; this may take some time ...
Creating SSH2 DSA key; this may take some time ...
Creating SSH2 ECDSA key; this may take some time ...
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 80
*** Running ls...
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
*** ls exited with exit code 0.
*** Shutting down runit daemon (PID 80)...
*** Killing all processes...
你会发现默认的启动的流程太负责.或者你不希望执行启动文件.你可以自定义所有通过给`my_init`增加参数.调用`docker run YOUR_IMAGE /sbin/my_init --help`可以看到帮助信息.
例如上面运行`ls`命令,同时要求不运行启动脚本,减少信息打印,运行runit所有命令.
$ docker run phusion/baseimage:<VERSION> /sbin/my_init --skip-startup-files --quiet -- ls
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
<a name="run_inside_existing_container"></a>
### 在一个已经运行的容器中,运行一条命令
这里有两种办法去在一个已经运行的容器中运行命令.
* 通过`nseneter`工具.这个工具用于Linux内核调用在内嵌容器中运行命令.可以查看[通过`nsenter`,登录容器或者在容器内执行命令](#login_nsenter).
* 通过SSH.这种办法需要在容器中运行ssh服务,而且需要你创建自己的sshkey.可以查看[通过`ssh`,登录容器或者在容器内执行命令](#login_ssh).
两种方法都是他们各自的优点和确定,你可以学习他们各自的章节来了他们.
<a name="login_nsenter"></a>
### 通过`nsenter`,登录容器或者在容器内执行命令
你可以使用在docker主机上面的`nsenter`工具,来登录任何基于baseimage-docker的docker容器.你可以使用它在你的容器中运行命令.
这里有个和[通过`ssh`,登录容器或者在容器内执行命令](#login_ssh)的优缺点的比较:
* 优点
* 不需要在容器中运行ssh服务.
* 不需要ssh key.
* 运行在任何容器上,甚至不是基于baseimage-docker的容器.
* 缺点
* 通过`nsenter`运行的进程会和正常运行稍微有不同.例如,他们不同结束掉在容器中正常运行的进程.这适用于所有的子进程.
* 如果`nsenter`进程被其他命令(如`kill`命令)给终止,然后由nsenter所执行的命令,是*不会*被结束的.你将不得不手动清理.(备注:终端控制命令像Ctrl-C ** 清理所有的子进程,因为终端信号被发送到所有流程的终端会话)
* 需要学习新工具.
* 需要在docker主机上面提供root权限.
* 需要在docker主机上面是可用的.在写这篇文字的时候(2014年7月),大多数linux发行版没有加载它.然而,baseimage-docker提供了预编译的二进制文件,允许你通过[docker-bash](#docker_bash)工具,来很容易的使用它.
* 不可能没有登录到docker主机,就登录到docker容器中.(也就是说,你必须登录到docker主机,通过docker主机登录到容器.)
<a name="nsenter_usage"></a>
#### 用例
第一,确定`nsenter`已经安装了.在写这篇文字的时候(2014年7月),大多数linux发行版没有加载它.然而,baseimage-docker提供了预编译的二进制文件,允许你通过[docker-bash](#docker_bash)工具,让任何人都可以使用.
接着,启动一个容器.
docker run YOUR_IMAGE
找出你刚才运行容器的`ID`.
docker ps
一旦拥有容器的id,找到运行容器的主要进程额`PID`.
docker inspect -f "{{ .State.Pid }}" <ID>
现在你有的容器的主进程的PID,就可以使用`nsenter`来登录容器,或者在容器里面执行命令:
# 登录容器
nsenter --target <MAIN PROCESS PID> --mount --uts --ipc --net --pid bash -l
# 在容器中执行命令
nsenter --target <MAIN PROCESS PID> --mount --uts --ipc --net --pid -- echo hello world
<a name="docker_bash"></a>
#### `docker-bash`工具
查找一个容器的主要进程的PID和输入这么长的nsenter命令很快会变得乏味无论.幸运的是,我们提供了一个`docker-bash` 工具,它可以自动完成只要的工具.这个工具是运行在*docker主机*上面,不是在docker容器中.
该工具还附带了一个预编译的二进制`nsenter`,这样你不需要自己安装`nsenter`了.`docker-bash`是很简单的使用的.
首先,在docker主机上安装这个工具:
curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \
tar xzf master.tar.gz && \
sudo ./baseimage-docker-master/install-tools.sh
运行这个工具登录到容器中:
docker-bash YOUR-CONTAINER-ID
你可以通过`docker ps`来查找你的容器ID.
默认,`docker-bash`会打开一个bash 回话.你可以告诉运行什么命令,之后就会自动退出:
docker-bash YOUR-CONTAINER-ID echo hello world
<a name="login_ssh"></a>
### 通过`ssh`,登录容器或者在容器内执行命令
你可以使用ssh来登录任何基于baseimage-docker的容器.你可以使用它在容器中执行命令.
这里有个和[通过`nsenter`,登录容器或者在容器内执行命令](#login_nsenter)的优缺点的比较:
* 优点
* 不像`nsenter`一样,运行在docker主机上面.几乎每个人都会安装一个ssh客户端.
* 不想使用`nsenter`,运行的进程和正在的进程会不一样.
* 不需要docker主机提供root权限.
* 运行你让用户登录到容器,而不需要登录到docker主机.然而,默认这是不启用的,因为baseimage-docker默认不是开放ssh服务的.
* 缺点
* 需要设置ssh key.然而,baseimage-docker会提供一中办法,会让key的生成会很容器.阅读更多信息.
第一件事情,就是你需要确定你在容器中已经安装设置了ssh key. 默认,没有任何安装key的,所有你无法登录.为了方便的原因,我们提供了一个[已经生成的key](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key) [(PuTTY format)](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key.ppk),为了让你使用方便.然后,请注意这个key仅仅是为方便.他没有任何安全行,因为它的key是在网络上提供的.**在生产环境,你必须使用你自己的key.**
<a name="using_the_insecure_key_for_one_container_only"></a>
#### 在容器中使用key
你可以临时的使用key仅仅作为容器使用.这就以为这key是安装在容器上的.如果你使用`docker stop``docker start`控制容器,那么key是在容器中,但是如果你使用`docker run`开启一个新容器,那么这个容器是不包含key的.
启动新容器包含key`--enable-insecure-key`:
docker run YOUR_IMAGE /sbin/my_init --enable-insecure-key
找出你的刚才运行的容器的ID:
docker ps
一旦你拥有容器的ID,就能找到容器使用的IP地址:
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
现在你有得了IP地址,你就看通过SSH来登录容器,或者在容器中执行命令了:
# 下载key
curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/insecure_key
chmod 600 insecure_key
# 登录容器
ssh -i insecure_key root@<IP address>
# 在容器中执行命令
ssh -i insecure_key root@<IP address> echo hello world
<a name="enabling_the_insecure_key_permanently"></a>
#### 支持一个长久的key
在一个长久存在的镜像中支持一个key是很可能的.一般是不推荐这么做,但是对于临时开始或者做demo演示,对安全要求不高,还是很合适的.
编辑你的dockerfile,来安装永久的key:
RUN /usr/sbin/enable_insecure_key
在容器中怎么使用,同[在容器中使用key](#using_the_insecure_key_for_one_container_only)的章节说的一样.
<a name="using_your_own_key"></a>
#### 使用你自己的key
编辑你的dockerfile,来安装ssh public key:
## 安装你自己的public key.
ADD your_key.pub /tmp/your_key.pub
RUN cat /tmp/your_key.pub >> /root/.ssh/authorized_keys && rm -f /tmp/your_key.pub
重新创建你的镜像.一旦你创建成功,启动基于这个镜像的容器.
docker run your-image-name
找出你的刚才运行的容器的ID:
docker ps
一旦你拥有容器的ID,就能找到容器使用的IP地址:
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
现在你有得了IP地址,你就看通过SSH来登录容器,或者在容器中执行命令了:
# 登录容器
ssh -i /path-to/your_key root@<IP address>
# 在容器中执行命令
ssh -i /path-to/your_key root@<IP address> echo hello world
<a name="docker_ssh"></a>
#### `docker-ssh`工具
找到容器的IP,运行ssh命令,很快会变得乏味无聊.幸运的是,我们提供了一个`docker-ssh`,可以自动完成这些事情.这个工具是运行在*Docker 主机*上的,不是安装在docker容器中的.
首先,在docker主机上面安装这个工具.
curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \
tar xzf master.tar.gz && \
sudo ./baseimage-docker-master/install-tools.sh
使用这个工具通过ssh登录容器:
docker-ssh YOUR-CONTAINER-ID
你可以使用`docker ps`找到`YOUR-CONTAINER-ID`.
默认,`docker-bash`会打开一个bash 回话.你可以告诉运行什么命令,之后就会自动退出:
docker-ssh YOUR-CONTAINER-ID echo hello world
<a name="building"></a>
## 创建你自己的镜像
如果某些原因,你需要创建你自己的镜像,来替代从docker仓库下载镜像,可以按照的说明.
克隆仓库:
git clone https://github.com/phusion/baseimage-docker.git
cd baseimage-docker
创建一个包含docker在的虚拟机.你可以使用我们提供的Vagrantfile.
vagrant up
vagrant ssh
cd /vagrant
编译镜像:
make build
如果你想把创建的镜像名字,叫其他名字,通过`NAME`变量可以设置:
make build NAME=joe/baseimage
<a name="conclusion"></a>
## 总结
* Using baseimage-docker? [Tweet about us](https://twitter.com/share) or [follow us on Twitter](https://twitter.com/phusion_nl).
* Having problems? Want to participate in development? Please post a message at [the discussion forum](https://groups.google.com/d/forum/passenger-docker).
* Looking for a more complete base image, one that is ideal for Ruby, Python, Node.js and Meteor web apps? Take a look at [passenger-docker](https://github.com/phusion/passenger-docker).
[<img src="http://www.phusion.nl/assets/logo.png">](http://www.phusion.nl/)
Please enjoy baseimage-docker, a product by [Phusion](http://www.phusion.nl/). :-)

55
Vagrantfile vendored
View File

@@ -1,31 +1,54 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
ROOT = File.dirname(File.expand_path(__FILE__))
ROOT = File.dirname(File.absolute_path(__FILE__))
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
VAGRANTFILE_API_VERSION = '2'
# Default env properties which can be overridden
# Example overrides:
# echo "ENV['PASSENGER_DOCKER_PATH'] ||= '../../phusion/passenger-docker' " >> ~/.vagrant.d/Vagrantfile
# echo "ENV['BASE_BOX_URL'] ||= 'd\:/dev/vm/vagrant/boxes/phusion/'" >> ~/.vagrant.d/Vagrantfile
BASE_BOX_URL = ENV['BASE_BOX_URL'] || 'https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/'
VAGRANT_BOX_URL = ENV['VAGRANT_BOX_URL'] || BASE_BOX_URL + 'ubuntu-14.04-amd64-vbox.box'
VMWARE_BOX_URL = ENV['VMWARE_BOX_URL'] || BASE_BOX_URL + 'ubuntu-14.04-amd64-vmwarefusion.box'
BASEIMAGE_PATH = ENV['BASEIMAGE_PATH' ] || '.'
PASSENGER_DOCKER_PATH = ENV['PASSENGER_PATH' ] || '../passenger-docker'
DOCKERIZER_PATH = ENV['DOCKERIZER_PATH'] || '../dockerizer'
$script = <<SCRIPT
wget -q -O - https://get.docker.io/gpg | apt-key add -
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -q -y --force-yes lxc-docker
usermod -a -G docker vagrant
docker version
su - vagrant -c 'echo alias d=docker >> ~/.bash_aliases'
SCRIPT
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "phusion-open-ubuntu-12.04-amd64"
config.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/ubuntu-12.04.3-amd64-vbox.box"
config.vm.box = 'phusion-open-ubuntu-14.04-amd64'
config.vm.box_url = VAGRANT_BOX_URL
config.ssh.forward_agent = true
if File.directory?("#{ROOT}/../passenger-docker")
config.vm.synced_folder File.expand_path("#{ROOT}/../passenger-docker"),
"/vagrant/passenger-docker"
passenger_docker_path = File.absolute_path(PASSENGER_DOCKER_PATH, ROOT)
if File.directory?(passenger_docker_path)
config.vm.synced_folder passenger_docker_path, '/vagrant/passenger-docker'
end
baseimage_path = File.absolute_path(BASEIMAGE_PATH, ROOT)
if File.directory?(baseimage_path)
config.vm.synced_folder baseimage_path, "/vagrant/baseimage-docker"
end
dockerizer_path = File.absolute_path(DOCKERIZER_PATH, ROOT)
if File.directory?(dockerizer_path)
config.vm.synced_folder dockerizer_path, '/vagrant/dockerizer'
end
config.vm.provider :vmware_fusion do |f, override|
override.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/ubuntu-12.04.3-amd64-vmwarefusion.box"
f.vmx["displayName"] = "baseimage-docker"
override.vm.box_url = VMWARE_BOX_URL
f.vmx['displayName'] = 'baseimage-docker'
end
if Dir.glob("#{File.dirname(__FILE__)}/.vagrant/machines/default/*/id").empty?
# Add lxc-docker package
pkg_cmd = "wget -q -O - https://get.docker.io/gpg | apt-key add -;" \
"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list;" \
"apt-get update -qq; apt-get install -q -y --force-yes lxc-docker; "
# Add vagrant user to the docker group
pkg_cmd << "usermod -a -G docker vagrant; "
config.vm.provision :shell, :inline => pkg_cmd
config.vm.provision :shell, :inline => $script
end
end

View File

@@ -1,6 +1,8 @@
#!/bin/bash
set -e
if [[ ! -e /etc/ssh/ssh_host_rsa_key ]]; then
if [[ ! -e /etc/service/sshd/down && ! -e /etc/ssh/ssh_host_rsa_key ]] || [[ "$1" == "-f" ]]; then
echo "No SSH host key available. Generating one..."
export LC_ALL=C
export DEBIAN_FRONTEND=noninteractive
dpkg-reconfigure openssh-server
fi

View File

@@ -1,8 +1,7 @@
FROM ubuntu:12.04
FROM ubuntu:14.04
MAINTAINER Phusion <info@phusion.nl>
ENV HOME /root
RUN mkdir /build
ADD . /build
RUN /build/prepare.sh && \
@@ -11,4 +10,3 @@ RUN /build/prepare.sh && \
/build/cleanup.sh
CMD ["/sbin/my_init"]
EXPOSE 22 80 443

30
image/bin/enable_insecure_key Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
set -e
AUTHORIZED_KEYS=/root/.ssh/authorized_keys
if [[ -e "$AUTHORIZED_KEYS" ]] && grep -q baseimage-docker-insecure-key "$AUTHORIZED_KEYS"; then
echo "Insecure key has already been added to $AUTHORIZED_KEYS."
else
DIR=`dirname "$AUTHORIZED_KEYS"`
echo "Creating directory $DIR..."
mkdir -p "$DIR"
chmod 700 "$DIR"
chown root:root "$DIR"
echo "Editing $AUTHORIZED_KEYS..."
cat /etc/insecure_key.pub >> "$AUTHORIZED_KEYS"
echo "Success: insecure key has been added to $AUTHORIZED_KEYS"
cat <<-EOF
+------------------------------------------------------------------------------+
| Insecure SSH key installed |
| |
| DO NOT expose port 22 on the Internet unless you know what you are doing! |
| |
| Use the private key below to connect with user root |
+------------------------------------------------------------------------------+
EOF
cat /etc/insecure_key
echo -e "\n\n"
fi

340
image/bin/my_init Executable file
View File

@@ -0,0 +1,340 @@
#!/usr/bin/python3 -u
import os, os.path, sys, stat, signal, errno, argparse, time, json, re
KILL_PROCESS_TIMEOUT = 5
KILL_ALL_PROCESSES_TIMEOUT = 5
LOG_LEVEL_ERROR = 1
LOG_LEVEL_WARN = 1
LOG_LEVEL_INFO = 2
LOG_LEVEL_DEBUG = 3
log_level = None
terminated_child_processes = {}
class AlarmException(Exception):
pass
def error(message):
if log_level >= LOG_LEVEL_ERROR:
sys.stderr.write("*** %s\n" % message)
def warn(message):
if log_level >= LOG_LEVEL_WARN:
sys.stderr.write("*** %s\n" % message)
def info(message):
if log_level >= LOG_LEVEL_INFO:
sys.stderr.write("*** %s\n" % message)
def debug(message):
if log_level >= LOG_LEVEL_DEBUG:
sys.stderr.write("*** %s\n" % message)
def ignore_signals_and_raise_keyboard_interrupt(signame):
signal.signal(signal.SIGTERM, signal.SIG_IGN)
signal.signal(signal.SIGINT, signal.SIG_IGN)
raise KeyboardInterrupt(signame)
def raise_alarm_exception():
raise AlarmException('Alarm')
def listdir(path):
try:
result = os.stat(path)
except OSError:
return []
if stat.S_ISDIR(result.st_mode):
return sorted(os.listdir(path))
else:
return []
def is_exe(path):
try:
return os.path.isfile(path) and os.access(path, os.X_OK)
except OSError:
return False
def import_envvars(clear_existing_environment = True, override_existing_environment = True):
new_env = {}
for envfile in listdir("/etc/container_environment"):
name = os.path.basename(envfile)
with open("/etc/container_environment/" + envfile, "r") as f:
# Text files often end with a trailing newline, which we
# don't want to include in the env variable value. See
# https://github.com/phusion/baseimage-docker/pull/49
value = re.sub('\n\Z', '', f.read())
new_env[name] = value
if clear_existing_environment:
os.environ.clear()
for name, value in new_env.items():
if override_existing_environment or not name in os.environ:
os.environ[name] = value
def export_envvars(to_dir = True):
shell_dump = ""
for name, value in os.environ.items():
if name in ['HOME', 'USER', 'GROUP', 'UID', 'GID', 'SHELL']:
continue
if to_dir:
with open("/etc/container_environment/" + name, "w") as f:
f.write(value)
shell_dump += "export " + shquote(name) + "=" + shquote(value) + "\n"
with open("/etc/container_environment.sh", "w") as f:
f.write(shell_dump)
with open("/etc/container_environment.json", "w") as f:
f.write(json.dumps(dict(os.environ)))
_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search
def shquote(s):
"""Return a shell-escaped version of the string *s*."""
if not s:
return "''"
if _find_unsafe(s) is None:
return s
# use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'"
# Waits for the child process with the given PID, while at the same time
# reaping any other child processes that have exited (e.g. adopted child
# processes that have terminated).
def waitpid_reap_other_children(pid):
global terminated_child_processes
status = terminated_child_processes.get(pid)
if status:
# A previous call to waitpid_reap_other_children(),
# with an argument not equal to the current argument,
# already waited for this process. Return the status
# that was obtained back then.
del terminated_child_processes[pid]
return status
done = False
status = None
while not done:
try:
this_pid, status = os.waitpid(-1, 0)
if this_pid == pid:
done = True
else:
# Save status for later.
terminated_child_processes[this_pid] = status
except OSError as e:
if e.errno == errno.ECHILD or e.errno == errno.ESRCH:
return None
else:
raise
return status
def stop_child_process(name, pid, signo = signal.SIGTERM, time_limit = KILL_PROCESS_TIMEOUT):
info("Shutting down %s (PID %d)..." % (name, pid))
try:
os.kill(pid, signo)
except OSError:
pass
signal.alarm(time_limit)
try:
try:
waitpid_reap_other_children(pid)
except OSError:
pass
except AlarmException:
warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid))
try:
os.kill(pid, signal.SIGKILL)
except OSError:
pass
try:
waitpid_reap_other_children(pid)
except OSError:
pass
finally:
signal.alarm(0)
def run_command_killable(*argv):
filename = argv[0]
status = None
pid = os.spawnvp(os.P_NOWAIT, filename, argv)
try:
status = waitpid_reap_other_children(pid)
except BaseException as s:
warn("An error occurred. Aborting.")
stop_child_process(filename, pid)
raise
if status != 0:
if status is None:
error("%s exited with unknown status\n" % filename)
else:
error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status)))
sys.exit(1)
def run_command_killable_and_import_envvars(*argv):
run_command_killable(*argv)
import_envvars()
export_envvars(False)
def kill_all_processes(time_limit):
info("Killing all processes...")
try:
os.kill(-1, signal.SIGTERM)
except OSError:
pass
signal.alarm(time_limit)
try:
# Wait until no more child processes exist.
done = False
while not done:
try:
os.waitpid(-1, 0)
except OSError as e:
if e.errno == errno.ECHILD:
done = True
else:
raise
except AlarmException:
warn("Not all processes have exited in time. Forcing them to exit.")
try:
os.kill(-1, signal.SIGKILL)
except OSError:
pass
finally:
signal.alarm(0)
def run_startup_files():
# Run /etc/my_init.d/*
for name in listdir("/etc/my_init.d"):
filename = "/etc/my_init.d/" + name
if is_exe(filename):
info("Running %s..." % filename)
run_command_killable_and_import_envvars(filename)
# Run /etc/rc.local.
if is_exe("/etc/rc.local"):
info("Running /etc/rc.local...")
run_command_killable_and_import_envvars("/etc/rc.local")
def start_runit():
info("Booting runit daemon...")
pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir",
"-P", "/etc/service")
info("Runit started as PID %d" % pid)
return pid
def wait_for_runit_or_interrupt(pid):
try:
status = waitpid_reap_other_children(pid)
return (True, status)
except KeyboardInterrupt:
return (False, None)
def shutdown_runit_services():
debug("Begin shutting down runit services...")
os.system("/usr/bin/sv down /etc/service/*")
def wait_for_runit_services():
debug("Waiting for runit services to exit...")
done = False
while not done:
done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0
if not done:
time.sleep(0.1)
def install_insecure_key():
info("Installing insecure SSH key for user root")
run_command_killable("/usr/sbin/enable_insecure_key")
def main(args):
import_envvars(False, False)
export_envvars()
if args.enable_insecure_key:
install_insecure_key()
if not args.skip_startup_files:
run_startup_files()
runit_exited = False
exit_code = None
if not args.skip_runit:
runit_pid = start_runit()
try:
exit_status = None
if len(args.main_command) == 0:
runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid)
if runit_exited:
if exit_code is None:
info("Runit exited with unknown status")
exit_status = 1
else:
exit_status = os.WEXITSTATUS(exit_code)
info("Runit exited with status %d" % exit_status)
else:
info("Running %s..." % " ".join(args.main_command))
pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command)
try:
exit_code = waitpid_reap_other_children(pid)
if exit_code is None:
info("%s exited with unknown status." % args.main_command[0])
exit_status = 1
else:
exit_status = os.WEXITSTATUS(exit_code)
info("%s exited with status %d." % (args.main_command[0], exit_status))
except KeyboardInterrupt:
stop_child_process(args.main_command[0], pid)
raise
except BaseException as s:
warn("An error occurred. Aborting.")
stop_child_process(args.main_command[0], pid)
raise
sys.exit(exit_status)
finally:
if not args.skip_runit:
shutdown_runit_services()
if not runit_exited:
stop_child_process("runit daemon", runit_pid)
wait_for_runit_services()
# Parse options.
parser = argparse.ArgumentParser(description = 'Initialize the system.')
parser.add_argument('main_command', metavar = 'MAIN_COMMAND', type = str, nargs = '*',
help = 'The main command to run. (default: runit)')
parser.add_argument('--enable-insecure-key', dest = 'enable_insecure_key',
action = 'store_const', const = True, default = False,
help = 'Install the insecure SSH key')
parser.add_argument('--skip-startup-files', dest = 'skip_startup_files',
action = 'store_const', const = True, default = False,
help = 'Skip running /etc/my_init.d/* and /etc/rc.local')
parser.add_argument('--skip-runit', dest = 'skip_runit',
action = 'store_const', const = True, default = False,
help = 'Do not run runit services')
parser.add_argument('--no-kill-all-on-exit', dest = 'kill_all_on_exit',
action = 'store_const', const = False, default = True,
help = 'Don\'t kill all processes on the system upon exiting')
parser.add_argument('--quiet', dest = 'log_level',
action = 'store_const', const = LOG_LEVEL_WARN, default = LOG_LEVEL_INFO,
help = 'Only print warnings and errors')
args = parser.parse_args()
log_level = args.log_level
if args.skip_runit and len(args.main_command) == 0:
error("When --skip-runit is given, you must also pass a main command.")
sys.exit(1)
# Run main function.
signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM'))
signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT'))
signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception())
try:
main(args)
except KeyboardInterrupt:
warn("Init system aborted.")
exit(2)
finally:
if args.kill_all_on_exit:
kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT)

26
image/bin/setuser Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/python3
import sys, os, pwd
if len(sys.argv) < 3:
sys.stderr.write("Usage: /sbin/setuser USERNAME COMMAND [args..]\n")
sys.exit(1)
def abort(message):
sys.stderr.write("setuser: %s\n" % message)
sys.exit(1)
username = sys.argv[1]
try:
user = pwd.getpwnam(username)
except KeyError:
abort("user %s not found" % username)
os.initgroups(username, user.pw_gid)
os.setgid(user.pw_gid)
os.setuid(user.pw_uid)
os.environ['USER'] = username
os.environ['HOME'] = user.pw_dir
os.environ['UID'] = str(user.pw_uid)
try:
os.execvp(sys.argv[2], sys.argv[2:])
except OSError as e:
abort("cannot execute %s: %s" % (sys.argv[2], str(e)))

View File

@@ -6,5 +6,7 @@ set -x
apt-get clean
rm -rf /build
rm -rf /tmp/* /var/tmp/*
rm -rf /var/lib/apt/lists/*
rm -f /etc/dpkg/dpkg.cfg.d/02apt-speedup
rm -f /etc/ssh/ssh_host_*

View File

@@ -0,0 +1,38 @@
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
sv reload syslog-ng > /dev/null
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
sv reload syslog-ng > /dev/null
sv restart cron-log-forwarder > /dev/null
endscript
}

View File

@@ -101,7 +101,7 @@ ChallengeResponseAuthentication no
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
@@ -123,13 +123,10 @@ ChallengeResponseAuthentication no
#Banner none
# override default of no subsystems
Subsystem sftp /usr/lib/sftp-server
Subsystem sftp /usr/lib/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# ForceCommand cvs server
# XAuthLocation added by XQuartz (http://xquartz.macosforge.org)
XAuthLocation /opt/X11/bin/xauth

View File

@@ -0,0 +1,12 @@
# If a variable is not set here, then the corresponding
# parameter will not be changed.
# If a variables is set, then every invocation of
# syslog-ng's init script will set them using dmesg.
# log level of messages which should go to console
# see syslog(3) for details
#
#CONSOLE_LOG_LEVEL=1
# Command line options to syslog-ng
SYSLOGNG_OPTS="--no-caps"

26
image/insecure_key.ppk Normal file
View File

@@ -0,0 +1,26 @@
PuTTY-User-Key-File-2: ssh-rsa
Encryption: none
Comment: imported-openssh-key
Public-Lines: 6
AAAAB3NzaC1yc2EAAAADAQABAAABAQDVmzBG5v7cO9IScGLIzlhGlHNFhXzy87Vf
aPzru7qnIIdQ1e9FEKvtqEws8hVixnCUdviwX5lvcMk4Ef4Tbrmj3dyF0zFtYbji
TSyl/XQlF68DQlc2sTAdHy96wJHvh7ky511tKJzzyWwSqeef4WjeVK28TqcGnq1u
p0S7saFO0dJh6OfDAg2cDmhyweR3VgT0vZJyrDV7hte95MBCdK+Gp7fdCyEZcWm3
S1DBFaeBqHzzt/Y/njAVKbYL9TIVPum8iMg0rMiLi9ShfP+dT5Xud5Oa3dcN2OWh
iDfJw5pfhFJWd44cJ/uGRwQpvNs/PNKsYABhgLlTMUH4iawhu1Xb
Private-Lines: 14
AAABAQCjROxgtX2Gft7yIx8Ol9IXmK6HLCI2XZt7ovb3hFWGGzHy0qMBql2P2Tzo
ed1o038Hq+woe9n+uTnEdtQ6rD6PByzgyW2VSsWTjCOdeJ5HH9Qw7ItXDZZWHBkh
fYHOkXI4e2oI3qshGAtYNLALn7KVhioJriCyyaSM2KOLx5khcY+EJ1inQfwQJKqP
GsdKc72liz07T8ifRj+mNLKtwrxlK3IXYfIdgLp/1pCKdrC80DhprMsD4xvNgq4p
CR9jd4FoqM9t/Up5ppTm+p6A/bDwdIPh6cFFeyMP+G3+bTlW1Gg7RLoNCc6qh53W
WVgEOQqdLHcQ8Ge4RLmbwLUmnRuRAAAAgQD312H46T2YvKzyEKbsddwbO8WktfxW
vVqqxH6z6bRXVFR3hQhmPKjlFXsD74h3W7NJwe9WJ5Pf3vemoBWIo0Hak0M1Z6WC
OIvBohpOYDzIgdlGHifx2ZiAd47Vsn+mfxjtISdWupl9Fw98yRjahWosKmmIHTtR
cIfYHB9ztpR8owAAAIEA3KNMYMFgenE+7q4pwat4t3RKA7rU8SPto5I1+sEHY8rz
cD7ONkIVlEhaqN+uTEYbr5rZa4dsQe4Ia+7ZXmO4djFsAP/fyJX+VCX/bHK83V5H
9toTdRLTqqfqJ3GOeZ41kPIN6UDHVEa4S8tfVM0DMNPEHBjLMfdbZGkoBQAPXWkA
AACBAJV/Bxr1jJohvmURQf/9y6MvO2wcRpTdKVLQhEnGm2cXQdh5CPVae2K+u0CG
d8u0/PDIZMGpueCQo4lft02W0skTDo5Kn+1IUwmQuoRzanVJ5ab+GyVnlouRLp/J
bWMQZ3pjXNkBsQOK/igrKYvqUb1jRsy9zxVQRl4i7JjjLpe/
Private-MAC: ef1e472b5254ae2c5319a522d39ad31d432dde75

View File

@@ -1 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVmzBG5v7cO9IScGLIzlhGlHNFhXzy87VfaPzru7qnIIdQ1e9FEKvtqEws8hVixnCUdviwX5lvcMk4Ef4Tbrmj3dyF0zFtYbjiTSyl/XQlF68DQlc2sTAdHy96wJHvh7ky511tKJzzyWwSqeef4WjeVK28TqcGnq1up0S7saFO0dJh6OfDAg2cDmhyweR3VgT0vZJyrDV7hte95MBCdK+Gp7fdCyEZcWm3S1DBFaeBqHzzt/Y/njAVKbYL9TIVPum8iMg0rMiLi9ShfP+dT5Xud5Oa3dcN2OWhiDfJw5pfhFJWd44cJ/uGRwQpvNs/PNKsYABhgLlTMUH4iawhu1Xb hongli@asuna-3939
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVmzBG5v7cO9IScGLIzlhGlHNFhXzy87VfaPzru7qnIIdQ1e9FEKvtqEws8hVixnCUdviwX5lvcMk4Ef4Tbrmj3dyF0zFtYbjiTSyl/XQlF68DQlc2sTAdHy96wJHvh7ky511tKJzzyWwSqeef4WjeVK28TqcGnq1up0S7saFO0dJh6OfDAg2cDmhyweR3VgT0vZJyrDV7hte95MBCdK+Gp7fdCyEZcWm3S1DBFaeBqHzzt/Y/njAVKbYL9TIVPum8iMg0rMiLi9ShfP+dT5Xud5Oa3dcN2OWhiDfJw5pfhFJWd44cJ/uGRwQpvNs/PNKsYABhgLlTMUH4iawhu1Xb baseimage-docker-insecure-key

View File

@@ -1,116 +0,0 @@
#!/usr/bin/python2
import os, sys, stat, signal, errno
pid = None
status = None
def listdir(path):
try:
result = os.stat(path)
except OSError:
return []
if stat.S_ISDIR(result.st_mode):
return sorted(os.listdir(path))
else:
return []
def is_exe(path):
try:
return os.path.isfile(path) and os.access(path, os.X_OK)
except OSError:
return False
def reap_child(signum, frame):
global pid, status, waiting_for_runit
try:
result = os.wait3(os.WNOHANG)
if result is not None and pid == result[0]:
status = result[1]
except OSError:
pass
def stop_child_process(name):
global pid
print("*** Shutting down %s (PID %d)..." % (name, pid))
try:
os.kill(pid, signal.SIGHUP)
except OSError:
pass
def run_command_killable(*argv):
global pid
filename = argv[0]
pid = os.spawnvp(os.P_NOWAIT, filename, argv)
signal.signal(signal.SIGINT, lambda signum, frame: stop_child_process(filename))
signal.signal(signal.SIGTERM, lambda signum, frame: stop_child_process(filename))
try:
this_pid, status = os.waitpid(pid, 0)
except OSError as e:
if e.errno == errno.EINTR:
sys.exit(2)
else:
raise
finally:
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
if status != 0:
sys.stderr.write("*** %s failed with exit code %d\n" % (filename, status))
sys.exit(1)
# Run /etc/my_init.d/*
for name in listdir("/etc/my_init.d"):
filename = "/etc/my_init.d/" + name
if is_exe(filename):
print("*** Running %s..." % filename)
run_command_killable(filename)
# Run /etc/rc.local.
if is_exe("/etc/rc.local"):
print("*** Running /etc/rc.local...")
run_command_killable("/etc/rc.local")
# Start runit.
signal.signal(signal.SIGCHLD, reap_child)
print("*** Booting runit...")
pid = os.spawnl(os.P_NOWAIT, "/usr/sbin/runsvdir-start", "/usr/sbin/runsvdir-start")
print("*** Runit started as PID %d" % pid)
signal.signal(signal.SIGTERM, lambda signum, frame: stop_child_process("runit"))
# Wait for runit, and while waiting, reap any adopted orphans.
done = False
while not done:
try:
this_pid, status = os.waitpid(pid, 0)
done = True
except OSError as e:
if e.errno == errno.EINTR:
# Try again
pass
else:
# The SIGCHLD handler probably caught it.
done = True
# Runit has exited. Reset signal handlers.
print("*** Runit exited with code %s. Waiting for all services to shut down..." % status)
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
signal.siginterrupt(signal.SIGCHLD, False)
signal.siginterrupt(signal.SIGTERM, False)
# Wait at most 5 seconds for services to shut down.
import time
def shutdown(signum = None, frame = None):
global status
if status is not None:
sys.exit(status)
signal.signal(signal.SIGALRM, shutdown)
signal.alarm(5)
done = False
while not done:
done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0
if not done:
time.sleep(0.5)
shutdown()

View File

@@ -3,23 +3,47 @@ set -e
source /build/buildconfig
set -x
## Enable Ubuntu Universe.
echo deb http://archive.ubuntu.com/ubuntu precise main universe > /etc/apt/sources.list
echo deb http://archive.ubuntu.com/ubuntu precise-updates main universe >> /etc/apt/sources.list
apt-get update
## Temporarily disable dpkg fsync to make building faster.
if [[ ! -e /etc/dpkg/dpkg.cfg.d/docker-apt-speedup ]]; then
echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
fi
## Install HTTPS support for APT.
$minimal_apt_get_install apt-transport-https
## Prevent initramfs updates from trying to run grub and lilo.
## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/
## http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594189
export INITRD=no
mkdir -p /etc/container_environment
echo -n no > /etc/container_environment/INITRD
## Enable Ubuntu Universe and Multiverse.
sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
sed -i 's/^#\s*\(deb.*multiverse\)$/\1/g' /etc/apt/sources.list
apt-get update
## Fix some issues with APT packages.
## See https://github.com/dotcloud/docker/issues/1024
dpkg-divert --local --rename --add /sbin/initctl
ln -sf /bin/true /sbin/initctl
## Replace the 'ischroot' tool to make it always return true.
## Prevent initscripts updates from breaking /dev/shm.
## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/
## https://bugs.launchpad.net/launchpad/+bug/974584
dpkg-divert --local --rename --add /usr/bin/ischroot
ln -sf /bin/true /usr/bin/ischroot
## Install HTTPS support for APT.
$minimal_apt_get_install apt-transport-https ca-certificates
## Install add-apt-repository
$minimal_apt_get_install software-properties-common
## Upgrade all packages.
echo "initscripts hold" | dpkg --set-selections
apt-get upgrade -y --no-install-recommends
apt-get dist-upgrade -y --no-install-recommends
## Fix locale.
$minimal_apt_get_install language-pack-en
locale-gen en_US
update-locale LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8
echo -n en_US.UTF-8 > /etc/container_environment/LANG
echo -n en_US.UTF-8 > /etc/container_environment/LC_CTYPE

2
image/runit/syslog-forwarder Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
exec tail -f -n 0 /var/log/syslog

View File

@@ -1,3 +1,32 @@
#!/bin/sh
set -e
exec syslog-ng -F -p /var/run/syslog-ng.pid
# If /dev/log is either a named pipe or it was placed there accidentally,
# e.g. because of the issue documented at https://github.com/phusion/baseimage-docker/pull/25,
# then we remove it.
if [ ! -S /dev/log ]; then rm -f /dev/log; fi
if [ ! -S /var/lib/syslog-ng/syslog-ng.ctl ]; then rm -f /var/lib/syslog-ng/syslog-ng.ctl; fi
SYSLOGNG_OPTS=""
[ -r /etc/default/syslog-ng ] && . /etc/default/syslog-ng
case "x$CONSOLE_LOG_LEVEL" in
x[1-8])
dmesg -n $CONSOLE_LOG_LEVEL
;;
x)
;;
*)
echo "CONSOLE_LOG_LEVEL is of unaccepted value."
;;
esac
if [ ! -e /dev/xconsole ]
then
mknod -m 640 /dev/xconsole p
chown root:adm /dev/xconsole
[ -x /sbin/restorecon ] && /sbin/restorecon $XCONSOLE
fi
exec syslog-ng -F -p /var/run/syslog-ng.pid $SYSLOGNG_OPTS

View File

@@ -1,12 +0,0 @@
#!/bin/bash
set -e
user="$1"
shift
if [[ "$user" == "root" ]]; then
export HOME=/root
else
export HOME=/home/$user
fi
exec chpst -u "$user" "$@"

View File

@@ -4,8 +4,17 @@ source /build/buildconfig
set -x
## Install init process.
cp /build/my_init /sbin/
cp /build/bin/my_init /sbin/
mkdir -p /etc/my_init.d
mkdir -p /etc/container_environment
touch /etc/container_environment.sh
touch /etc/container_environment.json
chmod 700 /etc/container_environment
groupadd -g 8377 docker_env
chown :docker_env /etc/container_environment.sh /etc/container_environment.json
chmod 640 /etc/container_environment.sh /etc/container_environment.json
ln -s /etc/container_environment.sh /etc/profile.d/
## Install runit.
$minimal_apt_get_install runit
@@ -15,11 +24,26 @@ $minimal_apt_get_install syslog-ng-core
mkdir /etc/service/syslog-ng
cp /build/runit/syslog-ng /etc/service/syslog-ng/run
mkdir -p /var/lib/syslog-ng
cp /build/config/syslog_ng_default /etc/default/syslog-ng
touch /var/log/syslog
chmod u=rw,g=r,o= /var/log/syslog
# Replace the system() source because inside Docker we
# can't access /proc/kmsg.
sed -i -E 's/^(\s*)system\(\);/\1unix-stream("\/dev\/log");/' /etc/syslog-ng/syslog-ng.conf
## Install syslog to "docker logs" forwarder.
mkdir /etc/service/syslog-forwarder
cp /build/runit/syslog-forwarder /etc/service/syslog-forwarder/run
## Install logrotate.
$minimal_apt_get_install logrotate
cp /build/config/logrotate_syslogng /etc/logrotate.d/syslog-ng
## Install the SSH server.
$minimal_apt_get_install openssh-server
mkdir /var/run/sshd
mkdir /etc/service/sshd
touch /etc/service/sshd/down
cp /build/runit/sshd /etc/service/sshd/run
cp /build/config/sshd_config /etc/ssh/sshd_config
cp /build/00_regen_ssh_host_keys.sh /etc/my_init.d/
@@ -28,9 +52,18 @@ cp /build/00_regen_ssh_host_keys.sh /etc/my_init.d/
mkdir -p /root/.ssh
chmod 700 /root/.ssh
chown root:root /root/.ssh
cat /build/insecure_key.pub > /root/.ssh/authorized_keys
cp /build/insecure_key.pub /etc/insecure_key.pub
cp /build/insecure_key /etc/insecure_key
chmod 644 /etc/insecure_key*
chown root:root /etc/insecure_key*
cp /build/bin/enable_insecure_key /usr/sbin/
## Install cron daemon.
$minimal_apt_get_install cron
mkdir /etc/service/cron
chmod 600 /etc/crontab
cp /build/runit/cron /etc/service/cron/run
## Remove useless cron entries.
# Checks for lost+found and scans for mtab.
rm -f /etc/cron.daily/standard

View File

@@ -7,4 +7,4 @@ set -x
$minimal_apt_get_install curl less nano vim psmisc
## This tool runs a command as another user and sets $HOME.
cp /build/setuser /sbin/setuser
cp /build/bin/setuser /sbin/setuser

12
install-tools.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
set -e
dir=`dirname "$0"`
cd "$dir"
set -x
cp tools/docker-bash /usr/local/bin/
cp tools/docker-ssh /usr/local/bin/
cp tools/baseimage-docker-nsenter /usr/local/bin/
mkdir -p /usr/local/share/baseimage-docker
cp image/insecure_key /usr/local/share/baseimage-docker/
chmod 644 /usr/local/share/baseimage-docker/insecure_key

16
test/runner.sh Normal file → Executable file
View File

@@ -14,9 +14,10 @@ function cleanup()
docker rm $ID >/dev/null
}
echo " --> Starting container"
PWD=`pwd`
ID=`docker run -d -v $PWD/test:/test $NAME:$VERSION`
echo " --> Starting insecure container"
ID=`docker run -d -v $PWD/test:/test $NAME:$VERSION /sbin/my_init --enable-insecure-key`
sleep 1
echo " --> Obtaining IP"
@@ -27,8 +28,15 @@ fi
trap cleanup EXIT
echo " --> Enabling SSH in the container"
docker exec -t -i $ID /etc/my_init.d/00_regen_ssh_host_keys.sh -f
docker exec -t -i $ID rm /etc/service/sshd/down
docker exec -t -i $ID sv start /etc/service/sshd
sleep 1
echo " --> Logging into container and running tests"
chmod 600 image/insecure_key
cp image/insecure_key /tmp/insecure_key
chmod 600 /tmp/insecure_key
sleep 1 # Give container some more time to start up.
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i image/insecure_key root@$IP \
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /tmp/insecure_key root@$IP \
/bin/bash /test/test.sh

0
test/test.sh Normal file → Executable file
View File

1
tools/README.md Normal file
View File

@@ -0,0 +1 @@
baseimage-docker-nsenter is the nsenter tool taken from https://github.com/jpetazzo/nsenter, commit 10ce18a7a32. It has been stripped in order to make it smaller.

BIN
tools/baseimage-docker-nsenter Executable file

Binary file not shown.

29
tools/docker-bash Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/sh
set -e
SELFDIR=`dirname "$0"`
SELFDIR=`cd "$SELFDIR" && pwd`
usage()
{
echo "Usage: docker-bash <CONTAINER_ID> [COMMAND...]"
echo "Login to a Baseimage-based Docker container using nsenter." \
"If COMMAND is not given, opens an interactive shell." \
"Otherwise, runs COMMAND inside the container."
}
if test $# = 0; then
usage
exit
fi
CONTAINER_ID="$1"
shift
PID=`docker inspect -f "{{ .State.Pid }}" "$CONTAINER_ID"`
if test $# = 0; then
exec "$SELFDIR/baseimage-docker-nsenter" --target "$PID" --mount --uts --ipc --net --pid -- /bin/bash -l
else
exec "$SELFDIR/baseimage-docker-nsenter" --target "$PID" --mount --uts --ipc --net --pid -- "$@"
fi

81
tools/docker-ssh Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/sh
set -e
KNOWN_HOSTS_FILE=
IP=
usage()
{
echo "Usage: docker-ssh <CONTAINER_ID> [COMMAND...]"
echo "Login to a Baseimage-based Docker container using SSH." \
"If COMMAND is not given, opens an interactive shell." \
"Otherwise, runs COMMAND inside the container."
}
cleanup()
{
local pids=`jobs -p`
if test "$pids" != ""; then
kill $pids
fi
if test "$KNOWN_HOSTS_FILE" != ""; then
rm -f "$KNOWN_HOSTS_FILE"
fi
}
if test $# = 0; then
usage
exit
fi
CONTAINER_ID="$1"
shift
trap cleanup EXIT
if ! test -e ~/.baseimage_docker_insecure_key; then
if test -e /usr/local/share/baseimage-docker/insecure_key; then
cp /usr/local/share/baseimage-docker/insecure_key ~/.baseimage_docker_insecure_key
else
dir=`dirname "$0"`
dir=`cd "$dir/.." && pwd`
if test -e "$dir/image/insecure_key"; then
cp "$dir/image/insecure_key" ~/.baseimage_docker_insecure_key
else
echo "*** ERROR ***: Baseimage-docker insecure key not found." >&2
echo "You probably didn't install docker-ssh properly. Please reinstall it:" >&2
echo "" >&2
echo " curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \\" >&2
echo " tar xzf master.tar.gz && \\" >&2
echo " sudo ./baseimage-docker-master/install-tools.sh" >&2
exit 1
fi
fi
chown "`whoami`": ~/.baseimage_docker_insecure_key
chmod 600 ~/.baseimage_docker_insecure_key
fi
KNOWN_HOSTS_FILE=`mktemp /tmp/docker-ssh.XXXXXXXXX`
IP=`docker inspect -f "{{ .NetworkSettings.IPAddress }}" "$CONTAINER_ID"`
# Prevent SSH from warning about adding a host to the known_hosts file.
ssh-keyscan "$IP" >"$KNOWN_HOSTS_FILE" 2>&1
if ! ssh -i ~/.baseimage_docker_insecure_key \
-o UserKnownHostsFile="$KNOWN_HOSTS_FILE" \
-o StrictHostKeyChecking=no \
-o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no \
-o ChallengeResponseAuthentication=no \
"root@$IP" "$@"
then
STATUS=$?
if test $# = 0; then
echo "----------------"
echo "It appears that login to the Docker container failed. This could be caused by the following reasons:"
echo "- The Docker container you're trying to login to is not based on Baseimage-docker. The docker-ssh tool only works with Baseimage-docker-based containers."
echo "- You did not enable the the insecure key inside the container. Please read https://github.com/phusion/baseimage-docker/blob/master/README.md#login to learn how to enable the insecure key."
fi
exit $STATUS
fi